Java: add class for Stapler web methods that are not default-protected from CSRF

This commit is contained in:
Jami Cogswell
2024-12-13 16:33:14 -05:00
parent 0f39011122
commit 286c655264
2 changed files with 53 additions and 0 deletions

View File

@@ -122,3 +122,40 @@ private class PostConstructDataBoundMethod extends Method {
this.getAnAnnotation() instanceof PostConstructAnnotation
}
}
/**
* A method intended for Stapler request routing.
*
* From: https://www.jenkins.io/doc/developer/handling-requests/actions/
* Web methods need to provide some indication that they are intended for Stapler routing:
* - Any applicable annotation recognized by Stapler, e.g., @RequirePOST.
* - Any inferable parameter type, e.g., StaplerRequest.
* - Any applicable parameter annotation, recognized by Stapler, e.g., @AncestorInPath.
* - Any declared exception type implementing HttpResponse, e.g., HttpResponseException.
* - A return type implementing HttpResponse.
*/
class StaplerWebMethod extends Method {
StaplerWebMethod() {
// Any applicable annotation recognized by Stapler, e.g., @RequirePOST.
this.hasAnnotation("org.kohsuke.stapler", "WebMethod")
or
this.hasAnnotation("org.kohsuke.stapler.interceptor", ["RequirePOST", "RespondSuccess"])
or
this.hasAnnotation("org.kohsuke.stapler.verb", ["DELETE", "GET", "POST", "PUT"])
or
// Any inferable parameter type, e.g., StaplerRequest.
this.getAParamType()
.(RefType)
.hasQualifiedName("org.kohsuke.stapler", ["StaplerRequest", "StaplerRequest2"])
or
// Any applicable parameter annotation, recognized by Stapler, e.g., @AncestorInPath
this.getAParameter()
.hasAnnotation("org.kohsuke.stapler", ["AncestorInPath", "QueryParameter", "Header"])
or
// A return type implementing HttpResponse
this.getReturnType().(RefType).getASourceSupertype*() instanceof HttpResponse
or
// Any declared exception type implementing HttpResponse, e.g., HttpResponseException
this.getAThrownExceptionType().getASourceSupertype*() instanceof HttpResponse
}
}

View File

@@ -2,6 +2,7 @@
import java
private import semmle.code.java.frameworks.spring.SpringController
private import semmle.code.java.frameworks.stapler.Stapler
private import semmle.code.java.frameworks.MyBatis
private import semmle.code.java.frameworks.Jdbc
private import semmle.code.java.dataflow.ExternalFlow
@@ -33,6 +34,21 @@ private class SpringCsrfUnprotectedMethod extends CsrfUnprotectedMethod instance
}
}
/**
* A Stapler web method that is not protected from CSRF by default.
*
* https://www.jenkins.io/doc/developer/security/form-validation/#protecting-from-csrf
*/
private class StaplerCsrfUnprotectedMethod extends CsrfUnprotectedMethod instanceof StaplerWebMethod
{
StaplerCsrfUnprotectedMethod() {
not (
this.hasAnnotation("org.kohsuke.stapler.interceptor", "RequirePOST") or
this.hasAnnotation("org.kohsuke.stapler.verb", "POST")
)
}
}
/** A method that updates a database. */
abstract class DatabaseUpdateMethod extends Method { }