diff --git a/pmd-visualforce/etc/grammar/VfParser.jjt b/pmd-visualforce/etc/grammar/VfParser.jjt index a13b913e0b..49c7dd7988 100644 --- a/pmd-visualforce/etc/grammar/VfParser.jjt +++ b/pmd-visualforce/etc/grammar/VfParser.jjt @@ -145,7 +145,7 @@ PARSER_END(VfParser) | =" > | | " > - | + | | | > | )+ > @@ -294,7 +294,7 @@ void Bom() #void : /** * Everything between a start-tag and the corresponding end-tag of an element (if an end tag exists). */ -void Content() #void : +void Content() : {} { ( ElOrText() | ContentElement() )* diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/ASTContent.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/ASTContent.java new file mode 100644 index 0000000000..2aa397b0ca --- /dev/null +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/ASTContent.java @@ -0,0 +1,21 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.vf.ast; + +public class ASTContent extends AbstractVFNode { + public ASTContent(int id) { + super(id); + } + + public ASTContent(VfParser p, int id) { + super(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(VfParserVisitor visitor, Object data) { + + return visitor.visit(this, data); + } +} diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/VfParserVisitorAdapter.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/VfParserVisitorAdapter.java index fb23bbffc5..d71d2744ef 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/VfParserVisitorAdapter.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/VfParserVisitorAdapter.java @@ -83,10 +83,14 @@ public class VfParserVisitorAdapter implements VfParserVisitor { public Object visit(ASTArguments node, Object data) { return visit((VfNode) node, data); } - @Override public Object visit(ASTDotExpression node, Object data) { return visit((VfNode) node, data); } + + @Override + public Object visit(ASTContent node, Object data) { + return visit((VfNode) node, data); + } } diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/rule/AbstractVfRule.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/rule/AbstractVfRule.java index a592072299..c446626e12 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/rule/AbstractVfRule.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/rule/AbstractVfRule.java @@ -18,6 +18,7 @@ import net.sourceforge.pmd.lang.vf.ast.ASTAttributeValue; import net.sourceforge.pmd.lang.vf.ast.ASTCData; import net.sourceforge.pmd.lang.vf.ast.ASTCommentTag; import net.sourceforge.pmd.lang.vf.ast.ASTCompilationUnit; +import net.sourceforge.pmd.lang.vf.ast.ASTContent; import net.sourceforge.pmd.lang.vf.ast.ASTDeclaration; import net.sourceforge.pmd.lang.vf.ast.ASTDoctypeDeclaration; import net.sourceforge.pmd.lang.vf.ast.ASTDoctypeExternalId; @@ -71,7 +72,6 @@ public abstract class AbstractVfRule extends AbstractRule implements VfParserVis public Object visit(ASTAttributeValue node, Object data) { return visit((VfNode) node, data); } - public Object visit(ASTElExpression node, Object data) { return visit((VfNode) node, data); @@ -132,4 +132,9 @@ public abstract class AbstractVfRule extends AbstractRule implements VfParserVis public Object visit(ASTDotExpression node, Object data) { return visit((VfNode) node, data); } + + public Object visit(ASTContent node, Object data) { + return visit((VfNode) node, data); + } + } diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/rule/security/VfUnescapeElRule.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/rule/security/VfUnescapeElRule.java index 64d8d14b30..217ecb8db9 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/rule/security/VfUnescapeElRule.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/rule/security/VfUnescapeElRule.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.regex.Pattern; import net.sourceforge.pmd.lang.vf.ast.ASTAttribute; +import net.sourceforge.pmd.lang.vf.ast.ASTContent; import net.sourceforge.pmd.lang.vf.ast.ASTElExpression; import net.sourceforge.pmd.lang.vf.ast.ASTElement; import net.sourceforge.pmd.lang.vf.ast.ASTIdentifier; @@ -136,14 +137,20 @@ public class VfUnescapeElRule extends AbstractVfRule { } private boolean hasAnyEL(final ASTElement node) { - final List innerElements = node.findChildrenOfType(ASTElement.class); - for (ASTElement element : innerElements) { - if (element.getName().equalsIgnoreCase(APEX_PARAM)) { - final List innerAttributes = element.findChildrenOfType(ASTAttribute.class); - for (ASTAttribute attrib : innerAttributes) { - final ASTElExpression elInVal = attrib.getFirstDescendantOfType(ASTElExpression.class); - if (elInVal != null) { - return true; + final ASTContent content = node.getFirstChildOfType(ASTContent.class); + if (content != null) { + List innerElements = content.findChildrenOfType(ASTElement.class); + for (ASTElement element : innerElements) { + if (element.getName().equalsIgnoreCase(APEX_PARAM)) { + final List innerAttributes = element.findChildrenOfType(ASTAttribute.class); + for (ASTAttribute attrib : innerAttributes) { + final List elsInVal = attrib.findDescendantsOfType(ASTElExpression.class); + for (final ASTElExpression el : elsInVal) { + if (doesElContainAnyUnescapedIdentifiers(el)) { + return true; + } + + } } } } diff --git a/pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/vf/rule/security/xml/VfUnescapeEl.xml b/pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/vf/rule/security/xml/VfUnescapeEl.xml index 9d9771df85..eb24e08cfe 100644 --- a/pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/vf/rule/security/xml/VfUnescapeEl.xml +++ b/pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/vf/rule/security/xml/VfUnescapeEl.xml @@ -1,6 +1,5 @@ - vf - + @@ -81,6 +80,23 @@ XSS via EL via param binding +]]> + vf + + + + + + 0 + + + + + + ]]> vf @@ -118,7 +134,7 @@ No XSS via EL via param binding ]]> vf - + vf - - +