11/**
22 * @name External Entity Expansion
33 * @description
4- * @kind problem
4+ * @kind path- problem
55 * @id cpp/external-entity-expansion
66 * @problem.severity warning
77 * @tags security
88 * external/cwe/cwe-611
99 */
1010
1111import cpp
12+ import semmle.code.cpp.ir.dataflow.DataFlow
13+ import DataFlow:: PathGraph
14+ import semmle.code.cpp.ir.IR
1215
1316class XercesDOMParser extends Class {
1417 XercesDOMParser ( ) { this .hasName ( "XercesDOMParser" ) }
1518}
1619
1720class AbstractDOMParser extends Class {
18- AbstractDOMParser ( ) { this .hasName ( "AbstractDOMParser" ) }
21+ AbstractDOMParser ( ) { this .hasName ( "AbstractDOMParser" ) }
22+ }
23+
24+ class DisableDefaultEntityResolution extends Function {
25+ DisableDefaultEntityResolution ( ) {
26+ this .hasQualifiedName ( _, "XercesDOMParser" , "disableDefaultEntityResolution" )
27+ }
28+ }
29+
30+ class SetCreateEntityReferenceNodes extends Function {
31+ SetCreateEntityReferenceNodes ( ) {
32+ this .hasQualifiedName ( _, "XercesDOMParser" , "setCreateEntityReferenceNodes" )
33+ }
34+ }
35+
36+ class CreateLSParser extends Function {
37+ CreateLSParser ( ) {
38+ this .hasName ( "createLSParser" )
39+ }
40+ }
41+
42+ class XercesXXEConfiguration extends DataFlow:: Configuration {
43+ XercesXXEConfiguration ( ) { this = "XercesXXEConfiguration" }
44+
45+ override predicate isSource ( DataFlow:: Node node ) {
46+ exists ( CallInstruction call |
47+ node .asInstruction ( ) .( WriteSideEffectInstruction ) .getDestinationAddress ( ) = call .getThisArgument ( ) and
48+ call .getStaticCallTarget ( ) .( Constructor ) .getDeclaringType ( ) instanceof XercesDOMParser
49+ )
50+ or
51+ exists ( Call call |
52+ call .getTarget ( ) instanceof CreateLSParser and
53+ call = node .asExpr ( )
54+ )
55+ }
56+
57+ override predicate isSink ( DataFlow:: Node node ) {
58+ exists ( Call call , ReadSideEffectInstruction instr |
59+ call .getTarget ( ) .hasName ( "parse" ) and
60+ call .getQualifier ( ) = instr .getArgumentDef ( ) .getUnconvertedResultExpression ( ) and
61+ node .asOperand ( ) = instr .getSideEffectOperand ( )
62+ )
63+ }
64+
65+ override predicate isBarrier ( DataFlow:: Node node ) {
66+ exists ( Call first , Call second |
67+ (
68+ first .getTarget ( ) instanceof DisableDefaultEntityResolution and
69+ second .getTarget ( ) instanceof SetCreateEntityReferenceNodes
70+ or
71+ first .getTarget ( ) instanceof SetCreateEntityReferenceNodes and
72+ second .getTarget ( ) instanceof DisableDefaultEntityResolution
73+ ) and
74+ DataFlow:: localExprFlow ( first .getQualifier ( ) , second .getQualifier ( ) ) and
75+ second .getQualifier ( ) = node .asDefiningArgument ( )
76+ )
77+ or
78+ exists ( Call setSecurityManager |
79+ // todo: security manager setup
80+ setSecurityManager .getQualifier ( ) = node .asDefiningArgument ( )
81+ )
82+ }
1983}
2084
2185/*
22- parser created
23- needs doSchema set?
24- needs validation set?
25- needs namespaces?
26- (
27- no security manager
28- OR
29- no
30- */
86+ * parser created
87+ * needs doSchema set?
88+ * needs validation set?
89+ * needs namespaces?
90+ * (
91+ * no security manager
92+ * OR
93+ * no
94+ */
95+
96+ from DataFlow:: PathNode source , DataFlow:: PathNode sink , XercesXXEConfiguration conf
97+ where conf .hasFlowPath ( source , sink )
98+ select sink , source , sink ,
99+ "This $@ is not configured to prevent an External Entity Expansion attack." , source , "XML parser"
0 commit comments