Skip to content

Commit 364702d

Browse files
authored
Refactors SQL Remediator and Codemods & HQL Transformation Bugfix (#456)
Refactors SQL injection codemods to use the new remediator API and fixes a HQL transformation bug.
1 parent 4b58536 commit 364702d

File tree

12 files changed

+199
-252
lines changed

12 files changed

+199
-252
lines changed

core-codemods/src/main/java/io/codemodder/codemods/DefectDojoSqlInjectionCodemod.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
import io.codemodder.providers.defectdojo.DefectDojoScan;
88
import io.codemodder.providers.defectdojo.Finding;
99
import io.codemodder.providers.defectdojo.RuleFindings;
10-
import io.codemodder.remediation.sqlinjection.JavaParserSQLInjectionRemediatorStrategy;
10+
import io.codemodder.remediation.Remediator;
11+
import io.codemodder.remediation.sqlinjection.SQLInjectionRemediator;
1112
import java.util.List;
1213
import java.util.Objects;
14+
import java.util.Optional;
1315
import javax.inject.Inject;
1416

1517
/**
@@ -25,15 +27,15 @@ public final class DefectDojoSqlInjectionCodemod extends JavaParserChanger
2527
implements FixOnlyCodeChanger {
2628

2729
private final RuleFindings findings;
28-
private final JavaParserSQLInjectionRemediatorStrategy remediatorStrategy;
30+
private final Remediator<Finding> remediatorStrategy;
2931

3032
@Inject
3133
public DefectDojoSqlInjectionCodemod(
3234
@DefectDojoScan(ruleId = "java.lang.security.audit.sqli.jdbc-sqli.jdbc-sqli")
3335
RuleFindings findings) {
3436
super(CodemodReporterStrategy.fromClasspath(SQLParameterizerCodemod.class));
3537
this.findings = Objects.requireNonNull(findings);
36-
this.remediatorStrategy = JavaParserSQLInjectionRemediatorStrategy.DEFAULT;
38+
this.remediatorStrategy = new SQLInjectionRemediator<>();
3739
}
3840

3941
@Override
@@ -60,6 +62,7 @@ public CodemodFileScanningResult visit(
6062
findingsForThisPath,
6163
finding -> String.valueOf(finding.getId()),
6264
Finding::getLine,
63-
f -> null);
65+
f -> Optional.empty(),
66+
f -> Optional.empty());
6467
}
6568
}

core-codemods/src/main/java/io/codemodder/codemods/HQLParameterizationCodemod.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public CodemodFileScanningResult visit(
5656
return CodemodFileScanningResult.withOnlyChanges(changes);
5757
}
5858

59-
private static final String queryParameterNamePrefix = ":parameter";
59+
private static final String queryParameterNamePrefix = "parameter";
6060

6161
private boolean isQueryCreation(final MethodCallExpr methodCallExpr) {
6262
final Predicate<MethodCallExpr> isQueryCall =
@@ -86,7 +86,8 @@ private List<Expression> fixInjections(
8686
final var builder = new StringBuilder(startString);
8787
final int lastQuoteIndex = startString.lastIndexOf('\'') + 1;
8888
final var prepend = startString.substring(lastQuoteIndex);
89-
builder.replace(lastQuoteIndex - 1, startString.length(), queryParameterNamePrefix + count);
89+
builder.replace(
90+
lastQuoteIndex - 1, startString.length(), ":" + queryParameterNamePrefix + count);
9091
start.asStringLiteralExpr().setValue(builder.toString());
9192

9293
// fix end

core-codemods/src/main/java/io/codemodder/codemods/SonarSQLInjectionCodemod.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@
77
import io.codemodder.providers.sonar.RuleHotspot;
88
import io.codemodder.providers.sonar.SonarRemediatingJavaParserChanger;
99
import io.codemodder.remediation.GenericRemediationMetadata;
10-
import io.codemodder.remediation.sqlinjection.JavaParserSQLInjectionRemediatorStrategy;
10+
import io.codemodder.remediation.Remediator;
11+
import io.codemodder.remediation.sqlinjection.SQLInjectionRemediator;
1112
import io.codemodder.sonar.model.Hotspot;
1213
import io.codemodder.sonar.model.SonarFinding;
14+
import io.codemodder.sonar.model.TextRange;
1315
import java.util.List;
1416
import java.util.Objects;
17+
import java.util.Optional;
1518
import javax.inject.Inject;
1619

1720
@Codemod(
@@ -21,15 +24,15 @@
2124
executionPriority = CodemodExecutionPriority.HIGH)
2225
public final class SonarSQLInjectionCodemod extends SonarRemediatingJavaParserChanger {
2326

24-
private final JavaParserSQLInjectionRemediatorStrategy remediationStrategy;
27+
private final Remediator<Hotspot> remediationStrategy;
2528
private final RuleHotspot hotspots;
2629

2730
@Inject
2831
public SonarSQLInjectionCodemod(
2932
@ProvidedSonarScan(ruleId = "java:S2077") final RuleHotspot hotspots) {
3033
super(GenericRemediationMetadata.SQL_INJECTION.reporter(), hotspots);
3134
this.hotspots = Objects.requireNonNull(hotspots);
32-
this.remediationStrategy = JavaParserSQLInjectionRemediatorStrategy.DEFAULT;
35+
this.remediationStrategy = new SQLInjectionRemediator<>();
3336
}
3437

3538
@Override
@@ -51,6 +54,7 @@ public CodemodFileScanningResult visit(
5154
hotspotsForFile,
5255
SonarFinding::getKey,
5356
i -> i.getTextRange() != null ? i.getTextRange().getStartLine() : i.getLine(),
54-
i -> i.getTextRange() != null ? i.getTextRange().getEndLine() : null);
57+
i -> Optional.ofNullable(i.getTextRange()).map(TextRange::getEndLine),
58+
i -> Optional.ofNullable(i.getTextRange()).map(tr -> tr.getStartOffset() + 1));
5559
}
5660
}

core-codemods/src/main/java/io/codemodder/codemods/semgrep/SemgrepSQLInjectionCodemod.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.codemodder.codemods.semgrep;
22

3+
import com.contrastsecurity.sarif.Result;
34
import com.github.javaparser.ast.CompilationUnit;
45
import io.codemodder.Codemod;
56
import io.codemodder.CodemodExecutionPriority;
@@ -12,7 +13,9 @@
1213
import io.codemodder.codetf.DetectorRule;
1314
import io.codemodder.providers.sarif.semgrep.ProvidedSemgrepScan;
1415
import io.codemodder.remediation.GenericRemediationMetadata;
15-
import io.codemodder.remediation.sqlinjection.JavaParserSQLInjectionRemediatorStrategy;
16+
import io.codemodder.remediation.Remediator;
17+
import io.codemodder.remediation.sqlinjection.SQLInjectionRemediator;
18+
import java.util.Optional;
1619
import javax.inject.Inject;
1720

1821
/**
@@ -26,14 +29,14 @@
2629
importance = Importance.HIGH)
2730
public final class SemgrepSQLInjectionCodemod extends SemgrepJavaParserChanger {
2831

29-
private final JavaParserSQLInjectionRemediatorStrategy remediator;
32+
private final Remediator<Result> remediator;
3033

3134
@Inject
3235
public SemgrepSQLInjectionCodemod(
3336
@ProvidedSemgrepScan(ruleId = "java.lang.security.audit.sqli.jdbc-sqli.jdbc-sqli")
3437
final RuleSarif sarif) {
3538
super(GenericRemediationMetadata.SQL_INJECTION.reporter(), sarif);
36-
this.remediator = JavaParserSQLInjectionRemediatorStrategy.DEFAULT;
39+
this.remediator = new SQLInjectionRemediator<>();
3740
}
3841

3942
@Override
@@ -54,6 +57,11 @@ public CodemodFileScanningResult visit(
5457
ruleSarif.getResultsByLocationPath(context.path()),
5558
SarifFindingKeyUtil::buildFindingId,
5659
r -> r.getLocations().get(0).getPhysicalLocation().getRegion().getStartLine(),
57-
r -> r.getLocations().get(0).getPhysicalLocation().getRegion().getEndLine());
60+
r ->
61+
Optional.ofNullable(
62+
r.getLocations().get(0).getPhysicalLocation().getRegion().getEndLine()),
63+
r ->
64+
Optional.ofNullable(
65+
r.getLocations().get(0).getPhysicalLocation().getRegion().getStartColumn()));
5866
}
5967
}

core-codemods/src/main/java/io/codemodder/codemods/semgrep/SemgrepSQLInjectionFormattedSqlStringCodemod.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.codemodder.codemods.semgrep;
22

3+
import com.contrastsecurity.sarif.Result;
34
import com.github.javaparser.ast.CompilationUnit;
45
import io.codemodder.Codemod;
56
import io.codemodder.CodemodExecutionPriority;
@@ -12,7 +13,9 @@
1213
import io.codemodder.codetf.DetectorRule;
1314
import io.codemodder.providers.sarif.semgrep.ProvidedSemgrepScan;
1415
import io.codemodder.remediation.GenericRemediationMetadata;
15-
import io.codemodder.remediation.sqlinjection.JavaParserSQLInjectionRemediatorStrategy;
16+
import io.codemodder.remediation.Remediator;
17+
import io.codemodder.remediation.sqlinjection.SQLInjectionRemediator;
18+
import java.util.Optional;
1619
import javax.inject.Inject;
1720

1821
/**
@@ -26,15 +29,15 @@
2629
importance = Importance.HIGH)
2730
public final class SemgrepSQLInjectionFormattedSqlStringCodemod extends SemgrepJavaParserChanger {
2831

29-
private final JavaParserSQLInjectionRemediatorStrategy remediator;
32+
private final Remediator<Result> remediator;
3033

3134
@Inject
3235
public SemgrepSQLInjectionFormattedSqlStringCodemod(
3336
@ProvidedSemgrepScan(
3437
ruleId = "java.lang.security.audit.formatted-sql-string.formatted-sql-string")
3538
final RuleSarif sarif) {
3639
super(GenericRemediationMetadata.SQL_INJECTION.reporter(), sarif);
37-
this.remediator = JavaParserSQLInjectionRemediatorStrategy.DEFAULT;
40+
this.remediator = new SQLInjectionRemediator<>();
3841
}
3942

4043
@Override
@@ -55,6 +58,11 @@ public CodemodFileScanningResult visit(
5558
ruleSarif.getResultsByLocationPath(context.path()),
5659
SarifFindingKeyUtil::buildFindingId,
5760
r -> r.getLocations().get(0).getPhysicalLocation().getRegion().getStartLine(),
58-
r -> r.getLocations().get(0).getPhysicalLocation().getRegion().getEndLine());
61+
r ->
62+
Optional.ofNullable(
63+
r.getLocations().get(0).getPhysicalLocation().getRegion().getEndLine()),
64+
r ->
65+
Optional.ofNullable(
66+
r.getLocations().get(0).getPhysicalLocation().getRegion().getStartColumn()));
5967
}
6068
}

core-codemods/src/test/resources/hql-parameterizer/Test.java.after

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,22 @@ public final class Test {
88
private Session session;
99

1010
void direct(String tainted) {
11-
Query<User> hqlQuery = session.createQuery("select p from Person p where p.name like :parameter0").setParameter(":parameter0", tainted);
11+
Query<User> hqlQuery = session.createQuery("select p from Person p where p.name like :parameter0").setParameter("parameter0", tainted);
1212
}
1313

1414
void indirect(String tainted) {
1515
String query = "select p from Person p where p.name like :parameter0";
16-
Query<User> hqlQuery = session.createQuery(query).setParameter(":parameter0", tainted);
16+
Query<User> hqlQuery = session.createQuery(query).setParameter("parameter0", tainted);
1717
}
1818

1919
void indirectMultiple(String tainted, String tainted2) {
2020
String query = "select p from Person p where p.name like :parameter0" + " and p.surname like :parameter1";
21-
Query<User> hqlQuery = session.createQuery(query).setParameter(":parameter0", tainted).setParameter(":parameter1", tainted2);
21+
Query<User> hqlQuery = session.createQuery(query).setParameter("parameter0", tainted).setParameter("parameter1", tainted2);
2222
}
2323

2424
void indirectMultipeString(String tainted, String tainted2) {
2525
String second = " and p.surname like :parameter1";
2626
String first = "select p from Person p where p.name like :parameter0" + second;
27-
Query<User> hqlQuery = session.createQuery(first).setParameter(":parameter0", tainted).setParameter(":parameter1", tainted2);
27+
Query<User> hqlQuery = session.createQuery(first).setParameter("parameter0", tainted).setParameter("parameter1", tainted2);
2828
}
2929
}

framework/codemodder-base/src/main/java/io/codemodder/remediation/sqlinjection/DefaultJavaParserSQLInjectionRemediatorStrategy.java

Lines changed: 0 additions & 162 deletions
This file was deleted.

0 commit comments

Comments
 (0)