diff --git a/core/src/main/java/hudson/model/BooleanParameterDefinition.java b/core/src/main/java/hudson/model/BooleanParameterDefinition.java index 6bf1a50096e3..f1afa5d8c3b7 100644 --- a/core/src/main/java/hudson/model/BooleanParameterDefinition.java +++ b/core/src/main/java/hudson/model/BooleanParameterDefinition.java @@ -29,6 +29,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import java.util.Objects; +import jenkins.model.EnvironmentVariableParameterNameFormValidation; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; @@ -125,7 +126,7 @@ public boolean equals(Object obj) { // unlike all the other ParameterDescriptors, using 'booleanParam' as the primary // to avoid picking the Java reserved word "boolean" as the primary identifier @Extension @Symbol("booleanParam") - public static class DescriptorImpl extends ParameterDescriptor { + public static class DescriptorImpl extends ParameterDescriptor implements EnvironmentVariableParameterNameFormValidation { @NonNull @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/model/ChoiceParameterDefinition.java b/core/src/main/java/hudson/model/ChoiceParameterDefinition.java index 98bdcf2e8072..d4c682a36201 100644 --- a/core/src/main/java/hudson/model/ChoiceParameterDefinition.java +++ b/core/src/main/java/hudson/model/ChoiceParameterDefinition.java @@ -13,6 +13,7 @@ import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; +import jenkins.model.EnvironmentVariableParameterNameFormValidation; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; @@ -202,7 +203,7 @@ public boolean equals(Object obj) { } @Extension @Symbol({"choice", "choiceParam"}) - public static class DescriptorImpl extends ParameterDescriptor { + public static class DescriptorImpl extends ParameterDescriptor implements EnvironmentVariableParameterNameFormValidation { @NonNull @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/model/FileParameterDefinition.java b/core/src/main/java/hudson/model/FileParameterDefinition.java index b8332f5911c5..0e012e84f922 100644 --- a/core/src/main/java/hudson/model/FileParameterDefinition.java +++ b/core/src/main/java/hudson/model/FileParameterDefinition.java @@ -34,6 +34,7 @@ import java.io.IOException; import java.nio.file.Files; import java.util.Objects; +import jenkins.model.EnvironmentVariableParameterNameFormValidation; import net.sf.json.JSONObject; import org.apache.commons.fileupload2.core.FileItem; import org.apache.commons.io.FileUtils; @@ -73,7 +74,7 @@ public FileParameterValue createValue(StaplerRequest2 req, JSONObject jo) { } @Extension @Symbol({"file", "fileParam"}) - public static class DescriptorImpl extends ParameterDescriptor { + public static class DescriptorImpl extends ParameterDescriptor implements EnvironmentVariableParameterNameFormValidation { @NonNull @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/model/PasswordParameterDefinition.java b/core/src/main/java/hudson/model/PasswordParameterDefinition.java index 901f1ee66712..e02ce2a34b5e 100644 --- a/core/src/main/java/hudson/model/PasswordParameterDefinition.java +++ b/core/src/main/java/hudson/model/PasswordParameterDefinition.java @@ -30,6 +30,7 @@ import hudson.Extension; import hudson.util.Secret; import java.util.Objects; +import jenkins.model.EnvironmentVariableParameterNameFormValidation; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; @@ -137,7 +138,7 @@ public boolean equals(Object obj) { } @Extension @Symbol("password") - public static final class ParameterDescriptorImpl extends ParameterDescriptor { + public static final class ParameterDescriptorImpl extends ParameterDescriptor implements EnvironmentVariableParameterNameFormValidation { @NonNull @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/model/RunParameterDefinition.java b/core/src/main/java/hudson/model/RunParameterDefinition.java index 487d895839dd..cae02ce79b57 100644 --- a/core/src/main/java/hudson/model/RunParameterDefinition.java +++ b/core/src/main/java/hudson/model/RunParameterDefinition.java @@ -32,6 +32,7 @@ import hudson.util.RunList; import java.util.Objects; import java.util.logging.Logger; +import jenkins.model.EnvironmentVariableParameterNameFormValidation; import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; @@ -142,7 +143,7 @@ public RunList getBuilds() { } @Extension @Symbol({"run", "runParam"}) - public static class DescriptorImpl extends ParameterDescriptor { + public static class DescriptorImpl extends ParameterDescriptor implements EnvironmentVariableParameterNameFormValidation { @NonNull @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/model/StringParameterDefinition.java b/core/src/main/java/hudson/model/StringParameterDefinition.java index 160e1b1a9c0c..ea40831eb178 100644 --- a/core/src/main/java/hudson/model/StringParameterDefinition.java +++ b/core/src/main/java/hudson/model/StringParameterDefinition.java @@ -30,6 +30,7 @@ import hudson.Extension; import hudson.Util; import java.util.Objects; +import jenkins.model.EnvironmentVariableParameterNameFormValidation; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; @@ -133,7 +134,7 @@ public StringParameterValue getDefaultParameterValue() { } @Extension @Symbol({"string", "stringParam"}) - public static class DescriptorImpl extends ParameterDescriptor { + public static class DescriptorImpl extends ParameterDescriptor implements EnvironmentVariableParameterNameFormValidation { @Override @NonNull public String getDisplayName() { diff --git a/core/src/main/java/hudson/model/TextParameterDefinition.java b/core/src/main/java/hudson/model/TextParameterDefinition.java index 96d973dc765a..727ba507cc62 100644 --- a/core/src/main/java/hudson/model/TextParameterDefinition.java +++ b/core/src/main/java/hudson/model/TextParameterDefinition.java @@ -29,6 +29,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import java.util.Objects; +import jenkins.model.EnvironmentVariableParameterNameFormValidation; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; @@ -54,7 +55,7 @@ public TextParameterDefinition(@NonNull String name, @CheckForNull String defaul } @Extension @Symbol({"text", "textParam"}) - public static class DescriptorImpl extends ParameterDescriptor { + public static class DescriptorImpl extends ParameterDescriptor implements EnvironmentVariableParameterNameFormValidation { @NonNull @Override public String getDisplayName() { diff --git a/core/src/main/java/jenkins/model/EnvironmentVariableParameterNameFormValidation.java b/core/src/main/java/jenkins/model/EnvironmentVariableParameterNameFormValidation.java new file mode 100644 index 000000000000..f7d5cbd5315c --- /dev/null +++ b/core/src/main/java/jenkins/model/EnvironmentVariableParameterNameFormValidation.java @@ -0,0 +1,46 @@ +package jenkins.model; + +import hudson.util.FormValidation; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.TreeSet; +import java.util.logging.Level; +import java.util.logging.Logger; +import jenkins.util.SystemProperties; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.QueryParameter; + +/** + * Convenient interface adding form validation for parameter 'name' fields, emitting a warning if it case-insensitively matches a known environment variable causing trouble during the build. + *
+ * This is intended to check for accidental name matches (in particular given Jenkins's case insensitive behavior), rather than intentional matches. + * Someone who wants to set LD_PRELOAD or DYLD_LIBRARY_PATH does so intentionally. + *
+ * + * @since TODO + */ +public interface EnvironmentVariableParameterNameFormValidation { + default FormValidation doCheckName(@QueryParameter String value) { + if (Configuration.DISCOURAGED_NAMES.contains(value)) { + return FormValidation.warning(Messages.ParameterNameFormValidation_Warning(value)); + } + return FormValidation.ok(); + } + + @Restricted(NoExternalUse.class) + class Configuration { + private static final Logger LOGGER = Logger.getLogger(EnvironmentVariableParameterNameFormValidation.class.getName()); + private static final String NAMES = SystemProperties.getString(EnvironmentVariableParameterNameFormValidation.class.getName() + ".NAMES", "HOME,PATH,USER"); + + private static final Collection