Merge branch 'marob-master'

This commit is contained in:
Andreas Dangel 2014-09-29 21:02:44 +02:00
commit bb9039426b
6 changed files with 236 additions and 26 deletions

View File

@ -0,0 +1,36 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.jsp.rule.basic;
import net.sourceforge.pmd.lang.jsp.ast.ASTElExpression;
import net.sourceforge.pmd.lang.jsp.ast.ASTElement;
import net.sourceforge.pmd.lang.jsp.rule.AbstractJspRule;
/**
* This rule detects unsanitized JSP Expressions (can lead to Cross Site Scripting (XSS) attacks)
*
* @author maxime_robert
*/
public class NoUnsanitizedJSPExpressionRule extends AbstractJspRule {
@Override
public Object visit(ASTElExpression node, Object data) {
if (elOutsideTaglib(node)) {
addViolation(data, node);
}
return super.visit(node, data);
}
private boolean elOutsideTaglib(ASTElExpression node) {
ASTElement parentASTElement = (ASTElement) node.getFirstParentOfType(ASTElement.class);
boolean elInTaglib = parentASTElement != null && parentASTElement.getName() != null
&& parentASTElement.getName().contains(":");
boolean elWithFnEscapeXml = node.getImage() != null && node.getImage().matches("^fn:escapeXml\\(.+\\)$");
return !elInTaglib && !elWithFnEscapeXml;
}
}

View File

@ -292,5 +292,26 @@ Externalized script could be reused between pages. Browsers can also cache the
]]>
</example>
</rule>
<rule
name="NoUnsanitizedJSPExpression" since="5.1.4"
class="net.sourceforge.pmd.lang.jsp.rule.basic.NoUnsanitizedJSPExpressionRule"
message="Using unsanitized JSP expression can lead to Cross Site Scripting (XSS) attacks"
externalInfoUrl="${pmd.website.baseurl}/rules/jsp/basic.html#NoUnsanitizedJSPExpression">
<description>
Avoid using expressions without escaping / sanitizing. This could lead to cross site scripting - as the expression
would be interpreted by the browser directly (e.g. "&lt;script&gt;alert('hello');&lt;/script&gt;").
</description>
<priority>3</priority>
<example>
<![CDATA[
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
${expression} <!-- don't use this -->
${fn:escapeXml(expression)} <!-- instead, escape it -->
<c:out value="${expression}" /> <!-- or use c:out -->
]]>
</example>
</rule>
</ruleset>

View File

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<ruleset name="514"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
This ruleset contains links to rules that are new in PMD v5.1.4
</description>
<rule ref="rulesets/jsp/basic.xml/NoUnsanitizedJSPExpression"/>
</ruleset>

View File

@ -8,4 +8,9 @@
**Pull requests:**
* [#9](https://github.com/adangel/pmd/pull/9/): New rule: NoUnsanitizedJSPExpressionRule
**New/Modified Rules:**
* JSP - Basic ruleset:
* NoUnsanitizedJSPExpression: Using unsanitized JSP expression can lead to Cross Site Scripting (XSS) attacks

View File

@ -1,25 +1,26 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.jsp.rule.basic;
import net.sourceforge.pmd.testframework.SimpleAggregatorTst;
public class BasicRulesTest extends SimpleAggregatorTst {
private static final String RULESET = "jsp-basic";
@Override
public void setUp() {
addRule(RULESET, "DuplicateJspImports");
addRule(RULESET, "IframeMissingSrcAttribute");
addRule(RULESET, "JspEncoding");
addRule(RULESET, "NoClassAttribute");
addRule(RULESET, "NoHtmlComments");
addRule(RULESET, "NoInlineScript");
addRule(RULESET, "NoInlineStyleInformation");
addRule(RULESET, "NoJspForward");
addRule(RULESET, "NoLongScripts");
addRule(RULESET, "NoScriptlets");
}
}
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.jsp.rule.basic;
import net.sourceforge.pmd.testframework.SimpleAggregatorTst;
public class BasicRulesTest extends SimpleAggregatorTst {
private static final String RULESET = "jsp-basic";
@Override
public void setUp() {
addRule(RULESET, "DuplicateJspImports");
addRule(RULESET, "IframeMissingSrcAttribute");
addRule(RULESET, "JspEncoding");
addRule(RULESET, "NoClassAttribute");
addRule(RULESET, "NoHtmlComments");
addRule(RULESET, "NoInlineScript");
addRule(RULESET, "NoInlineStyleInformation");
addRule(RULESET, "NoJspForward");
addRule(RULESET, "NoLongScripts");
addRule(RULESET, "NoScriptlets");
addRule(RULESET, "NoUnsanitizedJSPExpression");
}
}

View File

@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8"?>
<test-data>
<test-code>
<description><![CDATA[
An EL outside taglib #1
]]></description>
<expected-problems>1</expected-problems>
<code><![CDATA[
<%@ page contentType="text/html; charset=UTF-8" %>
${shouldBeDetectedAsXSSSecurityBreach}
]]></code>
<source-type>jsp</source-type>
</test-code>
<test-code>
<description><![CDATA[
An EL outside taglib #2
]]></description>
<expected-problems>1</expected-problems>
<code><![CDATA[
<%@ page contentType="text/html; charset=UTF-8" %>
<html>
<input type="text" value="${shouldBeDetectedAsXSSSecurityBreach}" />
</html>
]]></code>
<source-type>jsp</source-type>
</test-code>
<test-code>
<description><![CDATA[
An EL outside taglib #3
]]></description>
<expected-problems>1</expected-problems>
<code><![CDATA[
<%@ page contentType="text/html; charset=UTF-8" %>
<html>
<input
type="text"
value="${shouldBeDetectedAsXSSSecurityBreach}"
name="toto"
/>
</html>
]]></code>
<source-type>jsp</source-type>
</test-code>
<test-code>
<description><![CDATA[
Multiple EL outside taglib
]]></description>
<expected-problems>3</expected-problems>
<code><![CDATA[
<%@ page contentType="text/html; charset=UTF-8" %>
${shouldBeDetectedAsXSSSecurityBreach}
<html>
${shouldBeDetectedAsXSSSecurityBreach}
<input
type="text"
value="${shouldBeDetectedAsXSSSecurityBreach}"
name="toto"
/>
<c:out value="${expression}" />
</html>
]]></code>
<source-type>jsp</source-type>
</test-code>
<test-code>
<description>c:out fixes it</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
<%@ page contentType="text/html; charset=UTF-8" %>
<html>
<c:out value="${expression}" />
</html>
]]></code>
<source-type>jsp</source-type>
</test-code>
<test-code>
<description>fn:escape fixes it</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
${fn:escapeXml(expression)}
]]></code>
<source-type>jsp</source-type>
</test-code>
<test-code>
<description>fn:escape as attribute value</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<html>
<input type="text" value="${fn:escapeXml(expression)}" />
</html>
]]></code>
<source-type>jsp</source-type>
</test-code>
<test-code>
<description>fn:escape as attribute value, multiline</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<html>
<input
type="text"
value="${fn:escapeXml(expression)}"
name="toto"
/>
</html>
]]></code>
<source-type>jsp</source-type>
</test-code>
<test-code>
<description>fn:escape and c:out mix</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
${fn:escapeXml( expression )}
<html>
${fn:escapeXml(expression)}
<input
type="text"
value="${fn:escapeXml(expression)}"
name="toto"
/>
<c:out value="${fn:escapeXml(expression)}" />
</html>
]]></code>
<source-type>jsp</source-type>
</test-code>
</test-data>