Skip to content

Commit

Permalink
few cleanup items, added least privilege
Browse files Browse the repository at this point in the history
  • Loading branch information
mayhew64 committed Nov 16, 2016
1 parent f091e21 commit 507a4cf
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 129 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public class SqlInjectionLesson5b extends Assignment {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody AttackResult completed(@RequestParam String userid, HttpServletRequest request) throws IOException {
return injectableQuery(userid);

}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ public class SqlInjectionLesson6b extends Assignment {
} else {
return trackProgress(AttackResult.failed("You are close, try again"));
}

}

@Override
Expand Down Expand Up @@ -97,9 +96,6 @@ protected String getPassword()
e.printStackTrace();
// do nothing
}
System.out.println("Password: " + password);
return (password);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -203,54 +203,11 @@
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:SqlInjection_content12.adoc"></div>
</div>

<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<!--
<div class="adoc-content" th:replace="doc:HttpBasics_content2.adoc"></div>
-->
<div class="attack-container">
<!-- using attack-form class on your form, will allow your request to be ajaxified and stay within the display framework for webgoat -->
<div id="lessonContent">
<!-- using attack-form class on your form will allow your request to be ajaxified and stay within the display framework for webgoat -->
<!-- you can write your own custom forms, but standard form submission will take you to your endpoint and outside of the WebGoat framework -->
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjection/attack1"
enctype="application/json;charset=UTF-8">
<script>
// sample custom javascript in the recommended way ...
// a namespace has been assigned for it, but you can roll your own if you prefer
webgoat.customjs.assignRandomVal = function () {
var x = Math.floor((Math.random() * 100) + 1);
document.getElementById("magic_num").value = x;
};
webgoat.customjs.assignRandomVal();
</script>
<input type="hidden" name="magic_num" id="magic_num" value="foo" />
<table>
<tr>
<td>Was the HTTP command a POST or a GET:</td>
<td><input name="answer" value="" type="TEXT" /></td>
<td></td>
</tr>
<tr>
<td>What is the magic number:</td>
<td><input name="magic_answer" value="" type="TEXT" /><input
name="SUBMIT" value="Go!" type="SUBMIT" /></td>
<td></td>
</tr>
</table>
</form>
</div>
<!-- do not remove the two following div's, this is where your feedback/output will land -->
<div class="attack-feedback"></div>
<div class="attack-output"></div>
<!-- ... of course, you can move them if you want to, but that will not look consistent to other lessons -->
</div>
</div>
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:SqlInjection_content13.adoc"></div>
</div>

</html>
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
== Parameterized Queries – Java Example
-------------------------------------------------------
// Parser returns only valid string data
String accountID = getParser().getStringParameter(ACCT_ID, "");
String data = null;
try
// 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))
{
// 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;
// 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;
-------------------------------------------------------
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
== Parameterized Queries – .NET
-------------------------------------------------------
public static bool isUsernameValid(string username) {
RegEx r = new Regex(“^[A-Za-z0-9]{16}$”);
Return r.isMatch(username);
}
== Least Privilege

// 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… }
-------------------------------------------------------
=== Connect with a minimum set of privileges
* The application should connect to the database with different credentials for every trust distinction
* Applications rarely need delete rights to a table or database

=== Database accounts should limit schema access

=== Define database accounts for read and read/write access

=== Multiple connection pools based on access
* Use read only access for the authentication query
* Use read/write access for the data modification queries
* Use execute for access to stored procedure calls
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
== What is SQL Injection?

=== A SQL injection attack consists of insertion or "injection" of an SQL query via the input data from the client to the application
=== A SQL injection attack consists of insertion or "injection" of an malicious data via the SQL query input from the client to the application

=== A successful SQL injection exploit can:
* Read and modify sensitive data from the database
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

==== Potential String Injection
-------------------------------------------------------
"select * from users where name = " + userName + "'";
"select * from users where name = '" + userName + "'";
-------------------------------------------------------

==== Potential Numeric Injection
Expand All @@ -14,13 +14,14 @@
-------------------------------------------------------

=== 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;--#
* 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 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*

*All records are returned from database*
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ The query in the code builds a dynamic query as seen in the previous example. T
"select * from users where name = ‘" + userName + "'";
-------------------------------------------------------

Using the form below try to retrieve all the users from the users table.
Using the form below try to retrieve all the users from the users table. You shouldn't need to know any specific user name to get the complete list, however you can use 'Smith' to see the data for one user.

Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ The query in the code builds a dynamic query as seen in the previous example. T
"select * from users where employee_id = " + userID;
-------------------------------------------------------

Using the form below try to retrieve all the users from the users table.
Using the form below try to retrieve all the users from the users table. You shouldn't need to know any specific user name to get the complete list, however you can use '101' to see the data for one user.
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
== Parameterized Queries – Java Snippet

-------------------------------------------------------
[source,java]
----
public static bool isUsernameValid(string username) {
RegEx r = new Regex(“^[A-Za-z0-9]{16}$”);
return r.isMatch(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
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 }
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 … }
-------------------------------------------------------
----
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,5 @@ This lesson describes what is Structured Query Language (SQL) and how it can be
* The user will demonstrate knowledge on:
** String SQL Injection
** Numeric SQL Injection
** Blind SQL Injection


0 comments on commit 507a4cf

Please sign in to comment.