diff --git a/rules/java/spring/model_reflected_xss.yml b/rules/java/spring/model_reflected_xss.yml new file mode 100644 index 00000000..3bdf98c2 --- /dev/null +++ b/rules/java/spring/model_reflected_xss.yml @@ -0,0 +1,55 @@ +imports: + - java_shared_lang_external_input + - java_shared_lang_instance +patterns: + - pattern: | + $.addAttribute($<_>, $); + filters: + - variable: MODEL_INSTANCE + detection: java_shared_lang_instance + scope: cursor + filters: + - variable: JAVA_SHARED_LANG_INSTANCE_TYPE + regex: \A(org\.springframework\.ui\.)?Model\z + - variable: USER_INPUT + detection: java_spring_model_reflected_xss_unsanitized_input + scope: cursor +auxiliary: + - id: java_spring_model_reflected_xss_unsanitized_input + patterns: + - pattern: $; + filters: + - variable: USER_INPUT + detection: java_shared_lang_external_input + scope: cursor_strict + - not: + variable: USER_INPUT + detection: java_spring_model_reflected_xss_request_url_string + - id: java_spring_model_reflected_xss_request_url_string + patterns: + - pattern: $<_>.getRequestURL().toString(); + +languages: + - java +metadata: + description: "Unsanitized request data in Spring UI model (XSS)" + remediation_message: |- + ## Description + + Cross-site scripting (XSS) vulnerabilities occur when unsanitized user input is included in web page content. This flaw can lead to malicious scripts being executed in the context of the user's browser, compromising the security of user data and interactions with the application. + + ## Remediations + + - **Do** validate the input before adding it to the UI model. + - **Do** sanitize user input to remove or neutralize unwanted scripts. + + ## References + + - [OWASP XSS Prevention Cheatsheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html) + - [OWASP Java Encoder](https://owasp.org/www-project-java-encoder/) + - [Spring HtmlUtils](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/util/HtmlUtils.html) + cwe_id: + - 79 + id: "java_spring_model_reflected_xss" + documentation_url: https://docs.bearer.com/reference/rules/java_spring_model_reflected_xss +severity: high diff --git a/tests/java/spring/model_reflected_xss/test.js b/tests/java/spring/model_reflected_xss/test.js new file mode 100644 index 00000000..b3e3ded4 --- /dev/null +++ b/tests/java/spring/model_reflected_xss/test.js @@ -0,0 +1,19 @@ +const { + createNewInvoker, + getEnvironment, +} = require("../../../helper.js") +const { ruleId, ruleFile, testBase } = getEnvironment(__dirname) + +describe(ruleId, () => { + const invoke = createNewInvoker(ruleId, ruleFile, testBase) + + + test("main", () => { + const testCase = "main.java" + + const results = invoke(testCase) + + expect(results.Missing).toEqual([]) + expect(results.Extra).toEqual([]) + }) +}) \ No newline at end of file diff --git a/tests/java/spring/model_reflected_xss/testdata/main.java b/tests/java/spring/model_reflected_xss/testdata/main.java new file mode 100644 index 00000000..8eaccd52 --- /dev/null +++ b/tests/java/spring/model_reflected_xss/testdata/main.java @@ -0,0 +1,20 @@ +package com.example.model.xss; + +import org.springframework.ui.Model; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; + +@Controller +public class LoginController { + + @PostMapping("/updateUser") + public String updateUser(@RequestParam(name = "bad") String bad, Model model) { + // bearer:expected java_spring_model_reflected_xss + model.addAttribute("displayname", bad); + } + + @PostMapping("/submit") + public String updateUser(@RequestParam(id = "id") String id, Model model) { + model.addAttribute("selected", Integer.parseInt(id)); + } +}