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 -->
+
+
+
+
+
+
+
+
+
+
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 … }
+-------------------------------------------------------