diff --git a/pom.xml b/pom.xml index 010439d5..3745a77a 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ io.jenkins.tools.bom bom-2.176.x - 9 + 16 import pom diff --git a/src/main/java/org/jenkinsci/plugins/workflow/support/DefaultStepContext.java b/src/main/java/org/jenkinsci/plugins/workflow/support/DefaultStepContext.java index 4ccdbcc4..2b15f9c3 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/support/DefaultStepContext.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/support/DefaultStepContext.java @@ -31,11 +31,18 @@ import hudson.model.Computer; import hudson.model.Job; import hudson.model.Node; +import hudson.model.ParameterValue; +import hudson.model.ParametersAction; +import hudson.model.PasswordParameterValue; import hudson.model.Run; import hudson.model.TaskListener; import java.io.IOException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Collectors; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import org.jenkinsci.plugins.workflow.flow.FlowExecution; @@ -77,6 +84,9 @@ public abstract class DefaultStepContext extends StepContext { return value; } else if (key == TaskListener.class) { return key.cast(getListener(false)); + } else if (key == EnvironmentExpander.class) { + // Only called when `value == null` so that it does not override expanders contributed by steps. + return key.cast(new PasswordParameterEnvironmentExpander(get(Run.class))); } else if (Node.class.isAssignableFrom(key)) { Computer c = get(Computer.class); Node n = null; @@ -172,4 +182,35 @@ private T castOrNull(Class key, Object o) { */ protected abstract @Nonnull FlowNode getNode() throws IOException; + /** + * Default implementation of {@link EnvironmentExpander} that recognizes password parameters as sensitive variables. + */ + private static class PasswordParameterEnvironmentExpander extends EnvironmentExpander { + private static final long serialVersionUID = 1L; + + private final Set passwordParameterVariables; + + public PasswordParameterEnvironmentExpander(Run run) { + ParametersAction action = run.getAction(ParametersAction.class); + if (action != null) { + passwordParameterVariables = action.getParameters().stream() + .filter(PasswordParameterValue.class::isInstance) + .map(ParameterValue::getName) + .collect(Collectors.toCollection(() -> new HashSet<>())); // Make sure the set is serializable. + } else { + passwordParameterVariables = Collections.emptySet(); + } + } + + @Override + public void expand(EnvVars ev) { + // Do nothing. + } + + @Override + public Set getSensitiveVariables() { + return passwordParameterVariables; + } + } + }