Reworked description and added additional hints. Split regex for code checks for better readability.

This commit is contained in:
Benedikt - Desktop 2018-11-24 14:55:51 +01:00 committed by Nanne Baars
parent 4cdd649a5a
commit e873752eac
3 changed files with 52 additions and 16 deletions

View File

@ -19,7 +19,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@AssignmentPath("SqlInjection/attack10b") @AssignmentPath("SqlInjection/attack10b")
@AssignmentHints(value = {"SqlStringInjectionHint-mitigation-10b-1", "SqlStringInjectionHint-mitigation-10b-2", "SqlStringInjectionHint-mitigation-10b-3"}) @AssignmentHints(value = {"SqlStringInjectionHint-mitigation-10b-1", "SqlStringInjectionHint-mitigation-10b-2", "SqlStringInjectionHint-mitigation-10b-3", "SqlStringInjectionHint-mitigation-10b-4", "SqlStringInjectionHint-mitigation-10b-5"})
public class SqlInjectionLesson10b extends AssignmentEndpoint { public class SqlInjectionLesson10b extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST) @RequestMapping(method = RequestMethod.POST)
@ -28,21 +28,40 @@ public class SqlInjectionLesson10b extends AssignmentEndpoint {
try { try {
if (editor.isEmpty()) return trackProgress(failed().feedback("sql-injection.10b.no-code").build()); if (editor.isEmpty()) return trackProgress(failed().feedback("sql-injection.10b.no-code").build());
String regex1 = "(?=.*PreparedStatement.*)(?=.*setString.*)(?=.*\\=\\?.*|.*\\=\\s\\?.*)";
editor = editor.replaceAll("\\<.*?>", ""); editor = editor.replaceAll("\\<.*?>", "");
boolean hasImportant = this.check_text(regex1, editor.replace("\n", "").replace("\r", ""));
String regex_setsUpConnection = "(?=.*getConnection.*)";
String regex_usesPreparedStatement = "(?=.*PreparedStatement.*)";
String regex_usesPlaceholder = "(?=.*\\=\\?.*|.*\\=\\s\\?.*)";
String regex_usesSetString = "(?=.*setString.*)";
String regex_usesExecute = "(?=.*execute.*)";
String regex_usesExecuteUpdate = "(?=.*executeUpdate.*)";
String codeline = editor.replace("\n", "").replace("\r", "");
boolean setsUpConnection = this.check_text(regex_setsUpConnection, codeline);
boolean usesPreparedStatement = this.check_text(regex_usesPreparedStatement, codeline);
boolean usesSetString = this.check_text(regex_usesSetString, codeline);
boolean usesPlaceholder = this.check_text(regex_usesPlaceholder, codeline);
boolean usesExecute = this.check_text(regex_usesExecute, codeline);
boolean usesExecuteUpdate = this.check_text(regex_usesExecuteUpdate, codeline);
boolean hasImportant = (setsUpConnection && usesPreparedStatement && usesPlaceholder && usesSetString && (usesExecute || usesExecuteUpdate));
List<Diagnostic> hasCompiled = this.compileFromString(editor); List<Diagnostic> hasCompiled = this.compileFromString(editor);
String errors = "";
if (hasImportant && hasCompiled.size() < 1) { if (hasImportant && hasCompiled.size() < 1) {
return trackProgress(success().feedback("sql-injection.10b.success").build()); return trackProgress(success().feedback("sql-injection.10b.success").build());
} else if (hasCompiled.size() > 0) { } else if (hasCompiled.size() > 0) {
String errors = "";
for (Diagnostic d : hasCompiled) { for (Diagnostic d : hasCompiled) {
errors += d.getMessage(null) + "\n"; errors += d.getMessage(null) + "<br>";
} }
return trackProgress(failed().feedback("sql-injection.10b.compiler-errors").output(errors).build());
} else {
return trackProgress(failed().feedback("sql-injection.10b.failed").build());
} }
return trackProgress(failed().feedback("sql-injection.10b.failed").output(errors.replace("\n", "<br>")).build());
} catch(Exception e) { } catch(Exception e) {
return trackProgress(success().build()); return trackProgress(failed().output(e.getMessage()).build());
} }
} }
@ -59,7 +78,7 @@ public class SqlInjectionLesson10b extends AssignmentEndpoint {
} }
private SimpleJavaFileObject getJavaFileContentsAsString(String s){ private SimpleJavaFileObject getJavaFileContentsAsString(String s){
StringBuilder javaFileContents = new StringBuilder("import java.sql.*; public class TestClass { public static void main(String[] args) {" + s + "}}"); StringBuilder javaFileContents = new StringBuilder("import java.sql.*; public class TestClass { static String DBUSER; static String DBPW; static String DBURL; public static void main(String[] args) {" + s + "}}");
JavaObjectFromString javaFileObject = null; JavaObjectFromString javaFileObject = null;
try{ try{
javaFileObject = new JavaObjectFromString("TestClass.java", javaFileContents.toString()); javaFileObject = new JavaObjectFromString("TestClass.java", javaFileContents.toString());

View File

@ -64,9 +64,11 @@ SqlStringInjectionHint.9.5=How about something like '; UPDATE employees....
sql-injection.10.success=<span class='feedback-positive'>Success! You successfully deleted the access_log table and that way compromised the availability of the data.</span> sql-injection.10.success=<span class='feedback-positive'>Success! You successfully deleted the access_log table and that way compromised the availability of the data.</span>
sql-injection.10.entries=<span class='feedback-negative'>There's still evidence of what you did. Better remove the whole table.</span> sql-injection.10.entries=<span class='feedback-negative'>There's still evidence of what you did. Better remove the whole table.</span>
sql-injection.10b.success=<span class='feedback-positive'>Your code can prevent an SQL Injection! Success!</span>
sql-injection.10b.success=<span class='feedback-positive'>You did it! Your code can prevent an SQL Injection attack!</span>
sql-injection.10b.failed=<span class='feedback-negative'>Something doesn't seem right with that code. Maybe you should look at an example how to prevent SQL Injections with JDBC?</span> sql-injection.10b.failed=<span class='feedback-negative'>Something doesn't seem right with that code. Maybe you should look at an example how to prevent SQL Injections with JDBC?</span>
sql-injection.10b.no-code=<span class='feedback-negative'>You need to write some code.</span> sql-injection.10b.no-code=<span class='feedback-negative'>You need to write some code.</span>
sql-injection.10b.compiler-errors=<span class='feedback-negative'>Couldn't compile code:</span>
SqlStringInjectionHint.10.1=Use the techniques that you have learned before. SqlStringInjectionHint.10.1=Use the techniques that you have learned before.
SqlStringInjectionHint.10.2=The application takes your input and filters for entries that are LIKE it. SqlStringInjectionHint.10.2=The application takes your input and filters for entries that are LIKE it.
@ -78,9 +80,11 @@ SqlStringInjectionHint.10.6=Remember that you can use the -- metacharacter to co
SqlStringInjectionHint-mitigation-10a-1=First establish a connection, after that you can create a statement. SqlStringInjectionHint-mitigation-10a-1=First establish a connection, after that you can create a statement.
SqlStringInjectionHint-mitigation-10a-2=For every datatype there is a method to insert values into a wildcard symbol in a statement. SqlStringInjectionHint-mitigation-10a-2=For every datatype there is a method to insert values into a wildcard symbol in a statement.
SqlStringInjectionHint-mitigation-10b-1=A database connection has to be surrounded by a try-catch block to handle the very common case of an error while establishing the connection! SqlStringInjectionHint-mitigation-10b-1=A database connection has to be surrounded by a try-catch block to handle the very common case of an error while establishing the connection.
SqlStringInjectionHint-mitigation-10b-2=Remember to use the right kind of statement, so your code is no longer vulnerable for SQL-Injections! SqlStringInjectionHint-mitigation-10b-2=Remember to use the right kind of statement, so your code is no longer vulnerable for SQL-Injections.
SqlStringInjectionHint-mitigation-10b-3=The wildcard-symbol '?' in a prepared statement can be filled with the right kind of method. There exists one for every datatype! SqlStringInjectionHint-mitigation-10b-3=The wildcard-symbol '?' in a prepared statement can be filled with the right kind of method. There exists one for every datatype.
SqlStringInjectionHint-mitigation-10b-4=Make sure to execute your statement.
SqlStringInjectionHint-mitigation-10b-5=View the previous lesson to check back on how you can build set up a connection.
SqlStringInjectionHint-mitigation-12a-1=Try sorting and look at the request SqlStringInjectionHint-mitigation-12a-1=Try sorting and look at the request
SqlStringInjectionHint-mitigation-12a-2=Intercept the request and try to specify a different order by SqlStringInjectionHint-mitigation-12a-2=Intercept the request and try to specify a different order by

View File

@ -1,10 +1,22 @@
== Try it! Writing safe code == Try it! Writing safe code
Now it's time to write your own code! Use JDBC to connect to a database and use a statement to request data from the database (the content of the statement doesn't matter, but make sure, that the SQL is valid). The SQL Statement should at least contain one string parameter. The content of the parameter is stored in the variable 'String content'. Now it's time to write your own code!
Your task is to use JDBC to connect to a database and request data from it.
All code you write down below gets inserted into a main method of a java class with the name "TestClass". This class also imports java.sql.*. Use your knowledge and write the right code from scratch! *Requirements:*
For example; following coding would compile without any error. * connect to a database
* perform a query on the database which is immune to SQL Injection attacks
* your query needs to contain at least one string parameter
*Some tips before you start:* +
For connecting to the database, you can simply assume the constants *DBURL*, *DBUSER* and *DBPW* as given. +
The content of your query does not matter, as long as the SQL is valid and meets the requirements. +
All the code you write gets inserted into the main method of a java class with the name "TestClass" that already imports *java.sql.** for your.
Not creative enough to think of your own query? How about you try to retrieve the data for a user with a specific name from a fictional database table called *users*.
For example; following coding would compile without any error (but of course does not meet the requirements to complete this lesson).
[source,java] [source,java]
------------------------------------------------------- -------------------------------------------------------
@ -16,4 +28,5 @@ try {
} }
------------------------------------------------------- -------------------------------------------------------
Now type your solution in the editor window down below (if you can't type there it might help to adjust the size of your browser window once, then it should work): Use your knowledge and write some valid code from scratch in the editor window down below!
(if you can't type there it might help to adjust the size of your browser window once, then it should work):