Renamed to sqlinjection
This commit is contained in:
@ -0,0 +1,7 @@
|
||||
.feedback-positive {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.feedback-negative {
|
||||
color: red;
|
||||
}
|
96
src/main/resources/lessons/sqlinjection/css/challenge.css
Normal file
96
src/main/resources/lessons/sqlinjection/css/challenge.css
Normal file
@ -0,0 +1,96 @@
|
||||
.panel-login {
|
||||
border-color: #ccc;
|
||||
-webkit-box-shadow: 0px 2px 3px 0px rgba(0,0,0,0.2);
|
||||
-moz-box-shadow: 0px 2px 3px 0px rgba(0,0,0,0.2);
|
||||
box-shadow: 0px 2px 3px 0px rgba(0,0,0,0.2);
|
||||
}
|
||||
.panel-login>.panel-heading {
|
||||
color: #00415d;
|
||||
background-color: #fff;
|
||||
border-color: #fff;
|
||||
text-align:center;
|
||||
}
|
||||
.panel-login>.panel-heading a{
|
||||
text-decoration: none;
|
||||
color: #666;
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
-webkit-transition: all 0.1s linear;
|
||||
-moz-transition: all 0.1s linear;
|
||||
transition: all 0.1s linear;
|
||||
}
|
||||
.panel-login>.panel-heading a.active{
|
||||
color: #029f5b;
|
||||
font-size: 18px;
|
||||
}
|
||||
.panel-login>.panel-heading hr{
|
||||
margin-top: 10px;
|
||||
margin-bottom: 0px;
|
||||
clear: both;
|
||||
border: 0;
|
||||
height: 1px;
|
||||
background-image: -webkit-linear-gradient(left,rgba(0, 0, 0, 0),rgba(0, 0, 0, 0.15),rgba(0, 0, 0, 0));
|
||||
background-image: -moz-linear-gradient(left,rgba(0,0,0,0),rgba(0,0,0,0.15),rgba(0,0,0,0));
|
||||
background-image: -ms-linear-gradient(left,rgba(0,0,0,0),rgba(0,0,0,0.15),rgba(0,0,0,0));
|
||||
background-image: -o-linear-gradient(left,rgba(0,0,0,0),rgba(0,0,0,0.15),rgba(0,0,0,0));
|
||||
}
|
||||
.panel-login input[type="text"],.panel-login input[type="email"],.panel-login input[type="password"] {
|
||||
height: 45px;
|
||||
border: 1px solid #ddd;
|
||||
font-size: 16px;
|
||||
-webkit-transition: all 0.1s linear;
|
||||
-moz-transition: all 0.1s linear;
|
||||
transition: all 0.1s linear;
|
||||
}
|
||||
.panel-login input:hover,
|
||||
.panel-login input:focus {
|
||||
outline:none;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
border-color: #ccc;
|
||||
}
|
||||
.btn-login {
|
||||
background-color: #59B2E0;
|
||||
outline: none;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
height: auto;
|
||||
font-weight: normal;
|
||||
padding: 14px 0;
|
||||
text-transform: uppercase;
|
||||
border-color: #59B2E6;
|
||||
}
|
||||
.btn-login:hover,
|
||||
.btn-login:focus {
|
||||
color: #fff;
|
||||
background-color: #53A3CD;
|
||||
border-color: #53A3CD;
|
||||
}
|
||||
.forgot-password {
|
||||
text-decoration: underline;
|
||||
color: #888;
|
||||
}
|
||||
.forgot-password:hover,
|
||||
.forgot-password:focus {
|
||||
text-decoration: underline;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.btn-register {
|
||||
background-color: #1CB94E;
|
||||
outline: none;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
height: auto;
|
||||
font-weight: normal;
|
||||
padding: 14px 0;
|
||||
text-transform: uppercase;
|
||||
border-color: #1CB94A;
|
||||
}
|
||||
.btn-register:hover,
|
||||
.btn-register:focus {
|
||||
color: #fff;
|
||||
background-color: #1CA347;
|
||||
border-color: #1CA347;
|
||||
}
|
67
src/main/resources/lessons/sqlinjection/css/quiz.css
Normal file
67
src/main/resources/lessons/sqlinjection/css/quiz.css
Normal file
@ -0,0 +1,67 @@
|
||||
.attack-container.quiz {
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#q_container p {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#q_container .quiz_question {
|
||||
border: solid 2px white;
|
||||
padding: 4px;
|
||||
margin: 5px 2px 20px 2px;
|
||||
box-shadow: 0px 1px 3px 1px #e4e4e4;
|
||||
}
|
||||
|
||||
#q_container .quiz_question label {
|
||||
font-weight: normal;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
#q_container .quiz_question input {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
border: 2px solid #dadada;
|
||||
background: white;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
#q_container .quiz_question input:checked {
|
||||
background: #51b7ff;
|
||||
}
|
||||
|
||||
#q_container .quiz_question input:hover,
|
||||
#q_container .quiz_question label:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#q_container .quiz_question.correct {
|
||||
border: solid 2px #ddf7dd;
|
||||
background: #ddf7dd;
|
||||
transition: all 300ms ease-in-out;
|
||||
}
|
||||
|
||||
#q_container .quiz_question.incorrect {
|
||||
border: solid 2px #f5d3d3;
|
||||
background: #f5d3d3;
|
||||
transition: all 300ms ease-in-out;
|
||||
}
|
||||
|
||||
input[name='Quiz_solutions'] {
|
||||
background: white;
|
||||
border: 1px solid gray;
|
||||
padding: 7px 10px;
|
||||
transition: 300ms all ease-in-out;
|
||||
}
|
||||
|
||||
input[name='Quiz_solutions']:hover {
|
||||
background: #51b7ff;
|
||||
color: white;
|
||||
border-color: white;
|
||||
transition: 300ms all ease-in-out;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
CREATE TABLE SERVERS(
|
||||
id varchar(10),
|
||||
hostname varchar(20),
|
||||
ip varchar(20),
|
||||
mac varchar(20),
|
||||
status varchar(20),
|
||||
description varchar(40)
|
||||
);
|
||||
INSERT INTO SERVERS VALUES ('1', 'webgoat-dev', '192.168.4.0', 'AA:BB:11:22:CC:DD', 'online', 'Development server');
|
||||
INSERT INTO SERVERS VALUES ('2', 'webgoat-tst', '192.168.2.1', 'EE:FF:33:44:AB:CD', 'online', 'Test server');
|
||||
INSERT INTO SERVERS VALUES ('3', 'webgoat-acc', '192.168.3.3', 'EF:12:FE:34:AA:CC', 'offline', 'Acceptance server');
|
||||
INSERT INTO SERVERS VALUES ('4', 'webgoat-pre-prod', '192.168.6.4', 'EF:12:FE:34:AA:CC', 'offline', 'Pre-production server');
|
||||
INSERT INTO SERVERS VALUES ('4', 'webgoat-prd', '104.130.219.202', 'FA:91:EB:82:DC:73', 'out of order', 'Production server');
|
@ -0,0 +1,24 @@
|
||||
CREATE TABLE user_data(
|
||||
userid int not null,
|
||||
first_name varchar(20),
|
||||
last_name varchar(20),
|
||||
cc_number varchar(30),
|
||||
cc_type varchar(10),
|
||||
cookie varchar(20),
|
||||
login_count int
|
||||
);
|
||||
INSERT INTO user_data VALUES (101,'Joe','Snow','987654321','VISA',' ',0);
|
||||
INSERT INTO user_data VALUES (101,'Joe','Snow','2234200065411','MC',' ',0);
|
||||
INSERT INTO user_data VALUES (102,'John','Smith','2435600002222','MC',' ',0);
|
||||
INSERT INTO user_data VALUES (102,'John','Smith','4352209902222','AMEX',' ',0);
|
||||
INSERT INTO user_data VALUES (103,'Jane','Plane','123456789','MC',' ',0);
|
||||
INSERT INTO user_data VALUES (103,'Jane','Plane','333498703333','AMEX',' ',0);
|
||||
INSERT INTO user_data VALUES (10312,'Jolly','Hershey','176896789','MC',' ',0);
|
||||
INSERT INTO user_data VALUES (10312,'Jolly','Hershey','333300003333','AMEX',' ',0);
|
||||
INSERT INTO user_data VALUES (10323,'Grumpy','youaretheweakestlink','673834489','MC',' ',0);
|
||||
INSERT INTO user_data VALUES (10323,'Grumpy','youaretheweakestlink','33413003333','AMEX',' ',0);
|
||||
INSERT INTO user_data VALUES (15603,'Peter','Sand','123609789','MC',' ',0);
|
||||
INSERT INTO user_data VALUES (15603,'Peter','Sand','338893453333','AMEX',' ',0);
|
||||
INSERT INTO user_data VALUES (15613,'Joesph','Something','33843453533','AMEX',' ',0);
|
||||
INSERT INTO user_data VALUES (15837,'Chaos','Monkey','32849386533','CM',' ',0);
|
||||
INSERT INTO user_data VALUES (19204,'Mr','Goat','33812953533','VISA',' ',0);
|
@ -0,0 +1,10 @@
|
||||
CREATE TABLE salaries(
|
||||
userid varchar(50),
|
||||
salary int
|
||||
);
|
||||
|
||||
INSERT INTO salaries VALUES ('jsmith', 20000);
|
||||
INSERT INTO salaries VALUES ('lsmith', 45000);
|
||||
INSERT INTO salaries VALUES ('wgoat', 100000);
|
||||
INSERT INTO salaries VALUES ('rjones', 777777);
|
||||
INSERT INTO salaries VALUES ('manderson', 65000);
|
@ -0,0 +1,14 @@
|
||||
CREATE TABLE user_data_tan (
|
||||
userid int not null,
|
||||
first_name varchar(20),
|
||||
last_name varchar(20),
|
||||
cc_number varchar(30),
|
||||
cc_type varchar(10),
|
||||
cookie varchar(20),
|
||||
login_count int,
|
||||
password varchar(20)
|
||||
);
|
||||
|
||||
INSERT INTO user_data_tan VALUES (101,'Joe','Snow','987654321','VISA',' ',0, 'banana');
|
||||
INSERT INTO user_data_tan VALUES (102,'Jane','Plane','74589864','MC',' ',0, 'tarzan');
|
||||
INSERT INTO user_data_tan VALUES (103,'Jack','Sparrow','68659365','MC',' ',0, 'sniffy');
|
@ -0,0 +1,10 @@
|
||||
CREATE TABLE sql_challenge_users(
|
||||
userid varchar(250),
|
||||
email varchar(30),
|
||||
password varchar(30)
|
||||
);
|
||||
|
||||
INSERT INTO sql_challenge_users VALUES ('larry', 'larry@webgoat.org', 'larryknows');
|
||||
INSERT INTO sql_challenge_users VALUES ('tom', 'tom@webgoat.org', 'thisisasecretfortomonly');
|
||||
INSERT INTO sql_challenge_users VALUES ('alice', 'alice@webgoat.org', 'rt*(KJ()LP())$#**');
|
||||
INSERT INTO sql_challenge_users VALUES ('eve', 'eve@webgoat.org', '**********');
|
@ -0,0 +1,12 @@
|
||||
CREATE TABLE user_system_data(
|
||||
userid int not null primary key,
|
||||
user_name varchar(12),
|
||||
password varchar(10),
|
||||
cookie varchar(30)
|
||||
);
|
||||
|
||||
INSERT INTO user_system_data VALUES (101,'jsnow','passwd1', '');
|
||||
INSERT INTO user_system_data VALUES (102,'jdoe','passwd2', '');
|
||||
INSERT INTO user_system_data VALUES (103,'jplane','passwd3', '');
|
||||
INSERT INTO user_system_data VALUES (104,'jeff','jeff', '');
|
||||
INSERT INTO user_system_data VALUES (105,'dave','passW0rD', '');
|
@ -0,0 +1,20 @@
|
||||
CREATE TABLE employees(
|
||||
userid varchar(6) not null primary key,
|
||||
first_name varchar(20),
|
||||
last_name varchar(20),
|
||||
department varchar(20),
|
||||
salary int,
|
||||
auth_tan varchar(6)
|
||||
);
|
||||
|
||||
INSERT INTO employees VALUES ('32147','Paulina', 'Travers', 'Accounting', 46000, 'P45JSI');
|
||||
INSERT INTO employees VALUES ('89762','Tobi', 'Barnett', 'Development', 77000, 'TA9LL1');
|
||||
INSERT INTO employees VALUES ('96134','Bob', 'Franco', 'Marketing', 83700, 'LO9S2V');
|
||||
INSERT INTO employees VALUES ('34477','Abraham ', 'Holman', 'Development', 50000, 'UU2ALK');
|
||||
INSERT INTO employees VALUES ('37648','John', 'Smith', 'Marketing', 64350, '3SL99A');
|
||||
|
||||
CREATE TABLE access_log (
|
||||
id int generated always as identity not null primary key,
|
||||
time varchar(50),
|
||||
action varchar(200)
|
||||
);
|
@ -0,0 +1,14 @@
|
||||
CREATE TABLE grant_rights(
|
||||
userid varchar(6) not null primary key,
|
||||
first_name varchar(20),
|
||||
last_name varchar(20),
|
||||
department varchar(20),
|
||||
salary int
|
||||
);
|
||||
|
||||
INSERT INTO grant_rights VALUES ('32147','Paulina', 'Travers', 'Accounting', 46000);
|
||||
INSERT INTO grant_rights VALUES ('89762','Tobi', 'Barnett', 'Development', 77000);
|
||||
INSERT INTO grant_rights VALUES ('96134','Bob', 'Franco', 'Marketing', 83700);
|
||||
INSERT INTO grant_rights VALUES ('34477','Abraham ', 'Holman', 'Development', 50000);
|
||||
INSERT INTO grant_rights VALUES ('37648','John', 'Smith', 'Marketing', 64350);
|
||||
|
@ -0,0 +1,8 @@
|
||||
== Concept
|
||||
|
||||
This lesson describes the more advanced topics for an SQL injection.
|
||||
|
||||
== Goals
|
||||
|
||||
** Combining SQL injection Techniques
|
||||
** Blind SQL injection
|
@ -0,0 +1,6 @@
|
||||
We now explained the basic steps involved in an SQL injection. In this assignment you will need to combine all
|
||||
the things we explained in the SQL lessons.
|
||||
|
||||
Goal: Can you login as Tom?
|
||||
|
||||
Have fun!
|
@ -0,0 +1,28 @@
|
||||
== Parameterized Queries - Java Example
|
||||
[source,java]
|
||||
-------------------------------------------------------
|
||||
public static String loadAccount() {
|
||||
// Parser returns only valid string data
|
||||
String accountID = getParser().getStringParameter(ACCT_ID, "");
|
||||
String data = null;
|
||||
String query = "SELECT first_name, last_name, acct_id, balance FROM user_data WHERE acct_id = ?";
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
PreparedStatement statement = connection.prepareStatement(query)) {
|
||||
statement.setString(1, accountID);
|
||||
ResultSet results = statement.executeQuery();
|
||||
if (results != null && results.first()) {
|
||||
results.last(); // Only one record should be returned for this query
|
||||
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 }
|
||||
}
|
||||
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,13 @@
|
||||
== Input validation alone is not enough!!
|
||||
|
||||
You need to do both, use parametrized queries and validate the input received from the user. On StackOverflow you will
|
||||
see a lot of answers stating that input validation is enough. *However* it only takes you so far before you know
|
||||
the validation is broken, and you have an SQL injection in your application.
|
||||
|
||||
A nice read why it is not enough can be found https://twitter.com/marcan42/status/1238004834806067200?s=21
|
||||
|
||||
Let's repeat one of the previous assignments, the developer fixed the possible SQL injection with filtering, can you
|
||||
spot the weakness in this approach?
|
||||
|
||||
Read about the lesson goal link:start.mvc#lesson/SqlInjectionAdvanced.lesson/2[here].
|
||||
|
@ -0,0 +1,8 @@
|
||||
== Input validation alone is not enough!!
|
||||
|
||||
So the last attempt to validate if the query did not contain any spaces failed, the development team went further
|
||||
into the direction of only performing input validation, can you find out where it went wrong this time?
|
||||
|
||||
Read about the lesson goal link:start.mvc#lesson/SqlInjectionAdvanced.lesson/2[here].
|
||||
|
||||
|
@ -0,0 +1,47 @@
|
||||
== Order by clause
|
||||
|
||||
Question: Does a prepared statement always prevent against an SQL injection?
|
||||
Answer: No it does not
|
||||
|
||||
Let us take a look at the following statement:
|
||||
|
||||
----
|
||||
"SELECT * FROM users ORDER BY " + sortColumName + ";"
|
||||
----
|
||||
|
||||
If we look at the specification of the SQL grammar the definition is as follows:
|
||||
|
||||
----
|
||||
SELECT ...
|
||||
FROM tableList
|
||||
[WHERE Expression]
|
||||
[ORDER BY orderExpression [, ...]]
|
||||
|
||||
orderExpression:
|
||||
{ columnNr | columnAlias | selectExpression }
|
||||
[ASC | DESC]
|
||||
|
||||
selectExpression:
|
||||
{ Expression | COUNT(*) | {
|
||||
COUNT | MIN | MAX | SUM | AVG | SOME | EVERY |
|
||||
VAR_POP | VAR_SAMP | STDDEV_POP | STDDEV_SAMP
|
||||
} ([ALL | DISTINCT][2]] Expression) } [[AS] label]
|
||||
|
||||
Based on HSQLDB
|
||||
----
|
||||
|
||||
This means an `orderExpression` can be a `selectExpression` which can be a function as well, so for example with
|
||||
a `case` statement we might be able to ask the database some questions, like:
|
||||
|
||||
----
|
||||
SELECT * FROM users ORDER BY (CASE WHEN (TRUE) THEN lastname ELSE firstname)
|
||||
----
|
||||
|
||||
So we can substitute any kind of boolean operation in the `when(....)` part. The statement will just work because
|
||||
it is a valid query whether you use a prepared statement or not. An order by clause can by definition contain an
|
||||
expression.
|
||||
|
||||
=== Mitigation
|
||||
|
||||
If you need to provide a sorting column in your web application you should implement a whitelist to validate the value
|
||||
of the `order by` statement. It should always be limited to something like 'first name' or 'last name'.
|
@ -0,0 +1,14 @@
|
||||
== Least Privilege
|
||||
|
||||
=== 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
|
@ -0,0 +1,56 @@
|
||||
== Special Characters
|
||||
|
||||
[source]
|
||||
----
|
||||
/* */ are inline comments
|
||||
-- , # are line comments
|
||||
|
||||
Example: SELECT * FROM users WHERE name = 'admin' -- AND pass = 'pass'
|
||||
----
|
||||
|
||||
|
||||
[source]
|
||||
----
|
||||
; allows query chaining
|
||||
|
||||
Example: SELECT * FROM users; DROP TABLE users;
|
||||
----
|
||||
|
||||
[source]
|
||||
----
|
||||
',+,|| allows string concatenation
|
||||
Char() strings without quotes
|
||||
|
||||
Example: SELECT * FROM users WHERE name = '+char(27) OR 1=1
|
||||
----
|
||||
|
||||
|
||||
== Special Statements
|
||||
|
||||
=== Union
|
||||
|
||||
The Union operator is used, to combine the results of two or more SELECT Statements.
|
||||
|
||||
Rules to keep in mind, when working with a UNION:
|
||||
|
||||
- The number of columns selected in each statement must be the same.
|
||||
- The datatype of the first column in the first SELECT statement, must match the datatype
|
||||
of the first column in the second (third, fourth, ...) SELECT Statement. The Same applies to all other columns.
|
||||
|
||||
[source]
|
||||
------
|
||||
SELECT first_name FROM user_system_data UNION SELECT login_count FROM user_data;
|
||||
------
|
||||
|
||||
The UNION ALL Syntax also allows duplicate Values.
|
||||
|
||||
=== Joins
|
||||
|
||||
The Join operator is used to combine rows from two or more tables, based on a related column
|
||||
|
||||
[source]
|
||||
-----
|
||||
SELECT * FROM user_data INNER JOIN user_data_tan ON user_data.userid=user_data_tan.userid;
|
||||
-----
|
||||
|
||||
For more detailed information about JOINS visit: https://www.w3schools.com/sql/sql_join.asp
|
@ -0,0 +1,31 @@
|
||||
== Try It! Pulling data from other tables
|
||||
|
||||
The input field below is used to get data from a user by their last name. +
|
||||
The table is called 'user_data':
|
||||
|
||||
-------------------------------------------------------
|
||||
CREATE TABLE user_data (userid int not null,
|
||||
first_name varchar(20),
|
||||
last_name varchar(20),
|
||||
cc_number varchar(30),
|
||||
cc_type varchar(10),
|
||||
cookie varchar(20),
|
||||
login_count int);
|
||||
-------------------------------------------------------
|
||||
|
||||
Through experimentation you found that this field is susceptible to SQL injection.
|
||||
Now you want to use that knowledge to get the contents of another table. +
|
||||
The table you want to pull data from is:
|
||||
|
||||
-------------------------------------------------------
|
||||
CREATE TABLE user_system_data (userid int not null primary key,
|
||||
user_name varchar(12),
|
||||
password varchar(10),
|
||||
cookie varchar(30));
|
||||
-------------------------------------------------------
|
||||
|
||||
*6.a)* Retrieve all data from the table +
|
||||
*6.b)* When you have figured it out.... What is Dave's password?
|
||||
|
||||
Note: There are multiple ways to solve this Assignment. One is by using a UNION, the other by appending
|
||||
a new SQl statement. Maybe you can find both of them.
|
@ -0,0 +1,59 @@
|
||||
== Blind SQL injection
|
||||
|
||||
Blind SQL injection is a type of SQL injection attack that asks the database true or false
|
||||
questions and determines the answer based on the application's response. This attack is often used when the web
|
||||
application is configured to show generic error messages, but has not mitigated the code that is vulnerable to SQL
|
||||
injection.
|
||||
|
||||
=== Difference
|
||||
|
||||
Let us first start with the difference between a normal SQL injection and a blind SQL injection. In a normal
|
||||
SQL injection the error messages from the database are displayed and gives enough information to find out how
|
||||
the query is working. Or in the case of a UNION based SQL injection the application does not reflect the information
|
||||
directly on the web page. So in the case where nothing is displayed you will need to start asking the database questions
|
||||
based on a true or false statement. That is why a blind SQL injection is much more difficult to exploit.
|
||||
|
||||
There are several different types of blind SQL injections: content-based and time-based SQL injections.
|
||||
|
||||
|
||||
=== Example
|
||||
|
||||
In this case we are trying to ask the database a boolean question based on a unique id, for example
|
||||
suppose we have the following url: `https://my-shop.com?article=4`
|
||||
On the server side this query will be translated as follows:
|
||||
|
||||
----
|
||||
SELECT * FROM articles WHERE article_id = 4
|
||||
----
|
||||
|
||||
When we want to exploit this we change the url into: `https://shop.example.com?article=4 AND 1=1`
|
||||
This will be translated to:
|
||||
|
||||
----
|
||||
SELECT * FROM articles WHERE article_id = 4 and 1 = 1
|
||||
----
|
||||
|
||||
If the browser will return the same page as it used to when using `https://shop.example.com?article=4` you know the
|
||||
website is vulnerable for a blind SQL injection.
|
||||
If the browser responds with a page not found or something else you know a blind SQL injection might not work.
|
||||
You can now change the SQL query and test for example: `https://shop.example.com?article=4 AND 1=2` which will not return
|
||||
anything because the query returns false.
|
||||
|
||||
How do we actually take advantage of this? Above we only asked the database a trivial question but you can
|
||||
for example also use the following url: `https://shop.example.com?article=4 AND substring(database_version(),1,1) = 2`
|
||||
|
||||
Most of the time you start by finding which type of database is used, based on the type of database you can find
|
||||
the system tables of the database you can enumerate all the tables present in the database. With this information
|
||||
you can start getting information from all the tables and you are able to dump the database.
|
||||
Be aware that this approach might not work if the privileges of the database are setup correctly (meaning the
|
||||
system tables cannot be queried with the user used to connect from the web application to the database).
|
||||
|
||||
|
||||
Another way is called a time-based SQL injection, in this case you will ask the database to wait before returning
|
||||
the result. You might need to use this if you are totally blind. This means there is no difference between the response data.
|
||||
To achieve this kind of SQL injection you could use:
|
||||
|
||||
----
|
||||
article = 4; sleep(10) --
|
||||
----
|
||||
|
@ -0,0 +1,26 @@
|
||||
== Immutable Queries
|
||||
|
||||
These are the best defense against SQL injection. They either do not have data that could get interpreted, or they treat the data as a single entity that is bound to a column without interpretation.
|
||||
|
||||
=== Static Queries
|
||||
|
||||
----
|
||||
String query = "SELECT * FROM products";
|
||||
----
|
||||
|
||||
----
|
||||
String query = "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,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);
|
||||
}
|
||||
|
||||
// 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 ... }
|
||||
----
|
@ -0,0 +1,39 @@
|
||||
== What is SQL?
|
||||
|
||||
SQL is a standardized (ANSI in 1986, ISO in 1987) programming language which is used for managing relational databases and performing various operations on the data in them.
|
||||
|
||||
A database is a collection of data. The data is organized into rows, columns and tables, and indexed to make finding relevant information more efficient.
|
||||
|
||||
Example SQL table containing employee data; the name of the table is 'employees':
|
||||
|
||||
Employees Table
|
||||
|===
|
||||
|userid |first_name |last_name |department |salary |auth_tan |
|
||||
|
||||
|32147|Paulina|Travers|Accounting|$46.000|P45JSI|
|
||||
|89762|Tobi|Barnett|Development|$77.000|TA9LL1|
|
||||
|96134|Bob|Franco|Marketing|$83.700|LO9S2V|
|
||||
|34477|Abraham|Holman|Development|$50.000|UU2ALK|
|
||||
|37648|John|Smith|Marketing|$64.350|3SL99A|
|
||||
|
||||
|===
|
||||
|
||||
A company saves the following employee information in their databases:
|
||||
a unique employee number ('userid'), last name, first name, department, salary and a transaction authentication number ('auth_tan'). Each of these pieces of information is stored in a separate column and each row represents one employee of the company.
|
||||
|
||||
SQL queries can be used to modify a database table and its index structures and add, update and delete rows of data.
|
||||
|
||||
There are three main categories of SQL commands:
|
||||
|
||||
* Data Manipulation Language (DML)
|
||||
* Data Definition Language (DDL)
|
||||
* Data Control Language (DCL)
|
||||
|
||||
Each of these command types can be used by attackers to compromise the confidentiality, integrity, and/or availability of a system. Proceed with the lesson to learn more about the SQL command types and how they relate to protections goals.
|
||||
|
||||
If you are still struggling with SQL and need more information or practice, you can visit http://www.sqlcourse.com/ for free and interactive online training.
|
||||
|
||||
=== It is your turn!
|
||||
Look at the example table.
|
||||
Try to retrieve the department of the employee Bob Franco.
|
||||
Note that you have been granted full administrator privileges in this assignment and can access all data without authentication.
|
@ -0,0 +1,13 @@
|
||||
== Compromising Availability
|
||||
After successfully compromising confidentiality and integrity in the previous lessons, we are now going to compromise the third element of the CIA triad: *availability*.
|
||||
|
||||
There are many different ways to violate availability.
|
||||
If an account is deleted or its password gets changed, the actual owner cannot access this account anymore.
|
||||
Attackers could also try to delete parts of the database, or even drop the whole database, in order to make the data inaccessible.
|
||||
Revoking the access rights of admins or other users is yet another way to compromise availability; this would prevent these users from accessing either specific parts of the database or even the entire database as a whdle.
|
||||
|
||||
=== It is your turn!
|
||||
Now you are the top earner in your company.
|
||||
But do you see that?
|
||||
There seems to be a *access_log* table, where all your actions have been logged to! +
|
||||
Better go and _delete it_ completely before anyone notices.
|
@ -0,0 +1,9 @@
|
||||
== Try It! String SQL injection
|
||||
|
||||
The query in the code builds a dynamic query as seen in the previous example. The query is built by concatenating strings making it susceptible to String SQL injection:
|
||||
|
||||
------------------------------------------------------------
|
||||
"SELECT * FROM user_data WHERE first_name = 'John' AND last_name = '" + lastName + "'";
|
||||
------------------------------------------------------------
|
||||
|
||||
Try using the form below to retrieve all the users from the users table. You should not need to know any specific user name to get the complete list.
|
@ -0,0 +1,11 @@
|
||||
== 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 builds a dynamic query by concatenating a number making it susceptible to Numeric SQL injection:
|
||||
|
||||
--------------------------------------------------
|
||||
"SELECT * FROM user_data WHERE login_count = " + Login_Count + " AND userid = " + User_ID;
|
||||
--------------------------------------------------
|
||||
|
||||
Using the two Input Fields below, try to retrieve all the data from the users table.
|
||||
|
||||
Warning: Only one of these fields is susceptible to SQL Injection. You need to find out which, to successfully retrieve all the data.
|
@ -0,0 +1,25 @@
|
||||
=== Data Manipulation Language (DML)
|
||||
|
||||
As implied by the name, data manipulation language deals with the manipulation of data. Many of the most common SQL statements, including SELECT, INSERT, UPDATE, and DELETE, may be categorized as DML statements. DML statements may be used for requesting records (SELECT), adding records (INSERT), deleting records (DELETE), and modifying existing records (UPDATE).
|
||||
|
||||
If an attacker succeeds in "injecting" DML statements into a SQL database, he can violate the confidentiality (using SELECT statements), integrity (using UPDATE statements), and availability (using DELETE or UPDATE statements) of a system.
|
||||
|
||||
|
||||
* DML commands are used for storing, retrieving, modifying, and deleting data.
|
||||
* SELECT - retrieve data from a database
|
||||
* INSERT - insert data into a database
|
||||
* UPDATE - updates existing data within a database
|
||||
* DELETE - delete records from a database
|
||||
* Example:
|
||||
** Retrieve data:
|
||||
** SELECT phone +
|
||||
FROM employees +
|
||||
WHERE userid = 96134;
|
||||
** This statement retrieves the phone number of the employee who has the userid 96134.
|
||||
|
||||
=== It is your turn!
|
||||
Try to change the department of Tobi Barnett to 'Sales'.
|
||||
Note that you have been granted full administrator privileges in this assignment and can access all data without authentication.
|
||||
|
||||
|
||||
|
@ -0,0 +1,24 @@
|
||||
=== Data Definition Language (DDL)
|
||||
|
||||
Data definition language includes commands for defining data structures. DDL commands are commonly used to define a database's schema. The schema refers to the overall structure or organization of the database and. in SQL databases, includes objects such as tables, indexes, views, relationships, triggers, and more.
|
||||
|
||||
If an attacker successfully "injects" DDL type SQL commands into a database, he can violate the integrity (using ALTER and DROP statements) and availability (using DROP statements) of a system.
|
||||
|
||||
|
||||
* DDL commands are used for creating, modifying, and dropping the structure of database objects.
|
||||
* CREATE - create database objects such as tables and views
|
||||
* ALTER - alters the structure of the existing database
|
||||
* DROP - delete objects from the database
|
||||
* Example:
|
||||
** CREATE TABLE employees( +
|
||||
userid varchar(6) not null primary key, +
|
||||
first_name varchar(20), +
|
||||
last_name varchar(20), +
|
||||
department varchar(20), +
|
||||
salary varchar(10), +
|
||||
auth_tan varchar(6) +
|
||||
);
|
||||
** This statement creates the employees example table given on page 2.
|
||||
|
||||
Now try to modify the schema by adding the column "phone" (varchar(20)) to the table "employees". :
|
||||
|
@ -0,0 +1,14 @@
|
||||
=== Data Control Language (DCL)
|
||||
|
||||
Data control language is used to implement access control logic in a database. DCL can be used to revoke and grant user privileges on database objects such as tables, views, and functions.
|
||||
|
||||
If an attacker successfully "injects" DCL type SQL commands into a database, he can violate the confidentiality (using GRANT commands) and availability (using REVOKE commands) of a system. For example, the attacker could grant himself admin privileges on the database or revoke the privileges of the true administrator.
|
||||
|
||||
|
||||
* DCL commands are used to implement access control on database objects.
|
||||
* GRANT - give a user access privileges on database objects
|
||||
* REVOKE - withdraw user privileges that were previously given using GRANT
|
||||
|
||||
|
||||
Try to grant rights to the table `grant_rights` to user `unauthorized_user`:
|
||||
|
@ -0,0 +1,10 @@
|
||||
== Examples
|
||||
|
||||
SQL injection can be used for far more than reading the data of a single of user. The following are just a few examples of data a hacker could input to a form field (or anywhere user input is accepted) in an attempt to exploit a SQL injection vulnerability:
|
||||
|
||||
* `+Smith' OR '1' = '1+` +
|
||||
results in `+SELECT * FROM users WHERE name = 'Smith' OR TRUE;+` which will return all entries from the users table
|
||||
* `+Smith' OR 1 = 1; --+` +
|
||||
results in `+SELECT * FROM users WHERE name = 'Smith' OR TRUE;--';+` which, like the first example, will also return all entries from the users table
|
||||
* `+Smith'; DROP TABLE users; TRUNCATE audit_log; --+` +
|
||||
chains multiple SQL-Commands in order to both DROP the users table and delete all entries from the audit_log table
|
@ -0,0 +1,29 @@
|
||||
== What is SQL injection?
|
||||
|
||||
SQL injection (also called SQLi) is one of the most common web hacking techniques. *A SQL injection attack consists of insertion or "injection" of malicious code via the SQL query input from the client to the application.* If not dealt with correctly, SQL injection can seriously impact data integrity and security.
|
||||
|
||||
SQL injections can occur when unfiltered data from the client, such as input from a search field, gets into the SQL interpreter of the application itself. If an application fails to either correctly sanitize user input (using prepared statements or similar) or filter the input against special characters, hackers can manipulate the underlying SQL statement to their advantage. +
|
||||
For example, if the input is not filtered for SQL metacharacters like *--* (which comments out the rest of the line) or *;* (which ends a SQL query), SQL injection may result.
|
||||
|
||||
{nbsp} +
|
||||
|
||||
== Example of SQL injection
|
||||
|
||||
For example, consider a web application that allows users to retrieve user information simply by inputting a username into a form field. The input from the user is sent to the server and gets inserted into a SQL query which then is processed by a SQL interpreter.
|
||||
|
||||
The SQL query to retrieve the user information from the database follows: +
|
||||
-------------------------------------------------------
|
||||
"SELECT * FROM users WHERE name = '" + userName + "'";
|
||||
-------------------------------------------------------
|
||||
|
||||
The variable *userName* holds the input from the client and “injects” it into the query. +
|
||||
If the input were Smith the query would then become +
|
||||
-------------------------------------------------------
|
||||
"SELECT * FROM users WHERE name = 'Smith'";
|
||||
-------------------------------------------------------
|
||||
and would retrieve all data for the user with the name Smith.
|
||||
|
||||
{nbsp} +
|
||||
If an attacker inputs data containing characters or strings that have a "special" meaning to the SQL interpreter (such as *;*, *--*, or *'*), and the data is not correctly sanitized or validated, the attacker can modify the intended behavior of the SQL query in order to perform other (malicious) actions on the database.
|
||||
|
||||
Here is an input field. Try typing some SQL in here to better understand how the query changes.
|
@ -0,0 +1,18 @@
|
||||
== Consequences of SQL injection
|
||||
|
||||
=== A successful SQL injection exploit can:
|
||||
* Read and modify sensitive data from the database
|
||||
* Execute administrative 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
|
||||
|
||||
=== 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
|
@ -0,0 +1,22 @@
|
||||
== 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
|
||||
|
||||
=== 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)
|
||||
|
||||
=== Not all databases are equal (SQL Server)
|
||||
* Command shell: `master.dbo.xp_cmdshell 'cmd.exe dir c:'`
|
||||
* Registry commands: `xp_regread`, `xp_regdeletekey`, …
|
@ -0,0 +1,26 @@
|
||||
== Compromising confidentiality with String SQL injection
|
||||
If a system is vulnerable to SQL injections, aspects of that system's CIA triad can be easily compromised _(if you are unfamiliar with the CIA triad, check out the CIA triad lesson in the general category)_.
|
||||
In the following three lessons you will learn how to compromise each aspect of the CIA triad using techniques like _SQL string injections_ or _query chaining_.
|
||||
|
||||
In this lesson we will look at *confidentiality*.
|
||||
Confidentiality can be easily compromised by an attacker using SQL injection; for example, successful SQL injection can allow the attacker to read sensitive data like credit card numbers from a database.
|
||||
|
||||
=== What is String SQL injection?
|
||||
If an application builds SQL queries simply by concatenating user supplied strings to the query, the application is likely very susceptible to String SQL injection. +
|
||||
More specifically, if a user supplied string simply gets concatenated to a SQL query without any sanitization or preparation, then you may be able to modify the query's behavior by simply inserting quotation marks into an input field.
|
||||
For example, you could end the string parameter with quotation marks and input your own SQL after that.
|
||||
|
||||
=== It is your turn!
|
||||
You are an employee named John *Smith* working for a big company.
|
||||
The company has an internal system that allows all employees to see their own internal data such as the department they work in and their salary.
|
||||
|
||||
The system requires the employees to use a unique _authentication TAN_ to view their data. +
|
||||
Your current TAN is *3SL99A*.
|
||||
|
||||
Since you always have the urge to be the most highly paid employee, you want to exploit the system so that instead of viewing your own internal data, _you want to take a look at the data of all your colleagues_ to check their current salaries.
|
||||
|
||||
Use the form below and try to retrieve all employee data from the *employees* table. You should not need to know any specific names or TANs to get the information you need. +
|
||||
You already found out that the query performing your request looks like this:
|
||||
------------------------------------------------------------
|
||||
"SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'";
|
||||
------------------------------------------------------------
|
@ -0,0 +1,18 @@
|
||||
== Compromising Integrity with Query chaining
|
||||
After compromising the confidentiality of data in the previous lesson, this time we are gonna compromise the *integrity*
|
||||
of data by using SQL *query chaining*.
|
||||
|
||||
If a severe enough vulnerability exists, SQL injection may be used to compromise the integrity of any data in the database. Successful SQL injection may allow an attacker to change information that he should not even be
|
||||
able to access.
|
||||
|
||||
=== What is SQL query chaining?
|
||||
Query chaining is exactly what it sounds like. With query chaining, you try to append one or more queries to the end of
|
||||
the actual query. You can do this by using the *;* metacharacter. A *;* marks the end of a SQL statement; it allows one to start another query right after the initial query without the need to even start a new line.
|
||||
|
||||
=== It is your turn!
|
||||
You just found out that Tobi and Bob both seem to earn more money than you!
|
||||
Of course you cannot leave it at that. +
|
||||
Better go and _change your own salary so you are earning the most!_
|
||||
|
||||
|
||||
Remember: Your name is John *Smith* and your current TAN is *3SL99A*.
|
@ -0,0 +1,14 @@
|
||||
== Concept
|
||||
|
||||
This lesson describes what Structured Query Language (SQL) is and how it can be manipulated to perform tasks that were not the original intent of the developer.
|
||||
|
||||
=== Goals
|
||||
|
||||
* The user will have a basic understanding of how SQL works and what it is used for
|
||||
* The user will have a basic understanding of what SQL injection is and how it works
|
||||
* The user will demonstrate knowledge on:
|
||||
** DML, DDL and DCL
|
||||
** String SQL injection
|
||||
** Numeric SQL injection
|
||||
** How SQL injection violates the CIA triad
|
||||
|
@ -0,0 +1,5 @@
|
||||
== Try it! Writing safe code
|
||||
|
||||
You can see some code down below, but the code is incomplete. Complete the code, so that it's no longer vulnerable to a SQL injection! Use the classes and methods you have learned before.
|
||||
|
||||
The code has to retrieve the status of the user based on the name and the mail address of the user. Both the name and the mail are in the string format.
|
@ -0,0 +1,32 @@
|
||||
== Try it! Writing safe code
|
||||
|
||||
Now it is time to write your own code!
|
||||
Your task is to use JDBC to connect to a database and request data from it.
|
||||
|
||||
*Requirements:*
|
||||
|
||||
* connect to a database
|
||||
* perform a query on the database which is immune to SQL injection attacks
|
||||
* your query needs to contain at least one string parameter
|
||||
|
||||
*Some tips before you start:* +
|
||||
For connecting to the database, you can simply assume the constants *DBURL*, *DBUSER* and *DBPW* as given. +
|
||||
The content of your query does not matter, as long as the SQL is valid and meets the requirements. +
|
||||
All the code you write gets inserted into the main method of a Java class with the name "TestClass" that already imports *java.sql.** for you.
|
||||
|
||||
Not creative enough to think of your own query? How about you try to retrieve the data of a user with a specific name from a fictional database table called *users*.
|
||||
|
||||
For example; the following code would compile without any error (but of course does not meet the requirements to complete this lesson).
|
||||
|
||||
[source,java]
|
||||
-------------------------------------------------------
|
||||
try {
|
||||
Connection conn = null;
|
||||
System.out.println(conn); //should output 'null'
|
||||
} catch (Exception e) {
|
||||
System.out.println("Oops. Something went wrong!");
|
||||
}
|
||||
-------------------------------------------------------
|
||||
|
||||
Use your knowledge and write some valid code from scratch in the editor window down below!
|
||||
(if you cannot type there it might help to adjust the size of your browser window once, then it should work):
|
@ -0,0 +1,5 @@
|
||||
In this assignment try to perform an SQL injection through the ORDER BY field.
|
||||
Try to find the ip address of the `webgoat-prd` server, guessing the complete
|
||||
ip address might take too long so we give you the last part: `xxx.130.219.202`
|
||||
|
||||
Note: The submit field of this assignment is *NOT* vulnerable to an SQL injection.
|
@ -0,0 +1 @@
|
||||
Now it is time for a quiz! It is recommended to do all SQL injection lessons before trying the quiz. Answer all questions correctly to complete the assignment.
|
293
src/main/resources/lessons/sqlinjection/html/SqlInjection.html
Normal file
293
src/main/resources/lessons/sqlinjection/html/SqlInjection.html
Normal file
@ -0,0 +1,293 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<link rel="stylesheet" type="text/css" th:href="@{/lesson_css/assignments.css}"/>
|
||||
|
||||
<!--Page 1-->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_introduction_plan.adoc"></div>
|
||||
</div>
|
||||
|
||||
<!--Page 2-->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_introduction_content1.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjection/attack2"
|
||||
autocomplete="off">
|
||||
<table>
|
||||
<tr>
|
||||
<td><label>SQL query</label></td>
|
||||
<td width="100%"><input class="form-control" name="query" value="" type="TEXT" placeholder="SQL query"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button type="SUBMIT">Submit</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Page 3-->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_introduction_content2.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjection/attack3"
|
||||
autocomplete="off">
|
||||
<table>
|
||||
<tr>
|
||||
<td><label>SQL query</label></td>
|
||||
<td width="100%"><input class="form-control" name="query" value="" type="TEXT" placeholder="SQL query"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button type="SUBMIT">Submit</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Page 4-->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_introduction_content3.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjection/attack4"
|
||||
autocomplete="off">
|
||||
<table>
|
||||
<tr>
|
||||
<td><label>SQL query</label></td>
|
||||
<td width="100%"><input class="form-control" name="query" value="" type="TEXT" placeholder="SQL query"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button type="SUBMIT">Submit</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Page 5-->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_introduction_content4.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjection/attack5"
|
||||
autocomplete="off">
|
||||
<table>
|
||||
<tr>
|
||||
<td><label>SQL query</label></td>
|
||||
<td width="100%"><input class="form-control" name="query" value="" type="TEXT" placeholder="SQL query"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button type="SUBMIT">Submit</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Page 6-->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_introduction_content5_before.adoc"></div>
|
||||
<div>
|
||||
<label for="username-preview">Username:</label>
|
||||
<input id="preview-input" type="text" name="username" val=""/>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre>"SELECT * FROM users WHERE name = '<span id="input-preview" style="font-weight: bold;"></span>'";</pre>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready( () => {
|
||||
$("#preview-input").on("keyup", (e) => {
|
||||
$("#input-preview").text(e.target.value);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_introduction_content5_after.adoc"></div>
|
||||
</div>
|
||||
|
||||
<!--Page 7-->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_introduction_content6.adoc"></div>
|
||||
</div>
|
||||
|
||||
<!--Page 8-->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_introduction_content7.adoc"></div>
|
||||
</div>
|
||||
|
||||
<!--Page 9-->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_introduction_content11.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjection/assignment5a">
|
||||
<table>
|
||||
<tr>
|
||||
<td>SELECT * FROM user_data WHERE first_name = 'John' AND last_name = '</td>
|
||||
<td><select name="account">
|
||||
<option>Smith</option>
|
||||
<option>'Smith</option>
|
||||
<option>'</option>
|
||||
<option>'Smith'</option>
|
||||
<option>Smith'</option>
|
||||
</select></td>
|
||||
<td>
|
||||
<select name="operator">
|
||||
<option>or</option>
|
||||
<option>and</option>
|
||||
<option>and not</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<select name="injection">
|
||||
<option>1 = 1</option>
|
||||
<option>1 = 2</option>
|
||||
<option>1' = '2</option>
|
||||
<option>'1' = '1</option>
|
||||
<option>'1' = '2</option>
|
||||
<option>Last_Name = 'Smith</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>'</td>
|
||||
<td><input
|
||||
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_introduction_content12.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjection/assignment5b">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Login_Count:</td>
|
||||
<td><input name="login_count" type="text" required="true"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>User_Id:</td>
|
||||
<td><input name="userid" type="TEXT" required="true"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><input
|
||||
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_introduction_content8.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjection/attack8"
|
||||
autocomplete="off">
|
||||
<table>
|
||||
<tr>
|
||||
<td><label>Employee Name:</label></td>
|
||||
<td><input name="name" value="" type="TEXT" placeholder="Lastname"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>Authentication TAN:</label></td>
|
||||
<td><input name="auth_tan" value="" type="TEXT" placeholder="TAN"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button type="SUBMIT">Get department</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Page 10-->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_introduction_content9.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjection/attack9"
|
||||
autocomplete="off">
|
||||
<table>
|
||||
<tr>
|
||||
<td><label>Employee Name:</label></td>
|
||||
<td><input name="name" value="" type="TEXT" placeholder="Lastname"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>Authentication TAN:</label></td>
|
||||
<td><input name="auth_tan" value="" type="TEXT" placeholder="TAN"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button type="SUBMIT">Get department</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Page 11-->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_introduction_content10.adoc"></div>
|
||||
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjection/attack10"
|
||||
autocomplete="off">
|
||||
<table>
|
||||
<tr>
|
||||
<td><label>Action contains:</label></td>
|
||||
<td><input name="action_string" value="" type="TEXT" placeholder="Enter search string"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button type="SUBMIT">Search logs</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</html>
|
@ -0,0 +1,184 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<link rel="stylesheet" type="text/css" th:href="@{/lesson_css/assignments.css}"/>
|
||||
|
||||
<!-- 1 -->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjectionAdvanced_plan.adoc"></div>
|
||||
</div>
|
||||
|
||||
<!-- 2 -->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_content6.adoc"></div>
|
||||
</div>
|
||||
|
||||
<!-- 3 -->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_content6a.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjectionAdvanced/attack6a">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td><input name="userid_6a" value="" type="TEXT"/></td>
|
||||
<td><input
|
||||
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjectionAdvanced/attack6b">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Password:</td>
|
||||
<td><input name="userid_6b" value="" type="TEXT"/></td>
|
||||
<td><input
|
||||
name="Check Dave's Password:" value="Check Password" type="SUBMIT"/></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4 -->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_content6c.adoc"></div>
|
||||
</div>
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_challenge.adoc"></div>
|
||||
<link rel="stylesheet" type="text/css" th:href="@{/lesson_css/challenge.css}"/>
|
||||
<script th:src="@{/lesson_js/challenge.js}" language="JavaScript"></script>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-login">
|
||||
<div class="panel-heading">
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<a href="#" class="active" id="login-form-link">Login</a>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<a href="#" id="register-form-link">Register</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<form id="login-form" class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjectionAdvanced/challenge_Login"
|
||||
role="form">
|
||||
<div class="form-group">
|
||||
<input type="text" name="username_login" id="username4" tabindex="1"
|
||||
class="form-control" placeholder="Username" value=""/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="password" name="password_login" id="password4" tabindex="2"
|
||||
class="form-control" placeholder="Password"/>
|
||||
</div>
|
||||
<div class="form-group text-center">
|
||||
<input type="checkbox" tabindex="3" class="" name="remember" id="remember"/>
|
||||
<label for="remember"> Remember me</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-sm-offset-3">
|
||||
<input type="submit" name="login-submit" id="login-submit"
|
||||
tabindex="4" class="form-control btn-primary"
|
||||
value="Log In"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="text-center">
|
||||
<a href="#" tabindex="5" class="forgot-password">Forgot
|
||||
Password?</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form id="register-form" class="attack-form" accept-charset="UNKNOWN"
|
||||
method="PUT" name="form"
|
||||
action="/WebGoat/SqlInjectionAdvanced/challenge"
|
||||
style="display: none;" role="form">
|
||||
<div class="form-group">
|
||||
<input type="text" name="username_reg" id="username" tabindex="1"
|
||||
class="form-control" placeholder="Username" value=""/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="email" name="email_reg" id="email" tabindex="1"
|
||||
class="form-control" placeholder="Email Address" value=""/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="password" name="password_reg" id="password" tabindex="2"
|
||||
class="form-control" placeholder="Password"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="password" name="confirm_password_reg" id="confirm-password"
|
||||
tabindex="2" class="form-control" placeholder="Confirm Password"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-sm-offset-3">
|
||||
<input type="submit" name="register-submit" id="register-submit"
|
||||
tabindex="4" class="form-control btn btn-primary"
|
||||
value="Register Now"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<br/>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<span id="quiz_id" data-quiz_id="sql_injection"></span>
|
||||
<link rel="stylesheet" type="text/css" th:href="@{/css/quiz.css}"/>
|
||||
<script th:src="@{/js/quiz.js}" language="JavaScript"></script>
|
||||
<link rel="import" type="application/json" th:href="@{/lesson_js/questions.json}"/>
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_quiz.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<div class="container-fluid">
|
||||
<form id="quiz-form" class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjectionAdvanced/quiz"
|
||||
role="form">
|
||||
<div id="q_container"></div>
|
||||
<br />
|
||||
<input name="Quiz_solutions" value="Submit answers" type="SUBMIT"/>
|
||||
</form>
|
||||
</div>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</html>
|
@ -0,0 +1,197 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<link rel="stylesheet" type="text/css" th:href="@{/lesson_css/assignments.css}"/>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_content7.adoc"></div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_content8.adoc"></div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_content9.adoc"></div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_content10.adoc"></div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_jdbc_completion.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" action="/WebGoat/SqlInjectionMitigations/attack10a">
|
||||
<div>
|
||||
<p>Connection conn = DriverManager.<input type="text" name="field1" id="field1" />(DBURL, DBUSER, DBPW);</p>
|
||||
<p><input type="text" name="field2" id="field2" /> = conn.<input type="text" name="field3" id="field3" />("SELECT status FROM users WHERE name=<input type="text" name="field4" id="field4" /> AND mail=<input type="text" name="field5" id="field5" />");</p>
|
||||
<p><input type="text" name="field6" id="field6" />;</p>
|
||||
<p><input type="text" name="field7" id="field7" />;</p>
|
||||
</div>
|
||||
<div class="input-group" style="margin-top: 10px">
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_jdbc_newcode.adoc"></div>
|
||||
<div class="attack-container" style="border: none !important; height: 100%; min-height: 300px;">
|
||||
<form id="codesubmit" style="height: 100%; min-height: 300px;" class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" action="/WebGoat/SqlInjectionMitigations/attack10b">
|
||||
<div>
|
||||
<div id="editor" style="position: absolute; top: 0; right: 0; bottom: 0; left: 0; height: 300px;" name="editor"></div>
|
||||
<script th:src="@{/js/libs/ace.js}" type="text/javascript" charset="utf-8"></script>
|
||||
<script th:src="@{/lesson_js/assignment10b.js}" type="text/javascript" charset="utf-8"></script>
|
||||
</div>
|
||||
<input type="hidden" name="editor"/>
|
||||
<div class="input-group" style="position: absolute; top: 310px;">
|
||||
<button class="btn btn-primary" type="submit">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
<br />
|
||||
<div class="attack-feedback" style="margin-top: 40px;"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_content11.adoc"></div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_content12.adoc"></div>
|
||||
</div>
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_content12a.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlOnlyInputValidation/attack"
|
||||
enctype="application/json;charset=UTF-8">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td><input name="userid_sql_only_input_validation" value="" type="TEXT"/></td>
|
||||
<td><input
|
||||
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_content12b.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlOnlyInputValidationOnKeywords/attack"
|
||||
enctype="application/json;charset=UTF-8">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td><input name="userid_sql_only_input_validation_on_keywords" value="" type="TEXT"/></td>
|
||||
<td><input
|
||||
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_content13.adoc"></div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_order_by.adoc"></div>
|
||||
<script th:src="@{/lesson_js/assignment13.js}" language="JavaScript"></script>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjectionMitigations/attack12a">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3>List of servers
|
||||
<div class="pull-right">
|
||||
<button id="btn-admin" class="btn btn-default"><span
|
||||
class="glyphicon glyphicon-pencil"></span> Edit
|
||||
</button>
|
||||
</div>
|
||||
</h3>
|
||||
</div>
|
||||
<div id="toolbar-admin" class="panel-body">
|
||||
<div class="btn-toolbar" role="toolbar" aria-label="admin">
|
||||
<div class="btn-group pull-right" role="group">
|
||||
<button id="btn-online" type="button" class="btn btn-success">Online</button>
|
||||
<button id="btn-offline" type="button" class="btn btn-warning">Offline</button>
|
||||
<button id="btn-out-of-order" type="button" class="btn btn-danger">Out Of Order
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-check"></th>
|
||||
<th></th>
|
||||
<th>Hostname <span onclick="getServers('hostname')"><i
|
||||
class="fa fa-fw fa-sort"></i></span>
|
||||
</th>
|
||||
<th>IP <span onclick="getServers('ip')"><i class="fa fa-fw fa-sort"></i></span></th>
|
||||
<th>MAC <span onclick="getServers('mac')"><i class="fa fa-fw fa-sort"></i></span></th>
|
||||
<th>Status <span onclick="getServers('status')"><i class="fa fa-fw fa-sort"></i></span>
|
||||
</th>
|
||||
<th>Description <span onclick="getServers('description')"><i
|
||||
class="fa fa-fw fa-sort"></i></span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="servers">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<br/>
|
||||
</div>
|
||||
</form>
|
||||
<form class="attack-form" method="POST" name="form" action="/WebGoat/SqlInjectionMitigations/attack12a">
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">IP address webgoat-prd server:</div>
|
||||
<input type="text" class="form-control" id="ip" name="ip"
|
||||
placeholder="192.1.0.12"/>
|
||||
</div>
|
||||
<div class="input-group" style="margin-top: 10px">
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/sqlinjection/documentation/SqlInjection_content14.adoc"></div>
|
||||
</div>
|
||||
|
||||
</html>
|
@ -0,0 +1,116 @@
|
||||
#StringSqlInjection.java
|
||||
1.sql.injection.title=SQL Injection (intro)
|
||||
2.sql.advanced.title=SQL Injection (advanced)
|
||||
3.sql.mitigation.title=SQL Injection (mitigation)
|
||||
|
||||
|
||||
SqlInjectionChallenge1=Look at the different response you receive from the server
|
||||
SqlInjectionChallenge2=The vulnerability is on the register form
|
||||
SqlInjectionChallenge3=Use tooling to automate this attack
|
||||
NoResultsMatched=No results matched, try again.
|
||||
ResultsButNotTom=Try To login as Tom!
|
||||
|
||||
sql-injection.2.success=You have succeeded!
|
||||
sql-injection.2.failed=Something went wrong! You got no results, check your SQL Statement and the table above.
|
||||
SqlStringInjectionHint2-1=You want the data from the column with the name department. You know the database name (employees) and you know the first- and lastname of the employee (first_name, last_name).
|
||||
SqlStringInjectionHint2-2=SELECT column FROM tablename WHERE condition;
|
||||
SqlStringInjectionHint2-3=Use ' instead of " when comparing two strings.
|
||||
SqlStringInjectionHint2-4=Pay attention to case sensitivity when comparing two strings.
|
||||
|
||||
SqlStringInjectionHint3-1=Try the UPDATE statement
|
||||
SqlStringInjectionHint3-2=UPDATE table name SET column name=value WHERE condition;
|
||||
|
||||
SqlStringInjectionHint4-1=ALTER TABLE alters the structure of an existing database
|
||||
SqlStringInjectionHint4-2=Do not forget the data type of the new column (e.g. varchar(size) or int(size))
|
||||
SqlStringInjectionHint4-3=ALTER TABLE table name ADD column name data type(size);
|
||||
|
||||
SqlStringInjectionHint5-1=Take a look at how to use a grant statement (WebGoat uses HSQLDB)
|
||||
SqlStringInjectionHint5-2=You can grant to a user or a role.
|
||||
SqlStringInjectionHint5-3=Try to grant 'select' privilege to 'unauthorized_user'.
|
||||
SqlStringInjectionHint5-4=Use 'grant select on <<table>> to <<user>>' to solve the assignment.
|
||||
|
||||
sql-injection.5a.success=You have succeeded: {0}
|
||||
sql-injection.5a.no.results=No results matched. Try Again.
|
||||
SqlStringInjectionHint5a1=Remember that for an successful Sql-Injection the query needs to always evaluate to <span style="font-style: italic">true.
|
||||
|
||||
sql-injection.5b.success=You have succeeded: {0}
|
||||
sql-injection.5b.no.results=No results matched. Try Again.
|
||||
SqlStringInjectionHint5b1=Try to check which of the input fields is susceptible to an injection attack.
|
||||
SqlStringInjectionHint5b2=Insert: <span style="font-style: italic">0 or 1 = 1 into the first input field. The output should tell you if this field is injectable.
|
||||
SqlStringInjectionHint5b3=The first input field is not susceptible to sql injection.
|
||||
SqlStringInjectionHint5b4=You do not need to insert any quotations into your injection-string.
|
||||
|
||||
sql-injection.6a.success=You have succeeded: {0}
|
||||
sql-injection.6a.no.results=No results matched. Try Again.
|
||||
|
||||
sql-injection.advanced.6a.success=You have succeeded: {0}
|
||||
sql-injection.advanced.6a.no.results=No results matched. Try Again.
|
||||
SqlStringInjectionHint-advanced-6a-1=Remember that when using an UNION each SELECT statement within UNION must have the same number of columns.
|
||||
SqlStringInjectionHint-advanced-6a-2=The data type of a column in the first SELECT statement must have a similar data type to that in the second SELECT statement.
|
||||
SqlStringInjectionHint-advanced-6a-3=Your new SQL query must end with a comment. eg: --
|
||||
SqlStringInjectionHint-advanced-6a-4=If a column needs a String you could substitute something like <span style="font-style: italic">'a String' for it. For integers you could substitute a <span style="font-style: italic">1.
|
||||
SqlStringInjectionHint-advanced-6a-5=Try something like: <span style="font-style: italic">Smith' UNION SELECT userid,user_name, password, 'a', 'b', 'c', 1 from user_system_data --
|
||||
|
||||
sql-injection.6b.success=You have succeeded: {0}
|
||||
sql-injection.6b.no.results=No results matched. Try Again.
|
||||
|
||||
sql-injection.8.success=You have succeeded! You successfully compromised the confidentiality of data by viewing internal information that you should not have access to. Well done!
|
||||
sql-injection.8.no.results=No employee found with matching last name. Or maybe your authentication TAN is incorrect?
|
||||
sql-injection.8.one=That is only one account. You want them all! Try again.
|
||||
SqlStringInjectionHint.8.1=The application is taking your input and inserting the values into the variables 'name' and 'auth_tan' of the pre-formed SQL command.
|
||||
SqlStringInjectionHint.8.2=Compound SQL statements can be made by expanding the WHERE clause of the statement with keywords like AND and OR.
|
||||
SqlStringInjectionHint.8.3=Try appending a SQL statement that always resolves to true.
|
||||
SqlStringInjectionHint.8.4=Make sure all quotes (" ' ") are opened and closed properly so the resulting SQL query is syntactically correct.
|
||||
SqlStringInjectionHint.8.5=Try extending the WHERE clause of the statement by adding something like: ' OR '1' = '1.
|
||||
|
||||
sql-injection.9.success=Well done! Now you are earning the most money. And at the same time you successfully compromised the integrity of data by changing the salary!
|
||||
sql-injection.9.one=Still not earning enough! Better try again and change that.
|
||||
SqlStringInjectionHint.9.1=Try to find a way, to chain another query to the end of the existing one.
|
||||
SqlStringInjectionHint.9.2=Use the ; metacharacter to do so.
|
||||
SqlStringInjectionHint.9.3=Make use of DML to change your salary.
|
||||
SqlStringInjectionHint.9.4=Make sure that the resulting query is syntactically correct.
|
||||
SqlStringInjectionHint.9.5=How about something like '; UPDATE employees....
|
||||
|
||||
sql-injection.10.success=Success! You successfully deleted the access_log table and that way compromised the availability of the data.
|
||||
sql-injection.10.entries=There is still evidence of what you did. Better remove the whole table.
|
||||
|
||||
sql-injection.10b.success=You did it! Your code can prevent an SQL injection attack!
|
||||
sql-injection.10b.failed=Something does not seem right with that code. Maybe you should look at an example how to prevent SQL injections with JDBC?
|
||||
sql-injection.10b.no-code=You need to write some code.
|
||||
sql-injection.10b.compiler-errors=Could not compile code:
|
||||
|
||||
SqlStringInjectionHint.10.1=Use the techniques that you have learned before.
|
||||
SqlStringInjectionHint.10.2=The application takes your input and filters for entries that are LIKE it.
|
||||
SqlStringInjectionHint.10.3=Try query chaining to reach the goal.
|
||||
SqlStringInjectionHint.10.4=The DDL allows you to delete (DROP) database tables.
|
||||
SqlStringInjectionHint.10.5=The underlying SQL query looks like that: "SELECT * FROM access_log WHERE action LIKE '%" + action + "%'".
|
||||
SqlStringInjectionHint.10.6=Remember that you can use the -- metacharacter to comment out the rest of the line.
|
||||
|
||||
SqlStringInjectionHint-mitigation-10a-1=First establish a connection, after that you can create a statement.
|
||||
SqlStringInjectionHint-mitigation-10a-2=For every data type there is a method to insert values into a wildcard symbol in a statement.
|
||||
|
||||
SqlStringInjectionHint-mitigation-10b-1=A database connection has to be surrounded by a try-catch block to handle the very common case of an error while establishing the connection.
|
||||
SqlStringInjectionHint-mitigation-10b-2=Remember to use the right kind of statement, so your code is no longer vulnerable for SQL injections.
|
||||
SqlStringInjectionHint-mitigation-10b-3=The wildcard symbol '?' in a prepared statement can be filled with the right kind of method. There exists one for every data type.
|
||||
SqlStringInjectionHint-mitigation-10b-4=Make sure to execute your statement.
|
||||
SqlStringInjectionHint-mitigation-10b-5=View the previous lesson to check back on how you can build set up a connection.
|
||||
|
||||
SqlStringInjectionHint-mitigation-13-1=Try sorting and look at the request
|
||||
SqlStringInjectionHint-mitigation-13-2=Intercept the request and try to specify a different order by
|
||||
SqlStringInjectionHint-mitigation-13-3=Use for example "(case when (true) then hostname else id end)" in the order by and see what happens
|
||||
SqlStringInjectionHint-mitigation-13-4=Use for example "(case when (true) then hostname else id end)" in the order by and see what happens
|
||||
|
||||
SqlInjectionChallengeHint1=The table name is randomized at each start of WebGoat, try to figure out the name first.
|
||||
SqlInjectionChallengeHint2=Find the field which is vulnerable to SQL injection use that to change the password.
|
||||
SqlInjectionChallengeHint3=Change the password through an UPDATE Statement.
|
||||
SqlInjectionChallengeHint4=The vulnerable field is the username field of the register form.
|
||||
|
||||
SqlOnlyInputValidation-failed=Using spaces is not allowed!
|
||||
SqlOnlyInputValidation-1=Spaces are rejected, try to find a way around this restriction
|
||||
SqlOnlyInputValidation-2=Try to use a comment in the query
|
||||
SqlOnlyInputValidation-3=WebGoat uses HSQLDB as a database can you use one of them to make skip the filtering?
|
||||
|
||||
SqlOnlyInputValidationOnKeywords-failed=Use of spaces and/or SQL keywords are not allowed!
|
||||
SqlOnlyInputValidationOnKeywords-1=Spaces are and SQL keywords are rejected, try to find a way around this restriction
|
||||
SqlOnlyInputValidationOnKeywords-2=Try to use a comment in the query
|
||||
SqlOnlyInputValidationOnKeywords-3=WebGoat uses HSQLDB as a database can you use one of them to make skip the filtering?
|
@ -0,0 +1,8 @@
|
||||
#StringSqlInjection.java
|
||||
StringSqlInjectionSecondStage=Da sie nun erfolgreich eine SQL Injection durchgef\u00fchrt haben, versuchen Sie denselben Typ von Angriff auf eine parametrisierte Anfrage. Starten Sie Diese Lektion neu, wenn Sie zur verwundbaren SQL Anfrage gelangen m\u00f6chten.
|
||||
EnterLastName=Geben Sie Ihren Nachnamen ein:
|
||||
NoResultsMatched=Keine Resultate gefunden, versuchen Sie es erneut
|
||||
SqlStringInjectionHint1=The application is taking your input and inserting it at the end of a pre-formed SQL command.
|
||||
SqlStringInjectionHint2=This is the code for the query being built and issued by WebGoat:<br><br> "SELECT * FROM user_data WHERE last_name = "accountName"
|
||||
SqlStringInjectionHint3=Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. Try appending a SQL statement that always resolves to true
|
||||
SqlStringInjectionHint4=Try entering [ smith' OR '1' = '1 ].
|
@ -0,0 +1,8 @@
|
||||
#StringSqlInjection.java
|
||||
StringSqlInjectionSecondStage=Maintenant que vous avez r\u00e9alis\u00e9 une injection SQL avec succ\u00e8s, essayer le m\u00eame type d'attaque sur une requ\u00eate param\u00e9tr\u00e9e. Red\u00e9marrez la le\u00e7on si vous souhaitez revenir \u00e0 la requ\u00eate injectable.
|
||||
EnterLastName=Entrez votre nom :
|
||||
NoResultsMatched=Aucun r\u00e9sultat correspondant. Essayez encore.
|
||||
SqlStringInjectionHint1=L'application r\u00e9cup\u00e8re votre saisie et l'ins\u00e8re \u00e0 la fin d'une commande SQL pr\u00e9-form\u00e9e.
|
||||
SqlStringInjectionHint2=Voici le code de la requ\u00eate assembl\u00e9e et ex\u00e9cut\u00e9e par WebGoat :<br><br> "SELECT * FROM user_data WHERE last_name = "accountName"
|
||||
SqlStringInjectionHint3=Les commandes SQL compos\u00e9es peuvent \u00eatre assembl\u00e9es en associant de multiples conditions au moyen de mots-cl\u00e9 tels que AND et OR. Essayez d'assembler une condition qui sera toujours r\u00e9solue \u00e0 vrai.
|
||||
SqlStringInjectionHint4=Essayez de saisir [ smith' OR '1' = '1 ].
|
@ -0,0 +1,8 @@
|
||||
#StringSqlInjection.java
|
||||
StringSqlInjectionSecondStage=\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u0432\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0443\u0434\u0430\u0447\u043d\u043e \u043f\u0440\u043e\u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c SQL-\u0438\u043d\u044a\u0435\u043a\u0446\u0438\u044e, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0438\u0442\u044c \u044d\u0442\u043e \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c. \u041d\u0430\u0447\u043d\u0438\u0442\u0435 \u0443\u0440\u043e\u043a \u0437\u0430\u043d\u043e\u0432\u043e \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0432\u043d\u043e\u0432\u044c \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0435 \u043f\u043e\u043b\u0435.
|
||||
EnterLastName=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0432\u0430\u0448\u0443 \u0444\u0430\u043c\u0438\u043b\u0438\u044e:
|
||||
NoResultsMatched=\u041d\u0435\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0439. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0441\u043d\u043e\u0432\u0430.
|
||||
SqlStringInjectionHint1=\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u0435\u0440\u0451\u0442 \u0442\u043e \u0447\u0442\u043e \u0432\u044b \u0432\u0432\u043e\u0434\u0438\u0442\u0435 \u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432 \u043a\u043e\u043d\u0435\u0446 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e SQL-\u0437\u0430\u043f\u0440\u043e\u0441\u0430.
|
||||
SqlStringInjectionHint2=\u0412\u043e\u0442 \u043a\u043e\u0434 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f WebGoat`\u043e\u043c:<br><br> "SELECT * FROM user_data WHERE last_name = "accountName"
|
||||
SqlStringInjectionHint3=\u0426\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u044c SQL-\u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0434\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0442\u0430\u043a\u0438\u0445 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432 \u043a\u0430\u043a AND \u0438 OR. \u041f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u043a\u043e\u0435 SQL-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0438\u0441\u0442\u0438\u043d\u0443.
|
||||
SqlStringInjectionHint4=\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0432\u0432\u0435\u0441\u0442\u0438 [ smith' OR '1' = '1 ].
|
19
src/main/resources/lessons/sqlinjection/js/assignment10b.js
Normal file
19
src/main/resources/lessons/sqlinjection/js/assignment10b.js
Normal file
@ -0,0 +1,19 @@
|
||||
$(document).ready( () => {
|
||||
var editor = ace.edit("editor");
|
||||
editor.setTheme("ace/theme/monokai");
|
||||
editor.session.setMode("ace/mode/java");
|
||||
|
||||
editor.getSession().on("change", () => {
|
||||
setTimeout( () => {
|
||||
$("#codesubmit input[name='editor']").val(ace_collect());
|
||||
}, 20);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
function ace_collect() {
|
||||
var editor = ace.edit("editor");
|
||||
var code = editor.getValue();
|
||||
return code;
|
||||
}
|
61
src/main/resources/lessons/sqlinjection/js/assignment13.js
Normal file
61
src/main/resources/lessons/sqlinjection/js/assignment13.js
Normal file
@ -0,0 +1,61 @@
|
||||
$(function () {
|
||||
$('.col-check').hide();
|
||||
$('#btn-admin').on('click', function () {
|
||||
if ($("#toolbar-admin").is(":visible")) {
|
||||
$("#toolbar-admin").hide();
|
||||
$(".col-check").hide();
|
||||
}
|
||||
else {
|
||||
$("#toolbar-admin").show();
|
||||
$(".col-check").show();
|
||||
}
|
||||
});
|
||||
|
||||
$('#btn-online').on('click', function () {
|
||||
$('table tr').filter(':has(:checkbox:checked)').find('td').parent().removeClass().addClass('success');
|
||||
$('table tr').filter(':has(:checkbox:checked)').find('td.status').text('online');
|
||||
});
|
||||
$('#btn-offline').on('click', function () {
|
||||
$('table tr').filter(':has(:checkbox:checked)').find('td').parent().removeClass().addClass('warning');
|
||||
$('table tr').filter(':has(:checkbox:checked)').find('td.status').text('offline');
|
||||
});
|
||||
$('#btn-out-of-order').on('click', function () {
|
||||
$('table tr').filter(':has(:checkbox:checked)').find('td').parent().removeClass().addClass('danger');
|
||||
$('table tr').filter(':has(:checkbox:checked)').find('td.status').text('out of order');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$(document).ready(function () {
|
||||
getServers('id');
|
||||
});
|
||||
|
||||
var html = '<tr class="STATUS">' +
|
||||
'<td class="col-check"><input type="checkbox" class="form-check-input"/></td>' +
|
||||
'<td>HOSTNAME</td>' +
|
||||
'<td>IP</td>' +
|
||||
'<td>MAC</td>' +
|
||||
'<td class="status">ONLINE</td>' +
|
||||
'<td>DESCRIPTION</td>' +
|
||||
'</tr>';
|
||||
|
||||
function getServers(column) {
|
||||
$.get("SqlInjectionMitigations/servers?column=" + column, function (result, status) {
|
||||
$("#servers").empty();
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
var server = html.replace('ID', result[i].id);
|
||||
var status = "success";
|
||||
if (result[i].status === 'offline') {
|
||||
status = "danger";
|
||||
}
|
||||
server = server.replace('ONLINE', status);
|
||||
server = server.replace('STATUS', status);
|
||||
server = server.replace('HOSTNAME', result[i].hostname);
|
||||
server = server.replace('IP', result[i].ip);
|
||||
server = server.replace('MAC', result[i].mac);
|
||||
server = server.replace('DESCRIPTION', result[i].description);
|
||||
$("#servers").append(server);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
18
src/main/resources/lessons/sqlinjection/js/challenge.js
Normal file
18
src/main/resources/lessons/sqlinjection/js/challenge.js
Normal file
@ -0,0 +1,18 @@
|
||||
$(function() {
|
||||
|
||||
$('#login-form-link').click(function(e) {
|
||||
$("#login-form").delay(100).fadeIn(100);
|
||||
$("#register-form").fadeOut(100);
|
||||
$('#register-form-link').removeClass('active');
|
||||
$(this).addClass('active');
|
||||
e.preventDefault();
|
||||
});
|
||||
$('#register-form-link').click(function(e) {
|
||||
$("#register-form").delay(100).fadeIn(100);
|
||||
$("#login-form").fadeOut(100);
|
||||
$('#login-form-link').removeClass('active');
|
||||
$(this).addClass('active');
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
});
|
@ -0,0 +1,43 @@
|
||||
{
|
||||
"questions": [{
|
||||
"text": "What is the difference between a prepared statement and a statement?",
|
||||
"solutions": {
|
||||
"1": "Prepared statements are statements with hard-coded parameters.",
|
||||
"2": "Prepared statements are not stored in the database.",
|
||||
"3": "A statement is faster.",
|
||||
"4": "A statement has got values instead of a prepared statement"
|
||||
}
|
||||
}, {
|
||||
"text": "Which one of the following characters is a placeholder for variables?",
|
||||
"solutions": {
|
||||
"1": "*",
|
||||
"2": "=",
|
||||
"3": "?",
|
||||
"4": "!"
|
||||
}
|
||||
}, {
|
||||
"text": "How can prepared statements be faster than statements?",
|
||||
"solutions": {
|
||||
"1": "They are not static so they can compile better written code than statements.",
|
||||
"2": "Prepared statements are compiled once by the database management system waiting for input and are pre-compiled this way.",
|
||||
"3": "Prepared statements are stored and wait for input it raises performance considerably.",
|
||||
"4": "Oracle optimized prepared statements. Because of the minimal use of the databases resources it is faster."
|
||||
}
|
||||
}, {
|
||||
"text": "How can a prepared statement prevent SQL-Injection?",
|
||||
"solutions": {
|
||||
"1": "Prepared statements have got an inner check to distinguish between input and logical errors.",
|
||||
"2": "Prepared statements use the placeholders to make rules what input is allowed to use.",
|
||||
"3": "Placeholders can prevent that the users input gets attached to the SQL query resulting in a seperation of code and data.",
|
||||
"4": "Prepared statements always read inputs literally and never mixes it with its SQL commands."
|
||||
}
|
||||
}, {
|
||||
"text": "What happens if a person with malicious intent writes into a register form :Robert); DROP TABLE Students;-- that has a prepared statement?",
|
||||
"solutions": {
|
||||
"1": "The table Students and all of its content will be deleted.",
|
||||
"2": "The input deletes all students with the name Robert.",
|
||||
"3": "The database registers 'Robert' and deletes the table afterwards.",
|
||||
"4": "The database registers 'Robert' ); DROP TABLE Students;--'."
|
||||
}
|
||||
}]
|
||||
}
|
Reference in New Issue
Block a user