Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds new transformation for SQL injection/parameterization codemods #463

Merged
merged 8 commits into from
Nov 8, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ void foo() {
break;
default:
break;
case 0:
break;
}
case 0:
break;
}
}
}
""";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,21 @@

import io.codemodder.testutils.CodemodTestMixin;
import io.codemodder.testutils.Metadata;
import org.junit.jupiter.api.Nested;

@Metadata(
codemodType = SQLParameterizerCodemod.class,
testResourceDir = "sql-parameterizer",
dependencies = {})
final class SQLParameterizerCodemodTest implements CodemodTestMixin {}
final class SQLParameterizerCodemodTest {

@Nested
@Metadata(
codemodType = SQLParameterizerCodemod.class,
testResourceDir = "sql-parameterizer/defaultTransformation",
dependencies = {})
class DefaultTransformationTest implements CodemodTestMixin {}

@Nested
@Metadata(
codemodType = SQLParameterizerCodemod.class,
testResourceDir = "sql-parameterizer/hijackTransformation",
dependencies = {})
class HijackTransformationTest implements CodemodTestMixin {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public class SqlInjectionChallenge extends AssignmentEndpoint {
"select userid from sql_challenge_users where userid = ?";
PreparedStatement statement = connection.prepareStatement(checkUserQuery);
statement.setString(1, username_reg);

ResultSet resultSet = statement.execute();
if (resultSet.next()) {
if (username_reg.contains("tom'")) {
Expand All @@ -84,7 +85,6 @@ public class SqlInjectionChallenge extends AssignmentEndpoint {
preparedStatement.execute();
attackResult = success(this).feedback("user.created").feedbackArgs(username_reg).build();
}

} catch (SQLException e) {
attackResult = failed(this).output("Something went wrong").build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,10 @@ public class SqlInjectionLesson8 extends AssignmentEndpoint {
try {
PreparedStatement statement =
connection.prepareStatement(
query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
log(connection, query);
statement.setString(1, name);

statement.setString(2, auth_tan);
ResultSet results = statement.execute();
if (results.getStatement() != null) {
Expand All @@ -98,7 +99,6 @@ query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDAT
} else {
return failed(this).build();
}

} catch (SQLException e) {
return failed(this)
.output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>")
Expand Down Expand Up @@ -156,7 +156,7 @@ query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDAT
statement.setString(1, sdf.format(cal.getTime()));
statement.setString(2, action);
statement.execute();
} catch (SQLException e) {
} catch (SQLException e) {
System.err.println(e.getMessage());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public final class Test {
JexlExpression expression = jexl.createExpression(input);
JexlContext context = new MapContext();
expression.evaluate(context);

}
}

Expand All @@ -42,7 +41,6 @@ public final class Test {
sandbox.block(cls);
}
new JexlBuilder().sandbox(sandbox).create().createExpression(input).evaluate(context);

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ final class Test {
case "bar":
System.out.println("bar");
break;
default:
System.out.println("default"); }
default:
System.out.println("default");}
System.out.println("bar");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ public class SqlInjectionLesson5a extends AssignmentEndpoint {
"SELECT * FROM user_data WHERE first_name = 'John' and last_name = ?";
try (PreparedStatement statement =
connection.prepareStatement(
query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE)) {
query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE)) {
statement.setString(1, accountName);

ResultSet results = statement.execute();
if ((results != null) && (results.first())) {
ResultSetMetaData resultsMetaData = results.getMetaData();
Expand All @@ -90,7 +91,6 @@ query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATAB
.output("Your query was: " + query)
.build();
}

} catch (SQLException sqle) {
return failed(this).output(sqle.getMessage() + "<br> Your query was: " + query).build();
}
Expand Down Expand Up @@ -135,4 +135,4 @@ query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATAB
t.append("</p>");
return (t.toString());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,10 @@ public class SqlInjectionLesson8 extends AssignmentEndpoint {
try {
PreparedStatement statement =
connection.prepareStatement(
query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
log(connection, query);
statement.setString(1, name);

statement.setString(2, auth_tan);
ResultSet results = statement.execute();
if (results.getStatement() != null) {
Expand All @@ -98,7 +99,6 @@ query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDAT
} else {
return failed(this).build();
}

} catch (SQLException e) {
return failed(this)
.output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>")
Expand Down Expand Up @@ -156,7 +156,7 @@ query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDAT
statement.setString(1, sdf.format(cal.getTime()));
statement.setString(2, action);
statement.execute();
} catch (SQLException e) {
} catch (SQLException e) {
System.err.println(e.getMessage());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public class SqlInjectionChallenge extends AssignmentEndpoint {
"select userid from sql_challenge_users where userid = ?";
PreparedStatement statement = connection.prepareStatement(checkUserQuery);
statement.setString(1, username_reg);

ResultSet resultSet = statement.execute();
if (resultSet.next()) {
if (username_reg.contains("tom'")) {
Expand All @@ -84,7 +85,6 @@ public class SqlInjectionChallenge extends AssignmentEndpoint {
preparedStatement.execute();
attackResult = success(this).feedback("user.created").feedbackArgs(username_reg).build();
}

} catch (SQLException e) {
attackResult = failed(this).output("Something went wrong").build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public final class Test {
stmt.setString(1, input);
var rs = stmt.execute();
return rs;
}
}

public ResultSet nameConflict(String input) throws SQLException {
int stmt = 0;
Expand All @@ -33,7 +33,7 @@ public final class Test {
ResultSet rs = statement.execute();
stmt++;
return rs;
}
}

public ResultSet doubleNameConflict(String input) throws SQLException {
int stmt = 0;
Expand All @@ -44,7 +44,7 @@ public final class Test {
ResultSet rs = stmt1.execute();
stmt = stmt + statement;
return rs;
}
}

public ResultSet tryResource(String input) throws SQLException {
String sql = "SELECT * FROM USERS WHERE USER = ?";
Expand All @@ -62,7 +62,7 @@ public final class Test {
stmt.setString(1, "user_" + input + "_name");
stmt.setString(2, input2);
return stmt.execute();
}
}

public ResultSet referencesAfterExecute(String input) throws SQLException {
String sql = "SELECT * FROM USERS WHERE USER = ?";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.acme.testcode;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public final class Test {

private Connection conn;

public void queryAfterDeclaration() throws SQLException {
Statement stmt;
String query2 = "SELECT * FROM users WHERE username = ?";
PreparedStatement statement = conn.prepareStatement(query2);
statement.setString(1, request.getParameter("username"));
ResultSet rs2 = statement.execute();
stmt = statement;
while (rs2.next()) {
System.out.println("User: " + rs2.getString("username"));
}
String query3 = "SELECT * FROM users WHERE email = ?";
stmt.close();
PreparedStatement stmt1 = conn.prepareStatement(query3);
stmt1.setString(1, request.getParameter("email"));
ResultSet rs3 = stmt1.execute();
stmt = stmt1;
while (rs3.next()) {
System.out.println("User: " + rs3.getString("username"));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.acme.testcode;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public final class Test {

private Connection conn;

public void queryAfterDeclaration() throws SQLException {
Statement stmt = conn.createStatement();
String username = request.getParameter("username");
String query2 = "SELECT * FROM users WHERE username = '" + username + "'";
ResultSet rs2 = stmt.executeQuery(query2);
while (rs2.next()) {
System.out.println("User: " + rs2.getString("username"));
}
String email = request.getParameter("email");
String query3 = "SELECT * FROM users WHERE email = '" + email + "'";
ResultSet rs3 = stmt.executeQuery(query3);
while (rs3.next()) {
System.out.println("User: " + rs3.getString("username"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import com.github.javaparser.resolution.types.ResolvedType;
import java.util.ArrayList;
import java.util.Optional;
import java.util.stream.IntStream;

public final class ASTTransforms {
/** Add an import in alphabetical order. */
Expand Down Expand Up @@ -87,26 +86,21 @@ public static void addStaticImportIfMissing(final CompilationUnit cu, final Stri
*/
public static <N extends Node> void addStatementAt(
final NodeWithStatements<N> node, final Statement stmt, final int index) {

var oldStatements = node.getStatements();
var newStatements = new ArrayList<Statement>();
int i = 0;
for (var s : node.getStatements()) {
for (var s : oldStatements) {
if (i == index) {
newStatements.add(stmt);
}
newStatements.add(s);
i++;
}

// rebuilds the whole statements list as to preserve proper children order.

// workaround for maintaining indent, removes all but the first
IntStream.range(0, node.getStatements().size() - 1)
.forEach(j -> node.getStatements().removeLast());
// replace the first with the new statement if needed
if (index == 0) {
node.getStatements().get(0).replace(stmt);
for (i = index; i < oldStatements.size(); i++) {
node.setStatement(i, newStatements.get(i));
}
newStatements.stream().skip(1).forEach(node.getStatements()::add);
node.addStatement(newStatements.get(newStatements.size() - 1));
}

/**
Expand Down Expand Up @@ -291,7 +285,13 @@ public static Expression removeEmptyStringConcatenation(final BinaryExpr binexp)
public static void removeEmptyStringConcatenation(Node subtree) {
subtree
.findAll(BinaryExpr.class, Node.TreeTraversal.POSTORDER)
.forEach(binexp -> binexp.replace(removeEmptyStringConcatenation(binexp)));
.forEach(
binexp -> {
var newNode = removeEmptyStringConcatenation(binexp);
if (newNode != binexp) {
binexp.replace(newNode.clone());
}
});
}

/** Removes unused variables. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,11 @@ public static Optional<MethodCallExpr> isScopeInMethodCall(final Expression expr
*
* @return A tuple with the above pattern in order sans the {@link SimpleName}.
*/
public static Optional<PatternExpr> isPatternExprDeclarationOf(
public static Optional<TypePatternExpr> isPatternExprDeclarationOf(
final Node node, final String name) {
if (node instanceof PatternExpr) {
var pexpr = (PatternExpr) node;
if (pexpr.getNameAsString().equals(name)) return Optional.of(pexpr);
if (node instanceof TypePatternExpr) {
var pexpr = (TypePatternExpr) node;
if (pexpr.getName().asString().equals(name)) return Optional.of(pexpr);
}
return Optional.empty();
}
Expand Down
Loading
Loading