First round of sql injection with stubs
This commit is contained in:
parent
dbcd5cce3a
commit
8b6ad92aea
@ -13,7 +13,7 @@
|
|||||||
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
|
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
|
||||||
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
|
<!-- 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 -->
|
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
|
||||||
<div class="adoc-content" th:replace="doc:SqlInjection_conent1.adoc"></div>
|
<div class="adoc-content" th:replace="doc:SqlInjection_content1.adoc"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="lesson-page-wrapper">
|
<div class="lesson-page-wrapper">
|
||||||
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
|
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
|
||||||
@ -33,6 +33,114 @@
|
|||||||
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
|
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
|
||||||
<div class="adoc-content" th:replace="doc:SqlInjection_content4.adoc"></div>
|
<div class="adoc-content" th:replace="doc:SqlInjection_content4.adoc"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="lesson-page-wrapper">
|
||||||
|
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
|
||||||
|
<!-- 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_content5.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:SqlInjection_content5a.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/attack5a"
|
||||||
|
enctype="application/json;charset=UTF-8">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>Name:</td>
|
||||||
|
<td><input name="answer" value="" type="TEXT" /></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>
|
||||||
|
<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:SqlInjection_content5a.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/attack5b"
|
||||||
|
enctype="application/json;charset=UTF-8">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>Name:</td>
|
||||||
|
<td><input name="answer" value="" type="TEXT" /></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>
|
||||||
|
<div class="lesson-page-wrapper">
|
||||||
|
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
|
||||||
|
<!-- 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_content6.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, 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_content7.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, 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_content8.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, 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_content9.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, 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_content10.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, 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_content11.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, 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_content12.adoc"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="lesson-page-wrapper">
|
<div class="lesson-page-wrapper">
|
||||||
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
|
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
== What is SQL
|
== 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”
|
* Not “Standard Query Language”
|
||||||
* Multiple versions of SQL. Most databases have some custom functions
|
* Multiple versions of SQL. Most databases have some custom functions
|
||||||
* Most vendors have a proprietary extension
|
* Most vendors have a proprietary extension
|
||||||
|
|
||||||
= Data Manipulation Language (DML)
|
=== Data Manipulation Language (DML)
|
||||||
* SELECT, INSERT, UPDATE, DELETE, …
|
* SELECT, INSERT, UPDATE, DELETE, …
|
||||||
|
|
||||||
= Data Definition Language (DDL)
|
=== Data Definition Language (DDL)
|
||||||
* CREATE, ALTER, DROP,TRUNCATE,…
|
* CREATE, ALTER, DROP,TRUNCATE,…
|
||||||
|
|
||||||
= Data Control Language (DCL)
|
=== Data Control Language (DCL)
|
||||||
* GRANT, REVOKE, …
|
* GRANT, REVOKE, …
|
||||||
|
@ -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;
|
||||||
|
-------------------------------------------------------
|
@ -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… }
|
||||||
|
-------------------------------------------------------
|
@ -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
|
||||||
|
|
@ -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… }
|
||||||
|
-------------------------------------------------------
|
@ -1,32 +1,13 @@
|
|||||||
== Consequences of SQL Injection
|
== What is SQL Injection?
|
||||||
|
|
||||||
= SQL injection attacks allow attackers to
|
=== A SQL injection attack consists of insertion or "injection" of an SQL query via the input data from the client to the application
|
||||||
* 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
|
|
||||||
|
|
||||||
= SQL Injection is more common in PHP, Classic ASP, Cold Fusion and older languages
|
=== A successful SQL injection exploit can:
|
||||||
* Languages do not provide parameterized query support
|
* Read and modify sensitive data from the database
|
||||||
* Parameterized queries have been added to newer versions
|
* Execute administration operations on the database
|
||||||
* Early adopters of web technology
|
** 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, …
|
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
== Example of SQL Injection
|
== Consequences of SQL Injection
|
||||||
|
|
||||||
= Dynamic query in application
|
=== SQL injection attacks allow attackers to
|
||||||
* select * from users where name = ‘” + userName + “’”;
|
* Spoof identity
|
||||||
* select * from users where employee_id = ” + userID;
|
* 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
|
=== SQL Injection is more common in PHP, Classic ASP, Cold Fusion and older languages
|
||||||
* userName = [red]Smith’ or ‘1’=‘1[red]
|
* Languages that do not provide parameterized query support
|
||||||
* userName =[red]‘ or 1=1 --[red]
|
* Parameterized queries have been added to newer versions
|
||||||
* userID = [red]1234567 or 1=1[red]
|
* Early adopters of web technology (i.e. Old Code)
|
||||||
* 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*
|
|
@ -1,19 +1,17 @@
|
|||||||
== Special Characters & Statements
|
== Severity of SQL Injection
|
||||||
|
|
||||||
/* */ are inline comments
|
=== The severity of SQL Injection attacks is limited by
|
||||||
-- , # are line comments
|
* Attacker’s skill and imagination
|
||||||
'Select * from users where name = ‘admin’--and pass = ‘pass’'
|
* Defense in depth countermeasures
|
||||||
|
** Input validation
|
||||||
|
** Least privilege
|
||||||
|
* Database technology
|
||||||
|
|
||||||
; allows query chaining
|
=== Not all databases support command chaining
|
||||||
'Select * from users; drop table users;'
|
* Microsoft Access
|
||||||
|
* MySQL Connector/J and C
|
||||||
|
* Oracle
|
||||||
|
|
||||||
’,+,|| allows string concatenation
|
=== Not all databases are equal (SQL Server)
|
||||||
Char() strings without quotes
|
* Command shell: `master.dbo.xp_cmdshell 'cmd.exe dir c:'`
|
||||||
'Select * from users where name = ‘+char(27) or 1=1'
|
* Reqistry commands: `xp_regread`, `xp_regdeletekey`, …
|
||||||
|
|
||||||
|
|
||||||
Unions allows overlapping of database tables
|
|
||||||
'Select id, text from news
|
|
||||||
union all select name, pass from users'
|
|
||||||
|
|
||||||
Joins allows connecting to other tables
|
|
||||||
|
@ -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*
|
@ -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.
|
@ -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.
|
@ -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
|
@ -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
|
@ -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
|
||||||
|
-------------------------------------------------------
|
@ -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 … }
|
||||||
|
-------------------------------------------------------
|
Loading…
x
Reference in New Issue
Block a user