diff --git a/java/ql/src/semmle/code/java/dataflow/FlowSources.qll b/java/ql/src/semmle/code/java/dataflow/FlowSources.qll index e17e60f4ca6..5bb471259b3 100644 --- a/java/ql/src/semmle/code/java/dataflow/FlowSources.qll +++ b/java/ql/src/semmle/code/java/dataflow/FlowSources.qll @@ -17,8 +17,7 @@ import semmle.code.java.frameworks.android.WebView import semmle.code.java.frameworks.JaxWS import semmle.code.java.frameworks.javase.WebSocket import semmle.code.java.frameworks.android.Intent -import semmle.code.java.frameworks.play.PlayController -import semmle.code.java.frameworks.play.PlayHTTPRequestHeader +import semmle.code.java.frameworks.play.Play import semmle.code.java.frameworks.spring.SpringWeb import semmle.code.java.frameworks.spring.SpringController import semmle.code.java.frameworks.spring.SpringWebClient @@ -279,7 +278,7 @@ private class RemoteTaintedMethod extends Method { private class PlayRequestGetMethod extends Method { PlayRequestGetMethod() { this.getDeclaringType() instanceof PlayMVCHTTPRequestHeader and - this.hasName(["header", "getHeader"]) + this.hasName(["queryString","getQueryString","header", "getHeader"]) } } diff --git a/java/ql/src/semmle/code/java/frameworks/play/Play.qll b/java/ql/src/semmle/code/java/frameworks/play/Play.qll index 18f6dabf468..252379674b2 100644 --- a/java/ql/src/semmle/code/java/frameworks/play/Play.qll +++ b/java/ql/src/semmle/code/java/frameworks/play/Play.qll @@ -1,9 +1,165 @@ import java -import semmle.code.java.dataflow.FlowSources -import semmle.code.java.frameworks.play.PlayController -import semmle.code.java.frameworks.play.PlayAddCSRFToken -import semmle.code.java.frameworks.play.PlayAsyncResult -import semmle.code.java.frameworks.play.PlayBodyParser -import semmle.code.java.frameworks.play.PlayHTTPRequestHeader -import semmle.code.java.frameworks.play.PlayMVCResult -import semmle.code.java.frameworks.play.PlayMVCResults + +/** + * Play MVC Framework Result Class + */ +class PlayMVCResultClass extends Class { + PlayMVCResultClass() { this.hasQualifiedName("play.mvc", "Result") } +} + +/** + * Play MVC Framework Results Class + * + * Documentation: https://www.playframework.com/documentation/2.8.x/JavaActions + */ +class PlayMVCResultsClass extends Class { + PlayMVCResultsClass() { this.hasQualifiedName("play.mvc", "Results") } +} + +/** + * Play MVC Framework HTTP Request Header Class + */ +class PlayMVCHTTPRequestHeader extends RefType { + PlayMVCHTTPRequestHeader() { this.hasQualifiedName("play.mvc", "Http$RequestHeader") } +} + +/** + * Play Framework Explicit Body Parser Annotation + * + * Documentation: https://www.playframework.com/documentation/2.8.x/JavaBodyParsers#Choosing-an-explicit-body-parser + */ +class PlayBodyParserAnnotation extends Annotation { + PlayBodyParserAnnotation() { this.getType().hasQualifiedName("play.mvc", "BodyParser<>$Of") } +} + +/** + * Play Framework AddCSRFToken Annotation + * + * Documentation: https://www.playframework.com/documentation/2.8.x/JavaCsrf + */ +class PlayAddCSRFTokenAnnotation extends Annotation { + PlayAddCSRFTokenAnnotation() { + this.getType().hasQualifiedName("play.filters.csrf", "AddCSRFToken") + } +} + +/** + * Play Framework Async Promise - Gets the Promise Generic Member/Type of (play.libs.F) + * + * Documentation: https://www.playframework.com/documentation/2.5.1/api/java/play/libs/F.Promise.html + */ +class PlayAsyncResultPromise extends Member { + PlayAsyncResultPromise() { + exists(Class c | + c.hasQualifiedName("play.libs", "F") and + this = c.getAMember() and + this.getQualifiedName() = "F.Promise" + ) + } +} + +/** + * Play Framework Async Generic Result - Gets the CompletionStage Generic Type of (java.util.concurrent) + * + * Documentation: https://www.playframework.com/documentation/2.6.x/JavaAsync + */ +class PlayAsyncResultCompletionStage extends Type { + PlayAsyncResultCompletionStage() { + this.hasName("CompletionStage") and + this.getCompilationUnit().getPackage().hasName("java.util.concurrent") + } +} + +/** + * Play Framework Controllers which extends PlayMVCController recursively - Used to find all Controllers + */ +class PlayController extends Class { + PlayController() { + this.extendsOrImplements*(any(Class t | t.hasQualifiedName("play.mvc", "Controller"))) + } +} + +/** + * Play Framework Controller Action Methods - Mappings to route files + * + * Sample Route - `POST /login @com.company.Application.login()` + * + * Example - class get's `index` & `login` as valid action methods. + * ``` + * public class Application extends Controller { + * public Result index(String username, String password) { + * return ok("It works!"); + * } + * + * public Result login() { + * return ok("Log me In!"); + * } + * } + * ``` + * + * Documentation: https://www.playframework.com/documentation/2.8.x/JavaActions + */ +class PlayControllerActionMethod extends Method { + PlayControllerActionMethod() { + this = any(PlayController c).getAMethod() and + ( + this.getReturnType() instanceof PlayAsyncResultPromise or + this.getReturnType() instanceof PlayMVCResultClass or + this.getReturnType() instanceof PlayAsyncResultCompletionStage + ) + } +} + +/** + * Play Action-Method parameters. These are a source of user input + * + * Example - Class get's `username` & `password` as valid parameters + * ``` + * public class Application extends Controller { + * public Result index(String username, String password) { + * return ok("It works!"); + * } + * } + * ``` + */ +class PlayActionMethodQueryParameter extends Parameter { + PlayActionMethodQueryParameter() { + exists(PlayControllerActionMethod a | + a.isPublic() and + this = a.getAParameter() + ) + } +} + +/** + * Play Framework HTTPRequestHeader Methods - `headers`, `getQueryString`, `getHeader` + * + * Documentation: https://www.playframework.com/documentation/2.6.0/api/java/play/mvc/Http.RequestHeader.html + */ +class PlayMVCHTTPRequestHeaderMethods extends Method { + PlayMVCHTTPRequestHeaderMethods() { this.getDeclaringType() instanceof PlayMVCHTTPRequestHeader } + + /** + * Gets all references to play.mvc.HTTP.RequestHeader `getQueryString` method + */ + MethodAccess getQueryString() { this.hasName("getQueryString") and result = this.getAReference() } +} + +/** + * Play Framework mvc.Results Methods - `ok`, `status`, `redirect` + * + * Documentation: https://www.playframework.com/documentation/2.5.8/api/java/play/mvc/Results.html + */ +class PlayMVCResultsMethods extends Method { + PlayMVCResultsMethods() { this.getDeclaringType() instanceof PlayMVCResultsClass } + + /** + * Gets all references to play.mvc.Results `ok` method + */ + MethodAccess getAnOkAccess() { this.hasName("ok") and result = this.getAReference() } + + /** + * Gets all references to play.mvc.Results `redirect` method + */ + MethodAccess getARedirectAccess() { this.hasName("redirect") and result = this.getAReference() } +} diff --git a/java/ql/src/semmle/code/java/frameworks/play/PlayAddCSRFToken.qll b/java/ql/src/semmle/code/java/frameworks/play/PlayAddCSRFToken.qll deleted file mode 100644 index 3b289e23c37..00000000000 --- a/java/ql/src/semmle/code/java/frameworks/play/PlayAddCSRFToken.qll +++ /dev/null @@ -1,12 +0,0 @@ -import java - -/** - * Play Framework AddCSRFToken Annotation - * - * Documentation: https://www.playframework.com/documentation/2.8.x/JavaCsrf - */ -class PlayAddCSRFTokenAnnotation extends Annotation { - PlayAddCSRFTokenAnnotation() { - this.getType().hasQualifiedName("play.filters.csrf", "AddCSRFToken") - } -} diff --git a/java/ql/src/semmle/code/java/frameworks/play/PlayAsyncResult.qll b/java/ql/src/semmle/code/java/frameworks/play/PlayAsyncResult.qll deleted file mode 100644 index 27edc7a2521..00000000000 --- a/java/ql/src/semmle/code/java/frameworks/play/PlayAsyncResult.qll +++ /dev/null @@ -1,28 +0,0 @@ -import java - -/** - * Play Framework Async Promise - Gets the Promise Generic Member/Type of (play.libs.F) - * - * Documentation: https://www.playframework.com/documentation/2.5.1/api/java/play/libs/F.Promise.html - */ -class PlayAsyncResultPromise extends Member { - PlayAsyncResultPromise() { - exists(Class c | - c.hasQualifiedName("play.libs", "F") and - this = c.getAMember() and - this.getQualifiedName() = "F.Promise" - ) - } -} - -/** - * Play Framework Async Generic Result - Gets the CompletionStage Generic Type of (java.util.concurrent) - * - * Documentation: https://www.playframework.com/documentation/2.6.x/JavaAsync - */ -class PlayAsyncResultCompletionStage extends Type { - PlayAsyncResultCompletionStage() { - this.hasName("CompletionStage") and - this.getCompilationUnit().getPackage().hasName("java.util.concurrent") - } -} diff --git a/java/ql/src/semmle/code/java/frameworks/play/PlayBodyParser.qll b/java/ql/src/semmle/code/java/frameworks/play/PlayBodyParser.qll deleted file mode 100644 index 167bea85d4e..00000000000 --- a/java/ql/src/semmle/code/java/frameworks/play/PlayBodyParser.qll +++ /dev/null @@ -1,10 +0,0 @@ -import java - -/** - * Play Framework Explicit Body Parser Annotation - * - * Documentation: https://www.playframework.com/documentation/2.8.x/JavaBodyParsers#Choosing-an-explicit-body-parser - */ -class PlayBodyParserAnnotation extends Annotation { - PlayBodyParserAnnotation() { this.getType().hasQualifiedName("play.mvc", "BodyParser<>$Of") } -} diff --git a/java/ql/src/semmle/code/java/frameworks/play/PlayController.qll b/java/ql/src/semmle/code/java/frameworks/play/PlayController.qll deleted file mode 100644 index af05d96de23..00000000000 --- a/java/ql/src/semmle/code/java/frameworks/play/PlayController.qll +++ /dev/null @@ -1,73 +0,0 @@ -import java -import semmle.code.java.frameworks.play.PlayAsyncResult -import semmle.code.java.frameworks.play.PlayMVCResult - -/** - * Play MVC Framework Controller - */ -class PlayMVCControllerClass extends Class { - PlayMVCControllerClass() { this.hasQualifiedName("play.mvc", "Controller") } -} - -/** - * Play Framework Controllers which extends/implements PlayMVCController recursively - Used to find all Controllers - */ -class PlayController extends Class { - PlayController() { - exists(Class t | this.extendsOrImplements*(t) and t instanceof PlayMVCControllerClass) - } -} - -/** - * Play Framework Controller Action Methods - Mappings to route files - * - * Sample Route - `POST /login @com.linkedin.Application.login()` - * - * Example - class get's `index` & `login` as valid action methods. - * ``` - * public class Application extends Controller { - * public Result index(String username, String password) { - * return ok("It works!"); - * } - * - * public Result login() { - * return ok("Log me In!"); - * } - * } - * ``` - * - * Documentation: https://www.playframework.com/documentation/2.8.x/JavaActions - */ -class PlayControllerActionMethod extends Method { - PlayControllerActionMethod() { - exists(PlayController controller | - this = controller.getAMethod() and - ( - this.getReturnType() instanceof PlayAsyncResultPromise or - this.getReturnType() instanceof PlayMVCResultClass or - this.getReturnType() instanceof PlayAsyncResultCompletionStage - ) - ) - } -} - -/** - * Play Action-Method parameters. These are a source of user input - * - * Example - Class get's `username` & `password` as valid parameters - * ``` - * public class Application extends Controller { - * public Result index(String username, String password) { - * return ok("It works!"); - * } - * } - * ``` - */ -class PlayActionMethodQueryParameter extends Parameter { - PlayActionMethodQueryParameter() { - exists(PlayControllerActionMethod a | - a.isPublic() and - this = a.getAParameter() - ) - } -} diff --git a/java/ql/src/semmle/code/java/frameworks/play/PlayHTTPRequestHeader.qll b/java/ql/src/semmle/code/java/frameworks/play/PlayHTTPRequestHeader.qll deleted file mode 100644 index 539253dab4a..00000000000 --- a/java/ql/src/semmle/code/java/frameworks/play/PlayHTTPRequestHeader.qll +++ /dev/null @@ -1,25 +0,0 @@ -import java - -/** - * Play MVC Framework HTTP Request Header Class - */ -class PlayMVCHTTPRequestHeader extends RefType { - PlayMVCHTTPRequestHeader() { this.hasQualifiedName("play.mvc", "Http$RequestHeader") } -} - -/** - * Play Framework HTTPRequestHeader Methods - `headers`, `getQueryString`, `getHeader` - * - * Documentation: https://www.playframework.com/documentation/2.6.0/api/java/play/mvc/Http.RequestHeader.html - */ -class PlayMVCHTTPRequestHeaderMethods extends Method { - PlayMVCHTTPRequestHeaderMethods() { this.getDeclaringType() instanceof PlayMVCHTTPRequestHeader } - - /** - * Gets all references to play.mvc.HTTP.RequestHeader `getQueryString` method - */ - MethodAccess getQueryString() { - this.hasName("getQueryString") and result = this.getAReference() - } - -} diff --git a/java/ql/src/semmle/code/java/frameworks/play/PlayMVCResult.qll b/java/ql/src/semmle/code/java/frameworks/play/PlayMVCResult.qll deleted file mode 100644 index 027f8fe0907..00000000000 --- a/java/ql/src/semmle/code/java/frameworks/play/PlayMVCResult.qll +++ /dev/null @@ -1,8 +0,0 @@ -import java - -/** - * Play MVC Framework Result Class - */ -class PlayMVCResultClass extends Class { - PlayMVCResultClass() { this.hasQualifiedName("play.mvc", "Result") } -} diff --git a/java/ql/src/semmle/code/java/frameworks/play/PlayMVCResults.qll b/java/ql/src/semmle/code/java/frameworks/play/PlayMVCResults.qll deleted file mode 100644 index c03a9358ce5..00000000000 --- a/java/ql/src/semmle/code/java/frameworks/play/PlayMVCResults.qll +++ /dev/null @@ -1,33 +0,0 @@ -import java - -/** - * Play MVC Framework Results Class - * - * Documentation: https://www.playframework.com/documentation/2.8.x/JavaActions - */ -class PlayMVCResultsClass extends Class { - PlayMVCResultsClass() { this.hasQualifiedName("play.mvc", "Results") } -} - -/** - * Play Framework mvc.Results Methods - `ok`, `status`, `redirect` - * - * Documentation: https://www.playframework.com/documentation/2.5.8/api/java/play/mvc/Results.html - */ -class PlayMVCResultsMethods extends Method { - PlayMVCResultsMethods() { this.getDeclaringType() instanceof PlayMVCResultsClass } - - /** - * Gets all references to play.mvc.Results `ok` method - */ - MethodAccess getAnOkAccess() { - this.hasName("ok") and result = this.getAReference() - } - - /** - * Gets all references to play.mvc.Results `redirect` method - */ - MethodAccess getARedirectAccess() { - this.hasName("redirect") and result = this.getAReference() - } -}