如何用SonarQube检测JSP中未使用<c:out>的XSS漏洞?
Hey there! Let's break this down for you since you're new to SonarQube and focused on catching XSS risks in JSP files—specifically cases where <c:out> should be used but isn't.
First: Check SonarQube's Built-in Rules
SonarQube's Java plugin already includes security rules that target XSS vulnerabilities in JSPs, though they might not explicitly check for missing <c:out> tags. Instead, they flag unsafe output practices that lead to XSS, like:
- Directly outputting user-controlled data via scriptlets (
<%= userInput %>) without proper escaping - Using unescaped EL expressions (e.g.,
${userInput}) that aren't wrapped in<c:out>
To find and enable these rules:
- Go to your SonarQube instance's Rules page
- Filter by Language: Java and search for keywords like "XSS" or "JSP"
- Look for rules such as "XSS vulnerability due to unsafe output of user-controlled data in JSP" (exact wording might vary by SonarQube version)
- Add these rules to your quality profile, then run a scan on your project. These rules will catch many cases where
<c:out>is missing and unescaped output is present.
If Built-in Rules Aren't Enough: Custom Rule Development
If you need to explicitly enforce the use of <c:out> (rather than just flagging unsafe output), you'll need to create a custom SonarQube rule. Here's a high-level guide:
1. Set Up the Custom Rule Project
- Use SonarQube's official custom rule template for Java (you can generate one via Maven archetype)
- Include dependencies for
sonar-java-pluginandsonar-plugin-apiin your project
2. Write the Rule Logic
Your rule will need to parse JSP files and detect instances where user-controlled data is output without <c:out>. For example:
- Scan for scriptlet expressions (
<%= ... %>) that reference user-controlled variables (like request parameters, session attributes) - Scan for unescaped EL expressions (e.g.,
${userInput}) that aren't wrapped in<c:out>
Here's a simplified snippet of what the rule logic might look like (using SonarJava's API):
public class MissingCOutRule extends BaseTreeVisitor implements JavaFileScanner { private RuleContext context; @Override public void scanFile(RuleContext context) { this.context = context; scan(context.getTree()); } @Override public void visitExpressionStatement(ExpressionStatement tree) { if (tree.expression() instanceof LiteralTree) { // Skip literals, focus on variables/expressions return; } // Check if the expression is a scriptlet output (<%= ... %>) // and if the variable is user-controlled // If so, raise an issue suggesting to use <c:out> context.reportIssue(this, tree, "Use <c:out> tag to escape user-controlled output and prevent XSS"); super.visitExpressionStatement(tree); } }
3. Package and Deploy the Rule
- Package your custom rule into a JAR file
- Place the JAR in SonarQube's
extensions/pluginsdirectory - Restart your SonarQube server
- The new rule will appear in the Rules page—add it to your quality profile and run a scan
Quick Tips
- When using built-in rules, make sure your quality profile is set to include all relevant security rules (don't stick to the default "Sonar way" if it's missing XSS checks)
- For custom rules, test with sample JSP files (one that uses
<c:out>correctly, one that doesn't) to ensure the rule triggers only when intended - Remember that
<c:out>defaults toescapeXml="true", which is what prevents XSS—your rule should also ensure this attribute isn't set tofalseunnecessarily
内容的提问来源于stack exchange,提问作者James F

