diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/html/SqlInjection.html b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/html/SqlInjection.html index 2796365c9..20bf40f44 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/html/SqlInjection.html +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/html/SqlInjection.html @@ -13,7 +13,7 @@ -
+
@@ -33,6 +33,114 @@ which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
+
+ + +
+
+
+ + +
+
+ +
+ + + +
+ + + + + + +
Name:
+
+
+ +
+
+ +
+
+
+ + +
+
+ +
+ + + +
+ + + + + + +
Name:
+
+
+ +
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content1.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content1.adoc index f1471330c..10473457d 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content1.adoc +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content1.adoc @@ -1,17 +1,17 @@ == What is SQL -SQL is a way to interact with databases. +SQL is a way to interact with databases and is interpreted by the database. -= SQL = Structured Query Language +=== SQL - Structured Query Language * Not “Standard Query Language” * Multiple versions of SQL. Most databases have some custom functions * Most vendors have a proprietary extension -= Data Manipulation Language (DML) +=== Data Manipulation Language (DML) * SELECT, INSERT, UPDATE, DELETE, … -= Data Definition Language (DDL) +=== Data Definition Language (DDL) * CREATE, ALTER, DROP,TRUNCATE,… -= Data Control Language (DCL) +=== Data Control Language (DCL) * GRANT, REVOKE, … diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content10.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content10.adoc new file mode 100644 index 000000000..aab88f8d6 --- /dev/null +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content10.adoc @@ -0,0 +1,35 @@ +== Parameterized Queries – Java Example +------------------------------------------------------- + // Parser returns only valid string data + String accountID = getParser().getStringParameter(ACCT_ID, ""); + String data = null; + try + { + // Read only database connection + Statement connection = DatabaseUtilities.getConnection(READ_ONLY); + + // Build a fully qualified query + String query = "SELECT first_name, last_name, acct_id, balance + FROM user_data WHERE acct_id = ?"; + PreparedStatement statement = connection.prepareStatement(query); + statement.setString(1, accountID); + ResultSet results = statement.executeQuery(); + if ((results != null) && (results.first() == true)) + { + // Only one record should be returned for this query + Results.last(); + if (results.getRow() <= 2) + { + data = processAccount(results); + } + else { // Handle the error – Database integrity issue } + } + else { // Handle the error – no records found } + } + catch (SQLException sqle) { // Log and handle the SQL Exception } + catch (Exception e) { // Log and handle the Exception } + finally { // Always close connection in finally block + DatabaseUtilities.closeConnection(); + } + return data; +------------------------------------------------------- diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content11.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content11.adoc new file mode 100644 index 000000000..ff606709b --- /dev/null +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content11.adoc @@ -0,0 +1,22 @@ +== Parameterized Queries – .NET +------------------------------------------------------- +public static bool isUsernameValid(string username) { + RegEx r = new Regex(“^[A-Za-z0-9]{16}$”); + Return r.isMatch(username); +} + +// SqlConnection conn is set and opened elsewhere for brevity. +try { + string selectString = “SELECT * FROM user_table WHERE username = @userID”; + SqlCommand cmd = new SqlCommand( selectString, conn ); + if ( isUsernameValid( uid ) ) { + cmd.Parameters.Add( "@userID", SqlDbType.VarChar, 16 ).Value = uid; + SqlDataReader myReader = cmd.ExecuteReader(); + if ( myReader ) { + // make the user record active in some way. + myReader.Close(); + } + } else { // handle invalid input } +} +catch (Exception e) { // Handle all exceptions… } +------------------------------------------------------- diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content12.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content12.adoc new file mode 100644 index 000000000..3c1515f83 --- /dev/null +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content12.adoc @@ -0,0 +1,13 @@ +== Input Validation Required? + +=== Since my queries are no longer injectable do I still need to validate my input? +* *YES!* + +=== Prevents other types of attacks from being stored in the database +* Stored XSS +* Information leakage +* Logic errors – business rule validation +* SQL Injection + +=== Often the database is considered trusted + diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content13.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content13.adoc new file mode 100644 index 000000000..ff606709b --- /dev/null +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content13.adoc @@ -0,0 +1,22 @@ +== Parameterized Queries – .NET +------------------------------------------------------- +public static bool isUsernameValid(string username) { + RegEx r = new Regex(“^[A-Za-z0-9]{16}$”); + Return r.isMatch(username); +} + +// SqlConnection conn is set and opened elsewhere for brevity. +try { + string selectString = “SELECT * FROM user_table WHERE username = @userID”; + SqlCommand cmd = new SqlCommand( selectString, conn ); + if ( isUsernameValid( uid ) ) { + cmd.Parameters.Add( "@userID", SqlDbType.VarChar, 16 ).Value = uid; + SqlDataReader myReader = cmd.ExecuteReader(); + if ( myReader ) { + // make the user record active in some way. + myReader.Close(); + } + } else { // handle invalid input } +} +catch (Exception e) { // Handle all exceptions… } +------------------------------------------------------- diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content2.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content2.adoc index 7fd8d62e0..142a1ed3c 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content2.adoc +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content2.adoc @@ -1,32 +1,13 @@ -== Consequences of SQL Injection +== What is SQL Injection? -= SQL injection attacks allow attackers to -* Spoof identity -* Tamper with existing data -* Cause repudiation issues such as voiding transactions or changing balances -* Allow the complete disclosure of all data on the system -* Destroy the data or make it otherwise unavailable -* Become administrator of the database server +=== A SQL injection attack consists of insertion or "injection" of an SQL query via the input data from the client to the application -= SQL Injection is more common in PHP, Classic ASP, Cold Fusion and older languages -* Languages do not provide parameterized query support -* Parameterized queries have been added to newer versions -* Early adopters of web technology +=== A successful SQL injection exploit can: +* Read and modify sensitive data from the database +* Execute administration operations on the database +** Shutdown auditing or the DBMS +** Truncate tables and logs +** Add users +* Recover the content of a given file present on the DBMS file system +* Issue commands to the operating system -== Severity of SQL Injection - -= The severity of SQL Injection attacks is limited by -* Attacker’s skill and imagination -* Defense in depth countermeasures -Input validation -Least privilege -* Database technology - -= Not all databases support command chaining -* Microsoft Access -* MySQL Connector/J and C -* Oracle - -= Not all databases are equal (SQL Server) -* Command shell: master.dbo.xp_cmdshell 'cmd.exe dir c:' -* Reqistry commands: xp_regread, xp_regdeletekey, … diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content3.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content3.adoc index 9080b7f19..d4a6692f2 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content3.adoc +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content3.adoc @@ -1,17 +1,14 @@ -== Example of SQL Injection +== Consequences of SQL Injection -= Dynamic query in application -* select * from users where name = ‘” + userName + “’”; -* select * from users where employee_id = ” + userID; +=== SQL injection attacks allow attackers to +* Spoof identity +* Tamper with existing data +* Cause repudiation issues such as voiding transactions or changing balances +* Allow the complete disclosure of all data on the system +* Destroy the data or make it otherwise unavailable +* Become administrator of the database server -= Attacker supplies unexpected text -* userName = [red]Smith’ or ‘1’=‘1[red] -* userName =[red]‘ or 1=1 --[red] -* userID = [red]1234567 or 1=1[red] -* UserName = [red]Smith’;drop table users; truncate audit_log;--[red] - -= Application executes query -* select * from users where name = [red]‘Smith’ or ‘1’ = ‘1’[red] -** select * from users where name = [red]‘Smith’ or TRUE[red] -* select * from users where employee_id = 1234567 or 1=1 -** *All records are returned from database* +=== SQL Injection is more common in PHP, Classic ASP, Cold Fusion and older languages +* Languages that do not provide parameterized query support +* Parameterized queries have been added to newer versions +* Early adopters of web technology (i.e. Old Code) \ No newline at end of file diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content4.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content4.adoc index 51013c0ce..c34229c95 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content4.adoc +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content4.adoc @@ -1,19 +1,17 @@ -== Special Characters & Statements +== Severity of SQL Injection -/* */ are inline comments --- , # are line comments -'Select * from users where name = ‘admin’--and pass = ‘pass’' +=== The severity of SQL Injection attacks is limited by +* Attacker’s skill and imagination +* Defense in depth countermeasures +** Input validation +** Least privilege +* Database technology -; allows query chaining -'Select * from users; drop table users;' +=== Not all databases support command chaining +* Microsoft Access +* MySQL Connector/J and C +* Oracle -’,+,|| allows string concatenation -Char() strings without quotes -'Select * from users where name = ‘+char(27) or 1=1' - - -Unions allows overlapping of database tables -'Select id, text from news -union all select name, pass from users' - -Joins allows connecting to other tables +=== Not all databases are equal (SQL Server) +* Command shell: `master.dbo.xp_cmdshell 'cmd.exe dir c:'` +* Reqistry commands: `xp_regread`, `xp_regdeletekey`, … diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content5.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content5.adoc new file mode 100644 index 000000000..217c14c04 --- /dev/null +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content5.adoc @@ -0,0 +1,23 @@ +== Example of SQL Injection + +=== Dynamic query in application +------------------------------------------------------- +"select * from users where name = ‘" + userName + "'"; +------------------------------------------------------- + +------------------------------------------------------- + +"select * from users where employee_id = " + userID; +------------------------------------------------------- + +=== Attacker supplies unexpected text +* userName = [red]#Smith’ or ‘1’=‘1# +* userName =[red]#‘ or 1=1 --# +* userID = [red]#1234567 or 1=1# +* UserName = [red]#Smith’;drop table users; truncate audit_log;--# + +=== Application executes query +* select * from users where name = [red]#‘Smith’ or ‘1’ = ‘1’# +** select * from users where name = [red]#‘Smith’ or TRUE# +* select * from users where employee_id = 1234567 or 1=1 +* *All records are returned from database* diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content5a.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content5a.adoc new file mode 100644 index 000000000..f47627c38 --- /dev/null +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content5a.adoc @@ -0,0 +1,8 @@ +== Try It! String SQL Injection + +The query in the code builds a dynamic query as seen in the previous example. The query in the code looks like: +------------------------------------------------------- +"select * from users where name = ‘" + userName + "'"; +------------------------------------------------------- + +Using the form below try to retrieve all the users from the users table. diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content5b.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content5b.adoc new file mode 100644 index 000000000..c2cdd900c --- /dev/null +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content5b.adoc @@ -0,0 +1,8 @@ +== Try It! Numeric SQL Injection + +The query in the code builds a dynamic query as seen in the previous example. The query in the code looks like: +------------------------------------------------------- +"select * from users where employee_id = " + userID; +------------------------------------------------------- + +Using the form below try to retrieve all the users from the users table. diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content6.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content6.adoc new file mode 100644 index 000000000..f6ac31efe --- /dev/null +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content6.adoc @@ -0,0 +1,20 @@ +== Special Characters + +/* */ are inline comments +-- , # are line comments +'Select * from users where name = ‘admin’--and pass = ‘pass’' + +; allows query chaining +'Select * from users; drop table users;' + +’,+,|| allows string concatenation +Char() strings without quotes +'Select * from users where name = ‘+char(27) or 1=1' + +== Special Statements + +Unions allows overlapping of database tables +'Select id, text from news +union all select name, pass from users' + +Joins allows connecting to other tables diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content7.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content7.adoc new file mode 100644 index 000000000..68cbbdbdf --- /dev/null +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content7.adoc @@ -0,0 +1,23 @@ +== Immutable Queries + +=== Static queries? +------------------------------------------------------- +select * from products; +------------------------------------------------------- + +------------------------------------------------------- +select * from users where user = "'" + session.getAttribute("UserID") + "'"; +------------------------------------------------------- + +=== Parameterized Queries + +------------------------------------------------------- +String query = "SELECT * FROM users WHERE last_name = ?"; +PreparedStatement statement = connection.prepareStatement(query); +statement.setString(1, accountName); +ResultSet results = statement.executeQuery(); +------------------------------------------------------- + +=== Stored Procedures + +Only if stored procedure does not generate dynamic SQL diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content8.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content8.adoc new file mode 100644 index 000000000..850eae87c --- /dev/null +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content8.adoc @@ -0,0 +1,23 @@ +== Stored Procedures + +=== Safe Stored Procedure (Microsoft SQL Server) +------------------------------------------------------- +CREATE PROCEDURE ListCustomers(@Country nvarchar(30)) +AS +SELECT City, COUNT(*) +FROM Customers +WHERE Country LIKE @Country GROUP BY City + + +EXEC ListCustomers ‘USA’ +------------------------------------------------------- + +=== Injectable Stored Procedure (Microsoft SQL Server) +------------------------------------------------------- +CREATE PROEDURE getUser(@lastName nvarchar(25)) +AS +declare @sql nvarchar(255) +set @sql = 'select * from users where + LastName = + @LastName + ' +exec sp_executesql @sql +------------------------------------------------------- diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content9.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content9.adoc new file mode 100644 index 000000000..6d548addd --- /dev/null +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_content9.adoc @@ -0,0 +1,24 @@ +== Parameterized Queries – Java Snippet + +------------------------------------------------------- +public static bool isUsernameValid(string username) { + RegEx r = new Regex(“^[A-Za-z0-9]{16}$”); + return r.isMatch(username); +} + +// java.sql.Connection conn is set elsewhere for brevity. +PreparedStatement ps = null; +RecordSet rs = null; +try { + pUserName = request.getParameter(“UserName”); + if ( isUsernameValid (pUsername); + ps = conn.prepareStatement(“SELECT * FROM user_table + WHERE username = ? ”); + ps.setString(1, pUsername); + rs = ps.execute(); + if ( rs.next() ) { + // do the work of making the user record active in some way + } else { // handle invalid input } +} +catch (…) { // handle all exceptions … } +-------------------------------------------------------