Skip to content

Commit

Permalink
Refactors SQL Remediator and Codemods & HQL Transformation Bugfix (#456)
Browse files Browse the repository at this point in the history
Refactors SQL injection codemods to use the new remediator API and fixes
a HQL transformation bug.
  • Loading branch information
andrecsilva authored Oct 15, 2024
1 parent 4b58536 commit 364702d
Show file tree
Hide file tree
Showing 12 changed files with 199 additions and 252 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
import io.codemodder.providers.defectdojo.DefectDojoScan;
import io.codemodder.providers.defectdojo.Finding;
import io.codemodder.providers.defectdojo.RuleFindings;
import io.codemodder.remediation.sqlinjection.JavaParserSQLInjectionRemediatorStrategy;
import io.codemodder.remediation.Remediator;
import io.codemodder.remediation.sqlinjection.SQLInjectionRemediator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import javax.inject.Inject;

/**
Expand All @@ -25,15 +27,15 @@ public final class DefectDojoSqlInjectionCodemod extends JavaParserChanger
implements FixOnlyCodeChanger {

private final RuleFindings findings;
private final JavaParserSQLInjectionRemediatorStrategy remediatorStrategy;
private final Remediator<Finding> remediatorStrategy;

@Inject
public DefectDojoSqlInjectionCodemod(
@DefectDojoScan(ruleId = "java.lang.security.audit.sqli.jdbc-sqli.jdbc-sqli")
RuleFindings findings) {
super(CodemodReporterStrategy.fromClasspath(SQLParameterizerCodemod.class));
this.findings = Objects.requireNonNull(findings);
this.remediatorStrategy = JavaParserSQLInjectionRemediatorStrategy.DEFAULT;
this.remediatorStrategy = new SQLInjectionRemediator<>();
}

@Override
Expand All @@ -60,6 +62,7 @@ public CodemodFileScanningResult visit(
findingsForThisPath,
finding -> String.valueOf(finding.getId()),
Finding::getLine,
f -> null);
f -> Optional.empty(),
f -> Optional.empty());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public CodemodFileScanningResult visit(
return CodemodFileScanningResult.withOnlyChanges(changes);
}

private static final String queryParameterNamePrefix = ":parameter";
private static final String queryParameterNamePrefix = "parameter";

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

// fix end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
import io.codemodder.providers.sonar.RuleHotspot;
import io.codemodder.providers.sonar.SonarRemediatingJavaParserChanger;
import io.codemodder.remediation.GenericRemediationMetadata;
import io.codemodder.remediation.sqlinjection.JavaParserSQLInjectionRemediatorStrategy;
import io.codemodder.remediation.Remediator;
import io.codemodder.remediation.sqlinjection.SQLInjectionRemediator;
import io.codemodder.sonar.model.Hotspot;
import io.codemodder.sonar.model.SonarFinding;
import io.codemodder.sonar.model.TextRange;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import javax.inject.Inject;

@Codemod(
Expand All @@ -21,15 +24,15 @@
executionPriority = CodemodExecutionPriority.HIGH)
public final class SonarSQLInjectionCodemod extends SonarRemediatingJavaParserChanger {

private final JavaParserSQLInjectionRemediatorStrategy remediationStrategy;
private final Remediator<Hotspot> remediationStrategy;
private final RuleHotspot hotspots;

@Inject
public SonarSQLInjectionCodemod(
@ProvidedSonarScan(ruleId = "java:S2077") final RuleHotspot hotspots) {
super(GenericRemediationMetadata.SQL_INJECTION.reporter(), hotspots);
this.hotspots = Objects.requireNonNull(hotspots);
this.remediationStrategy = JavaParserSQLInjectionRemediatorStrategy.DEFAULT;
this.remediationStrategy = new SQLInjectionRemediator<>();
}

@Override
Expand All @@ -51,6 +54,7 @@ public CodemodFileScanningResult visit(
hotspotsForFile,
SonarFinding::getKey,
i -> i.getTextRange() != null ? i.getTextRange().getStartLine() : i.getLine(),
i -> i.getTextRange() != null ? i.getTextRange().getEndLine() : null);
i -> Optional.ofNullable(i.getTextRange()).map(TextRange::getEndLine),
i -> Optional.ofNullable(i.getTextRange()).map(tr -> tr.getStartOffset() + 1));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.codemodder.codemods.semgrep;

import com.contrastsecurity.sarif.Result;
import com.github.javaparser.ast.CompilationUnit;
import io.codemodder.Codemod;
import io.codemodder.CodemodExecutionPriority;
Expand All @@ -12,7 +13,9 @@
import io.codemodder.codetf.DetectorRule;
import io.codemodder.providers.sarif.semgrep.ProvidedSemgrepScan;
import io.codemodder.remediation.GenericRemediationMetadata;
import io.codemodder.remediation.sqlinjection.JavaParserSQLInjectionRemediatorStrategy;
import io.codemodder.remediation.Remediator;
import io.codemodder.remediation.sqlinjection.SQLInjectionRemediator;
import java.util.Optional;
import javax.inject.Inject;

/**
Expand All @@ -26,14 +29,14 @@
importance = Importance.HIGH)
public final class SemgrepSQLInjectionCodemod extends SemgrepJavaParserChanger {

private final JavaParserSQLInjectionRemediatorStrategy remediator;
private final Remediator<Result> remediator;

@Inject
public SemgrepSQLInjectionCodemod(
@ProvidedSemgrepScan(ruleId = "java.lang.security.audit.sqli.jdbc-sqli.jdbc-sqli")
final RuleSarif sarif) {
super(GenericRemediationMetadata.SQL_INJECTION.reporter(), sarif);
this.remediator = JavaParserSQLInjectionRemediatorStrategy.DEFAULT;
this.remediator = new SQLInjectionRemediator<>();
}

@Override
Expand All @@ -54,6 +57,11 @@ public CodemodFileScanningResult visit(
ruleSarif.getResultsByLocationPath(context.path()),
SarifFindingKeyUtil::buildFindingId,
r -> r.getLocations().get(0).getPhysicalLocation().getRegion().getStartLine(),
r -> r.getLocations().get(0).getPhysicalLocation().getRegion().getEndLine());
r ->
Optional.ofNullable(
r.getLocations().get(0).getPhysicalLocation().getRegion().getEndLine()),
r ->
Optional.ofNullable(
r.getLocations().get(0).getPhysicalLocation().getRegion().getStartColumn()));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.codemodder.codemods.semgrep;

import com.contrastsecurity.sarif.Result;
import com.github.javaparser.ast.CompilationUnit;
import io.codemodder.Codemod;
import io.codemodder.CodemodExecutionPriority;
Expand All @@ -12,7 +13,9 @@
import io.codemodder.codetf.DetectorRule;
import io.codemodder.providers.sarif.semgrep.ProvidedSemgrepScan;
import io.codemodder.remediation.GenericRemediationMetadata;
import io.codemodder.remediation.sqlinjection.JavaParserSQLInjectionRemediatorStrategy;
import io.codemodder.remediation.Remediator;
import io.codemodder.remediation.sqlinjection.SQLInjectionRemediator;
import java.util.Optional;
import javax.inject.Inject;

/**
Expand All @@ -26,15 +29,15 @@
importance = Importance.HIGH)
public final class SemgrepSQLInjectionFormattedSqlStringCodemod extends SemgrepJavaParserChanger {

private final JavaParserSQLInjectionRemediatorStrategy remediator;
private final Remediator<Result> remediator;

@Inject
public SemgrepSQLInjectionFormattedSqlStringCodemod(
@ProvidedSemgrepScan(
ruleId = "java.lang.security.audit.formatted-sql-string.formatted-sql-string")
final RuleSarif sarif) {
super(GenericRemediationMetadata.SQL_INJECTION.reporter(), sarif);
this.remediator = JavaParserSQLInjectionRemediatorStrategy.DEFAULT;
this.remediator = new SQLInjectionRemediator<>();
}

@Override
Expand All @@ -55,6 +58,11 @@ public CodemodFileScanningResult visit(
ruleSarif.getResultsByLocationPath(context.path()),
SarifFindingKeyUtil::buildFindingId,
r -> r.getLocations().get(0).getPhysicalLocation().getRegion().getStartLine(),
r -> r.getLocations().get(0).getPhysicalLocation().getRegion().getEndLine());
r ->
Optional.ofNullable(
r.getLocations().get(0).getPhysicalLocation().getRegion().getEndLine()),
r ->
Optional.ofNullable(
r.getLocations().get(0).getPhysicalLocation().getRegion().getStartColumn()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ public final class Test {
private Session session;

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

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

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

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

This file was deleted.

Loading

0 comments on commit 364702d

Please sign in to comment.