Search in sources :

Example 1 with InterpolatedSecretsAction

use of org.jenkinsci.plugins.workflow.cps.view.InterpolatedSecretsAction in project workflow-cps-plugin by jenkinsci.

the class DSL method logInterpolationWarnings.

private void logInterpolationWarnings(String stepName, @CheckForNull ArgumentsActionImpl argumentsAction, Set<String> interpolatedStrings, @CheckForNull EnvVars envVars, @NonNull Set<String> sensitiveVariables, TaskListener listener) throws IOException {
    if (UNSAFE_GROOVY_INTERPOLATION.equals("ignore")) {
        return;
    }
    boolean shouldFail;
    if (UNSAFE_GROOVY_INTERPOLATION.equals("fail")) {
        shouldFail = true;
    } else {
        shouldFail = false;
    }
    if (argumentsAction == null || interpolatedStrings.isEmpty() || envVars == null || envVars.isEmpty() || sensitiveVariables.isEmpty()) {
        return;
    }
    // Workaround for NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE false positive in lambdas: https://github.com/spotbugs/spotbugs/issues/552.
    final EnvVars nonNullEnvVars = envVars;
    List<String> scanResults = sensitiveVariables.stream().filter(e -> !nonNullEnvVars.get(e, "").isEmpty() && interpolatedStrings.stream().anyMatch(g -> g.contains(nonNullEnvVars.get(e)))).collect(Collectors.toList());
    if (scanResults != null && !scanResults.isEmpty()) {
        String warningType;
        if (shouldFail) {
            warningType = "Error";
        } else {
            warningType = "Warning";
        }
        String warning = String.format("%s: A secret was passed to \"%s\" using Groovy String interpolation, which is insecure.%n\t\t Affected argument(s) used the following variable(s): %s%n\t\t See https://jenkins.io/redirect/groovy-string-interpolation for details.", warningType, stepName, scanResults.toString());
        FlowExecutionOwner owner = exec.getOwner();
        if (owner != null && owner.getExecutable() instanceof Run) {
            InterpolatedSecretsAction runReport = ((Run) owner.getExecutable()).getAction(InterpolatedSecretsAction.class);
            if (runReport == null) {
                runReport = new InterpolatedSecretsAction();
                ((Run) owner.getExecutable()).addAction(runReport);
            }
            runReport.record(stepName, scanResults);
        } else {
            LOGGER.log(Level.FINE, "Unable to generate Interpolated Secrets Report");
        }
        if (shouldFail) {
            throw new AbortException(warning);
        } else {
            listener.getLogger().println(warning);
        }
    }
}
Also used : Arrays(java.util.Arrays) StringUtils(org.apache.commons.lang.StringUtils) Step(org.jenkinsci.plugins.workflow.steps.Step) Closure(groovy.lang.Closure) Symbol(org.jenkinsci.Symbol) EnvironmentExpander(org.jenkinsci.plugins.workflow.steps.EnvironmentExpander) ReflectionCache(org.codehaus.groovy.reflection.ReflectionCache) NoStaplerConstructorException(org.kohsuke.stapler.NoStaplerConstructorException) Map(java.util.Map) NonNull(edu.umd.cs.findbugs.annotations.NonNull) GroovyObjectSupport(groovy.lang.GroovyObjectSupport) PersistenceContext(org.jenkinsci.plugins.workflow.cps.persistence.PersistenceContext) Restricted(org.kohsuke.accmod.Restricted) GroovyRuntimeException(groovy.lang.GroovyRuntimeException) Jenkins(jenkins.model.Jenkins) Set(java.util.Set) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) LoadStep(org.jenkinsci.plugins.workflow.cps.steps.LoadStep) ParallelStep(org.jenkinsci.plugins.workflow.cps.steps.ParallelStep) ClassDescriptor(org.kohsuke.stapler.ClassDescriptor) Run(hudson.model.Run) Serializable(java.io.Serializable) GString(groovy.lang.GString) CachedClass(org.codehaus.groovy.reflection.CachedClass) DescribableModel(org.jenkinsci.plugins.structs.describable.DescribableModel) StepStartNode(org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode) List(java.util.List) Continuable(com.cloudbees.groovy.cps.Continuable) Annotation(java.lang.annotation.Annotation) Entry(java.util.Map.Entry) DescribableParameter(org.jenkinsci.plugins.structs.describable.DescribableParameter) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode) FlowExecutionOwner(org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner) InterpolatedSecretsAction(org.jenkinsci.plugins.workflow.cps.view.InterpolatedSecretsAction) StepListener(org.jenkinsci.plugins.workflow.flow.StepListener) TreeSet(java.util.TreeSet) Computer(hudson.model.Computer) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) GroovyObject(groovy.lang.GroovyObject) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) Queue(hudson.model.Queue) ArgumentsActionImpl(org.jenkinsci.plugins.workflow.cps.actions.ArgumentsActionImpl) UninstantiatedDescribable(org.jenkinsci.plugins.structs.describable.UninstantiatedDescribable) EnvVars(hudson.EnvVars) BodyExecutionCallback(org.jenkinsci.plugins.workflow.steps.BodyExecutionCallback) Index(org.jvnet.hudson.annotation_indexer.Index) Util(hudson.Util) PersistIn(org.jenkinsci.plugins.workflow.cps.persistence.PersistIn) AbortException(hudson.AbortException) TaskListener(hudson.model.TaskListener) SymbolLookup(org.jenkinsci.plugins.structs.SymbolLookup) Descriptor(hudson.model.Descriptor) StepExecution(org.jenkinsci.plugins.workflow.steps.StepExecution) NoExternalUse(org.kohsuke.accmod.restrictions.NoExternalUse) IOException(java.io.IOException) StepContext(org.jenkinsci.plugins.workflow.steps.StepContext) Outcome(com.cloudbees.groovy.cps.Outcome) TreeMap(java.util.TreeMap) Nullable(edu.umd.cs.findbugs.annotations.Nullable) Describable(hudson.model.Describable) StepDescriptor(org.jenkinsci.plugins.workflow.steps.StepDescriptor) StepAtomNode(org.jenkinsci.plugins.workflow.cps.nodes.StepAtomNode) StepEndNode(org.jenkinsci.plugins.workflow.cps.nodes.StepEndNode) CheckForNull(edu.umd.cs.findbugs.annotations.CheckForNull) Collections(java.util.Collections) ExtensionList(hudson.ExtensionList) ThreadTaskResult(org.jenkinsci.plugins.workflow.cps.ThreadTaskResult) EnvVars(hudson.EnvVars) FlowExecutionOwner(org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner) Run(hudson.model.Run) GString(groovy.lang.GString) InterpolatedSecretsAction(org.jenkinsci.plugins.workflow.cps.view.InterpolatedSecretsAction) AbortException(hudson.AbortException)

Example 2 with InterpolatedSecretsAction

use of org.jenkinsci.plugins.workflow.cps.view.InterpolatedSecretsAction in project workflow-cps-plugin by jenkinsci.

the class DSLTest method passwordParametersSanitized.

@Issue("JENKINS-47101")
@Test
public void passwordParametersSanitized() throws Exception {
    String shellStep = Functions.isWindows() ? "bat" : "sh";
    p.setDefinition(new CpsFlowDefinition("" + "node {\n" + shellStep + " \"echo ${params.TEXT} ${params.PASSWORD}\"\n" + "}", true));
    p.addProperty(new ParametersDefinitionProperty(new StringParameterDefinition("TEXT", ""), new PasswordParameterDefinition("PASSWORD", "", null)));
    WorkflowRun run = r.assertBuildStatusSuccess(p.scheduleBuild2(0, new ParametersAction(new StringParameterValue("TEXT", "hello"), new PasswordParameterValue("PASSWORD", "s3cr3t"))));
    r.assertLogContains("Warning: A secret was passed to \"" + shellStep + "\"", run);
    r.assertLogContains("Affected argument(s) used the following variable(s): [PASSWORD]", run);
    InterpolatedSecretsAction reportAction = run.getAction(InterpolatedSecretsAction.class);
    Assert.assertNotNull(reportAction);
    List<InterpolatedSecretsAction.InterpolatedWarnings> warnings = reportAction.getWarnings();
    MatcherAssert.assertThat(warnings.size(), is(1));
    InterpolatedSecretsAction.InterpolatedWarnings stepWarning = warnings.get(0);
    MatcherAssert.assertThat(stepWarning.getStepName(), is(shellStep));
    MatcherAssert.assertThat(stepWarning.getInterpolatedVariables(), is(Arrays.asList("PASSWORD")));
    LinearScanner scan = new LinearScanner();
    FlowNode node = scan.findFirstMatch(run.getExecution().getCurrentHeads().get(0), new NodeStepTypePredicate(shellStep));
    ArgumentsAction argAction = node.getPersistentAction(ArgumentsAction.class);
    Assert.assertFalse(argAction.isUnmodifiedArguments());
    MatcherAssert.assertThat(argAction.getArguments().values().iterator().next(), is("echo hello ${PASSWORD}"));
}
Also used : ArgumentsAction(org.jenkinsci.plugins.workflow.actions.ArgumentsAction) StringParameterDefinition(hudson.model.StringParameterDefinition) StringParameterValue(hudson.model.StringParameterValue) PasswordParameterValue(hudson.model.PasswordParameterValue) Matchers.containsString(org.hamcrest.Matchers.containsString) ParametersAction(hudson.model.ParametersAction) LinearScanner(org.jenkinsci.plugins.workflow.graphanalysis.LinearScanner) WorkflowRun(org.jenkinsci.plugins.workflow.job.WorkflowRun) NodeStepTypePredicate(org.jenkinsci.plugins.workflow.graphanalysis.NodeStepTypePredicate) ParametersDefinitionProperty(hudson.model.ParametersDefinitionProperty) PasswordParameterDefinition(hudson.model.PasswordParameterDefinition) InterpolatedSecretsAction(org.jenkinsci.plugins.workflow.cps.view.InterpolatedSecretsAction) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode) Issue(org.jvnet.hudson.test.Issue) Test(org.junit.Test)

Example 3 with InterpolatedSecretsAction

use of org.jenkinsci.plugins.workflow.cps.view.InterpolatedSecretsAction in project workflow-cps-plugin by jenkinsci.

the class DSLTest method sensitiveVariableInterpolation.

@Issue("JENKINS-63254")
@Test
public void sensitiveVariableInterpolation() throws Exception {
    final String credentialsId = "creds-sensitiveVariableInterpolation";
    final String username = "bob";
    final String password = "secr3t";
    UsernamePasswordCredentialsImpl c = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample", username, password);
    CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), c);
    String shellStep = Functions.isWindows() ? "bat" : "sh";
    p.setDefinition(new CpsFlowDefinition("" + "node {\n" + "withCredentials([usernamePassword(credentialsId: '" + credentialsId + "', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {\n" + shellStep + " \"echo $PASSWORD\"\n" + "}\n" + "}", true));
    WorkflowRun run = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
    r.assertLogContains("Warning: A secret was passed to \"" + shellStep + "\"", run);
    r.assertLogContains("Affected argument(s) used the following variable(s): [PASSWORD]", run);
    InterpolatedSecretsAction reportAction = run.getAction(InterpolatedSecretsAction.class);
    Assert.assertNotNull(reportAction);
    List<InterpolatedSecretsAction.InterpolatedWarnings> warnings = reportAction.getWarnings();
    MatcherAssert.assertThat(warnings.size(), is(1));
    InterpolatedSecretsAction.InterpolatedWarnings stepWarning = warnings.get(0);
    MatcherAssert.assertThat(stepWarning.getStepName(), is(shellStep));
    MatcherAssert.assertThat(stepWarning.getInterpolatedVariables(), is(Arrays.asList("PASSWORD")));
    LinearScanner scan = new LinearScanner();
    FlowNode node = scan.findFirstMatch(run.getExecution().getCurrentHeads().get(0), new NodeStepTypePredicate(shellStep));
    ArgumentsAction argAction = node.getPersistentAction(ArgumentsAction.class);
    Assert.assertFalse(argAction.isUnmodifiedArguments());
    MatcherAssert.assertThat(argAction.getArguments().values().iterator().next(), is("echo ${PASSWORD}"));
}
Also used : ArgumentsAction(org.jenkinsci.plugins.workflow.actions.ArgumentsAction) NodeStepTypePredicate(org.jenkinsci.plugins.workflow.graphanalysis.NodeStepTypePredicate) Matchers.containsString(org.hamcrest.Matchers.containsString) InterpolatedSecretsAction(org.jenkinsci.plugins.workflow.cps.view.InterpolatedSecretsAction) UsernamePasswordCredentialsImpl(com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl) LinearScanner(org.jenkinsci.plugins.workflow.graphanalysis.LinearScanner) WorkflowRun(org.jenkinsci.plugins.workflow.job.WorkflowRun) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode) Issue(org.jvnet.hudson.test.Issue) Test(org.junit.Test)

Example 4 with InterpolatedSecretsAction

use of org.jenkinsci.plugins.workflow.cps.view.InterpolatedSecretsAction in project workflow-cps-plugin by jenkinsci.

the class DSLTest method sensitiveVariableInterpolationWithNestedDescribable.

@Issue("JENKINS-63254")
@Test
public void sensitiveVariableInterpolationWithNestedDescribable() throws Exception {
    final String credentialsId = "creds-sensitiveVariableInterpolationWithNestedDescribable";
    final String username = "bob";
    final String password = "secr3t";
    UsernamePasswordCredentialsImpl c = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample", username, password);
    CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), c);
    p.setDefinition(new CpsFlowDefinition("" + "node {\n" + "withCredentials([usernamePassword(credentialsId: '" + credentialsId + "', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {\n" + "monomorphWithSymbolStep(monomorphSymbol([firstArg:\"${PASSWORD}\", secondArg:'two']))" + "}\n" + "}", true));
    WorkflowRun run = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
    r.assertLogContains("First arg: ****, second arg: two", run);
    r.assertLogContains("Warning: A secret was passed to \"monomorphWithSymbolStep\"", run);
    r.assertLogContains("Affected argument(s) used the following variable(s): [PASSWORD]", run);
    InterpolatedSecretsAction reportAction = run.getAction(InterpolatedSecretsAction.class);
    Assert.assertNotNull(reportAction);
    List<InterpolatedSecretsAction.InterpolatedWarnings> warnings = reportAction.getWarnings();
    MatcherAssert.assertThat(warnings.size(), is(1));
    InterpolatedSecretsAction.InterpolatedWarnings stepWarning = warnings.get(0);
    MatcherAssert.assertThat(stepWarning.getStepName(), is("monomorphWithSymbolStep"));
    MatcherAssert.assertThat(stepWarning.getInterpolatedVariables(), is(Arrays.asList("PASSWORD")));
    LinearScanner scan = new LinearScanner();
    FlowNode node = scan.findFirstMatch(run.getExecution().getCurrentHeads().get(0), new NodeStepTypePredicate("monomorphWithSymbolStep"));
    ArgumentsAction argAction = node.getPersistentAction(ArgumentsAction.class);
    Assert.assertFalse(argAction.isUnmodifiedArguments());
    Object var = argAction.getArguments().values().iterator().next();
    MatcherAssert.assertThat(var, instanceOf(UninstantiatedDescribable.class));
    MatcherAssert.assertThat(((UninstantiatedDescribable) var).getArguments().toString(), is("{firstArg=${PASSWORD}, secondArg=two}"));
}
Also used : ArgumentsAction(org.jenkinsci.plugins.workflow.actions.ArgumentsAction) UninstantiatedDescribable(org.jenkinsci.plugins.structs.describable.UninstantiatedDescribable) Matchers.containsString(org.hamcrest.Matchers.containsString) UsernamePasswordCredentialsImpl(com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl) LinearScanner(org.jenkinsci.plugins.workflow.graphanalysis.LinearScanner) WorkflowRun(org.jenkinsci.plugins.workflow.job.WorkflowRun) NodeStepTypePredicate(org.jenkinsci.plugins.workflow.graphanalysis.NodeStepTypePredicate) InterpolatedSecretsAction(org.jenkinsci.plugins.workflow.cps.view.InterpolatedSecretsAction) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode) Issue(org.jvnet.hudson.test.Issue) Test(org.junit.Test)

Example 5 with InterpolatedSecretsAction

use of org.jenkinsci.plugins.workflow.cps.view.InterpolatedSecretsAction in project workflow-cps-plugin by jenkinsci.

the class DSLTest method complexSensitiveVariableInterpolationWithNestedDescribable.

@Issue("JENKINS-63254")
@Test
public void complexSensitiveVariableInterpolationWithNestedDescribable() throws Exception {
    final String credentialsId = "creds-complexSensitiveVariableInterpolationWithNestedDescribable";
    final String username = "bob";
    final String password = "secr3t";
    UsernamePasswordCredentialsImpl c = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample", username, password);
    c.setUsernameSecret(true);
    CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), c);
    p.setDefinition(new CpsFlowDefinition("" + "node {\n" + "withCredentials([usernamePassword(credentialsId: '" + credentialsId + "', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {\n" + "monomorphListSymbolStep([monomorphSymbol(firstArg: monomorphWithSymbolStep(monomorphSymbol([firstArg: \"innerFirstArgIs${PASSWORD}\", secondArg: \"innerSecondArgIs${USERNAME}\"])), secondArg: \"hereismy${PASSWORD}\"), monomorphSymbol(firstArg: \"${PASSWORD}\", secondArg: \"${USERNAME}\")])" + "}\n" + "}", true));
    WorkflowRun run = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
    r.assertLogContains("Warning: A secret was passed to \"monomorphWithSymbolStep\"", run);
    r.assertLogContains("Affected argument(s) used the following variable(s): [PASSWORD, USERNAME]", run);
    r.assertLogContains("Warning: A secret was passed to \"monomorphListSymbolStep\"", run);
    r.assertLogNotContains("Affected argument(s) used the following variable(s): [PASSWORD]", run);
    InterpolatedSecretsAction reportAction = run.getAction(InterpolatedSecretsAction.class);
    Assert.assertNotNull(reportAction);
    List<InterpolatedSecretsAction.InterpolatedWarnings> warnings = reportAction.getWarnings();
    MatcherAssert.assertThat(warnings.size(), is(2));
    InterpolatedSecretsAction.InterpolatedWarnings stepWarning = warnings.get(0);
    MatcherAssert.assertThat(stepWarning.getStepName(), is("monomorphWithSymbolStep"));
    MatcherAssert.assertThat(stepWarning.getInterpolatedVariables(), equalTo(Arrays.asList("PASSWORD", "USERNAME")));
    InterpolatedSecretsAction.InterpolatedWarnings listStepWarning = warnings.get(1);
    MatcherAssert.assertThat(listStepWarning.getStepName(), is("monomorphListSymbolStep"));
    MatcherAssert.assertThat(listStepWarning.getInterpolatedVariables(), equalTo(Arrays.asList("PASSWORD", "USERNAME")));
}
Also used : Matchers.containsString(org.hamcrest.Matchers.containsString) InterpolatedSecretsAction(org.jenkinsci.plugins.workflow.cps.view.InterpolatedSecretsAction) UsernamePasswordCredentialsImpl(com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl) WorkflowRun(org.jenkinsci.plugins.workflow.job.WorkflowRun) Issue(org.jvnet.hudson.test.Issue) Test(org.junit.Test)

Aggregations

InterpolatedSecretsAction (org.jenkinsci.plugins.workflow.cps.view.InterpolatedSecretsAction)7 Matchers.containsString (org.hamcrest.Matchers.containsString)6 WorkflowRun (org.jenkinsci.plugins.workflow.job.WorkflowRun)6 Test (org.junit.Test)6 UsernamePasswordCredentialsImpl (com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl)5 FlowNode (org.jenkinsci.plugins.workflow.graph.FlowNode)5 Issue (org.jvnet.hudson.test.Issue)5 ArgumentsAction (org.jenkinsci.plugins.workflow.actions.ArgumentsAction)4 LinearScanner (org.jenkinsci.plugins.workflow.graphanalysis.LinearScanner)4 NodeStepTypePredicate (org.jenkinsci.plugins.workflow.graphanalysis.NodeStepTypePredicate)4 Continuable (com.cloudbees.groovy.cps.Continuable)1 Outcome (com.cloudbees.groovy.cps.Outcome)1 CheckForNull (edu.umd.cs.findbugs.annotations.CheckForNull)1 NonNull (edu.umd.cs.findbugs.annotations.NonNull)1 Nullable (edu.umd.cs.findbugs.annotations.Nullable)1 SuppressFBWarnings (edu.umd.cs.findbugs.annotations.SuppressFBWarnings)1 Closure (groovy.lang.Closure)1 GString (groovy.lang.GString)1 GroovyObject (groovy.lang.GroovyObject)1 GroovyObjectSupport (groovy.lang.GroovyObjectSupport)1