From 8c7ed77ac622d962301968dbac5a6a94ab18c8a3 Mon Sep 17 00:00:00 2001 From: Ulli Hafner Date: Sat, 28 Nov 2020 00:52:29 +0100 Subject: [PATCH] Enforce that validation methods must be called with @POST. For details see https://www.jenkins.io/doc/developer/security/form-validation/. --- plugin/pom.xml | 2 +- .../git/reference/GitReferenceRecorder.java | 2 + .../GitReferenceRecorder/config.jelly | 4 +- .../forensics/git/ArchitectureTest.java | 51 +++++++++++++++++-- 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/plugin/pom.xml b/plugin/pom.xml index b15c923e..6c79dfbd 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -28,7 +28,7 @@ 9.2.0 - 1.4.0 + 1.5.0 1.10.21-3 0.8.0-rc726.219087c7c31a diff --git a/plugin/src/main/java/io/jenkins/plugins/forensics/git/reference/GitReferenceRecorder.java b/plugin/src/main/java/io/jenkins/plugins/forensics/git/reference/GitReferenceRecorder.java index 968c07f9..f4567c0e 100644 --- a/plugin/src/main/java/io/jenkins/plugins/forensics/git/reference/GitReferenceRecorder.java +++ b/plugin/src/main/java/io/jenkins/plugins/forensics/git/reference/GitReferenceRecorder.java @@ -9,6 +9,7 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.verb.POST; import org.jenkinsci.Symbol; import hudson.Extension; import hudson.model.Run; @@ -123,6 +124,7 @@ public ComboBoxModel doFillReferenceJobItems() { * @return the validation result */ @Override + @POST @SuppressWarnings("unused") // Used in jelly validation public FormValidation doCheckReferenceJob(@QueryParameter final String referenceJob) { return model.validateJob(referenceJob); diff --git a/plugin/src/main/resources/io/jenkins/plugins/forensics/git/reference/GitReferenceRecorder/config.jelly b/plugin/src/main/resources/io/jenkins/plugins/forensics/git/reference/GitReferenceRecorder/config.jelly index b1a01648..8d593be3 100644 --- a/plugin/src/main/resources/io/jenkins/plugins/forensics/git/reference/GitReferenceRecorder/config.jelly +++ b/plugin/src/main/resources/io/jenkins/plugins/forensics/git/reference/GitReferenceRecorder/config.jelly @@ -1,8 +1,8 @@ - + - + diff --git a/plugin/src/test/java/io/jenkins/plugins/forensics/git/ArchitectureTest.java b/plugin/src/test/java/io/jenkins/plugins/forensics/git/ArchitectureTest.java index d3e50e69..c366a29a 100644 --- a/plugin/src/test/java/io/jenkins/plugins/forensics/git/ArchitectureTest.java +++ b/plugin/src/test/java/io/jenkins/plugins/forensics/git/ArchitectureTest.java @@ -1,5 +1,11 @@ package io.jenkins.plugins.forensics.git; +import javax.xml.parsers.SAXParser; + +import org.apache.commons.digester.Digester; +import org.apache.commons.digester.xmlrules.DigesterLoader; +import org.xml.sax.XMLReader; + import com.tngtech.archunit.junit.AnalyzeClasses; import com.tngtech.archunit.junit.ArchTest; import com.tngtech.archunit.lang.ArchRule; @@ -8,6 +14,11 @@ import io.jenkins.plugins.util.PluginArchitectureRules; +import static com.tngtech.archunit.base.DescribedPredicate.*; +import static com.tngtech.archunit.core.domain.JavaClass.Predicates.*; +import static com.tngtech.archunit.lang.conditions.ArchPredicates.*; +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.*; + /** * Defines several architecture rules for the static analysis model and parsers. * @@ -16,6 +27,15 @@ @SuppressWarnings("hideutilityclassconstructor") @AnalyzeClasses(packages = "io.jenkins.plugins.forensics.git..") class ArchitectureTest { + @ArchTest + static final ArchRule NO_TEST_API_CALLED = ArchitectureRules.NO_TEST_API_CALLED; + + @ArchTest + static final ArchRule NO_FORBIDDEN_ANNOTATION_USED = ArchitectureRules.NO_FORBIDDEN_ANNOTATION_USED; + + @ArchTest + static final ArchRule NO_FORBIDDEN_CLASSES_CALLED = ArchitectureRules.NO_FORBIDDEN_CLASSES_CALLED; + @ArchTest static final ArchRule NO_JENKINS_INSTANCE_CALL = PluginArchitectureRules.NO_JENKINS_INSTANCE_CALL; @@ -23,11 +43,36 @@ class ArchitectureTest { static final ArchRule NO_PUBLIC_TEST_CLASSES = PluginArchitectureRules.NO_PUBLIC_TEST_CLASSES; @ArchTest - static final ArchRule NO_TEST_API_CALLED = ArchitectureRules.NO_TEST_API_CALLED; + static final ArchRule NO_FORBIDDEN_PACKAGE_ACCESSED = PluginArchitectureRules.NO_FORBIDDEN_PACKAGE_ACCESSED; @ArchTest - static final ArchRule NO_FORBIDDEN_PACKAGE_ACCESSED = PluginArchitectureRules.NO_FORBIDDEN_PACKAGE_ACCESSED; + static final ArchRule AJAX_PROXY_METHOD_MUST_BE_IN_PUBLIC_CLASS = PluginArchitectureRules.AJAX_PROXY_METHOD_MUST_BE_IN_PUBLIC_CLASS; @ArchTest - static final ArchRule NO_FORBIDDEN_CLASSES_CALLED = ArchitectureRules.NO_FORBIDDEN_CLASSES_CALLED; + static final ArchRule DATA_BOUND_CONSTRUCTOR_MUST_BE_IN_PUBLIC_CLASS = PluginArchitectureRules.DATA_BOUND_CONSTRUCTOR_MUST_BE_IN_PUBLIC_CLASS; + + @ArchTest + static final ArchRule DATA_BOUND_SETTER_MUST_BE_IN_PUBLIC_CLASS = PluginArchitectureRules.DATA_BOUND_SETTER_MUST_BE_IN_PUBLIC_CLASS; + + @ArchTest + static final ArchRule USE_POST_FOR_VALIDATION_END_POINTS = PluginArchitectureRules.USE_POST_FOR_VALIDATION_END_POINTS; + + /** Digester must not be used directly, rather use a SecureDigester instance. */ + @ArchTest + static final ArchRule NO_DIGESTER_CONSTRUCTOR_CALLED = + noClasses().that().doNotHaveSimpleName("SecureDigester") + .should().callConstructor(Digester.class) + .orShould().callConstructor(Digester.class, SAXParser.class) + .orShould().callConstructor(Digester.class, XMLReader.class) + .orShould().callMethod(DigesterLoader.class, "createDigester"); + + /** Test classes should not use Junit 4. */ + // TODO: see https://github.com/TNG/ArchUnit/issues/136 + @ArchTest + static final ArchRule NO_JUNIT_4 = + noClasses().that(doNot( + have(simpleNameEndingWith("ITest")) + .or(have(simpleNameStartingWith("Integration"))) + .or(have(simpleName("ToolsLister"))))) + .should().dependOnClassesThat().resideInAnyPackage("org.junit"); }