Skip to content

Commit 300ffdb

Browse files
committed
filter documentbuilder more aggressively so it doesnt accidentally recgonie xmlparser calls
1 parent 0ecf40e commit 300ffdb

File tree

3 files changed

+45
-9
lines changed

3 files changed

+45
-9
lines changed

framework/codemodder-base/src/main/java/io/codemodder/remediation/NodePositionMatcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/** Provides methods for matching nodes to given coordinates. */
66
public interface NodePositionMatcher {
77

8-
static final NodePositionMatcher DEFAULT = new DefaultNodePositionMatcher();
8+
NodePositionMatcher DEFAULT = new DefaultNodePositionMatcher();
99

1010
/**
1111
* Matches a node with a range against a line

framework/codemodder-base/src/main/java/io/codemodder/remediation/xxe/DocumentBuilderFactoryAtParseFixStrategy.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,20 @@ public boolean match(final Node node) {
101101
.map(n -> n instanceof MethodCallExpr ? (MethodCallExpr) n : null)
102102
.filter(m -> "parse".equals(m.getNameAsString()))
103103
.filter(m -> m.getScope().filter(Expression::isNameExpr).isPresent())
104+
.filter(
105+
m -> {
106+
Optional<Node> sourceRef =
107+
ASTs.findNonCallableSimpleNameSource(m.getScope().get().asNameExpr().getName());
108+
if (sourceRef.isEmpty()) {
109+
return false;
110+
}
111+
Node source = sourceRef.get();
112+
if (source instanceof NodeWithType<?, ?>) {
113+
return Set.of("DocumentBuilder", "javax.xml.parsers.DocumentBuilder")
114+
.contains(((NodeWithType<?, ?>) source).getTypeAsString());
115+
}
116+
return false;
117+
})
104118
.isPresent();
105119
}
106120
}

framework/codemodder-base/src/test/java/io/codemodder/remediation/xxe/XMLReaderAtParseFixerTest.java

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,38 @@
99
import io.codemodder.remediation.SearcherStrategyRemediator;
1010
import java.util.List;
1111
import java.util.Optional;
12-
import org.junit.jupiter.api.Test;
12+
import java.util.stream.Stream;
13+
import org.junit.jupiter.params.ParameterizedTest;
14+
import org.junit.jupiter.params.provider.Arguments;
15+
import org.junit.jupiter.params.provider.MethodSource;
1316

1417
final class XMLReaderAtParseFixerTest {
1518

16-
@Test
17-
void it_fixes_xmlreaders_at_parse_call() {
19+
private static Stream<Arguments> provideRemediators() {
20+
return Stream.of(
21+
Arguments.of(
22+
new SearcherStrategyRemediator.Builder<>()
23+
.withMatchAndFixStrategy(new XMLReaderAtParseFixStrategy())
24+
.build()),
25+
26+
// now try with the previously conflicting parser strategy inline as well
27+
Arguments.of(
28+
new SearcherStrategyRemediator.Builder<>()
29+
.withMatchAndFixStrategy(new DocumentBuilderFactoryAtParseFixStrategy())
30+
.withMatchAndFixStrategy(new XMLReaderAtParseFixStrategy())
31+
.build()),
32+
33+
// reverse the order to confirm no ordering issues
34+
Arguments.of(
35+
new SearcherStrategyRemediator.Builder<>()
36+
.withMatchAndFixStrategy(new XMLReaderAtParseFixStrategy())
37+
.withMatchAndFixStrategy(new DocumentBuilderFactoryAtParseFixStrategy())
38+
.build()));
39+
}
40+
41+
@MethodSource("provideRemediators")
42+
@ParameterizedTest
43+
void it_fixes_xmlreaders_at_parse_call(final SearcherStrategyRemediator remediator) {
1844
String vulnerableCode =
1945
"""
2046
public class MyCode {
@@ -43,12 +69,8 @@ public void foo() {
4369
CompilationUnit cu = StaticJavaParser.parse(vulnerableCode);
4470
LexicalPreservingPrinter.setup(cu);
4571

46-
var searcherRemediator =
47-
new SearcherStrategyRemediator.Builder<>()
48-
.withMatchAndFixStrategy(new XMLReaderAtParseFixStrategy())
49-
.build();
5072
var result =
51-
searcherRemediator.remediateAll(
73+
remediator.remediateAll(
5274
cu,
5375
"path",
5476
new DetectorRule("", "", ""),

0 commit comments

Comments
 (0)