Dev Learning Lab

The labs on this site need JavaScript to run. The same content is written out below.

Learn › Security › Web attacks and defenses

Three web attacks

What happens when you trust input as it is

SQL injection, cross-site scripting (XSS), and cross-site request forgery (CSRF) work on different principles. In one, the input becomes part of the SQL. In another, the input runs as a script in another user's browser. In the third, a logged-in user's browser is made to send a request on the attacker's behalf.

Partly checked against real execution · Part of each of the three attacks was checked with SQLite and a browser

Concepts in this lab

SQL injection
An attack in which user input is interpreted as part of a SQL statement, so a query that the attacker intended is executed. It happens when SQL is built by concatenating input values as strings. Parameterized queries with bind variables (PreparedStatement) separate the SQL structure from the values, so input is always treated only as a value, which prevents the attack.
Cross-site scripting (XSS)
An attack in which an attacker injects a malicious script into a web page so that it runs in another user's browser. It happens when a script placed in a post or a comment is output as is. The script can steal the user's cookies or send requests with the user's privileges. The basic defense is to convert special characters (escaping) when you output user input to the page.
Cross-site request forgery (CSRF)
An attack that takes advantage of the fact that a user is logged in: a page made by the attacker causes the user's browser to send an unintended request to the target site. The browser attaches cookies automatically, so the server treats it as a normal request. To block it, require requests to include an unpredictable token issued by the server, or use the SameSite attribute of cookies.
HttpOnly, Secure, and SameSite
Attributes that protect cookies. HttpOnly stops JavaScript from reading the cookie, which prevents the cookie from being stolen by a script injection attack. Secure makes the browser send the cookie only over HTTPS connections. SameSite restricts sending the cookie with requests that start from another site, which reduces CSRF attacks.
Cookie
A small piece of data that a server sends in a response. The browser stores it and automatically sends it back with every request to the same site. HTTP does not remember state between requests, so this data is used to keep information that must carry over, such as a login state. Because it is stored in the user's browser, you must use it on the assumption that the user can read or change its contents.

Try these

Running with the default settings

  1. The attacker types ' OR '1'='1 in the password field. The intent is to close the string early with the single quote and attach a SQL condition after it.
  2. The server concatenated the input into the SQL string as is. The single quote in the input closed the string in the SQL, and the OR '1'='1' after it became part of the SQL syntax.
  3. '1'='1' is always true, so the whole WHERE condition becomes true. A member row is returned, and the server decides that the login succeeded.

Result of this run

Code

// The input is concatenated into a string
String sql = "SELECT * FROM member WHERE email = '" + email
           + "' AND password = '" + password + "'";
ResultSet rs = statement.executeQuery(sql);

Assumptions of this model

All three attacks are textbook examples to show the principle, and they follow the explanations of OWASP and the defenses in the Spring Security documentation. The login code that compares the password directly in SQL is there to explain SQL injection. In practice, passwords are stored as hashes and verified in the application. The comparison covers states with only one defense turned on, but in practice several defenses are layered. For all three attacks, part of the behavior was checked by actually running it. For SQL injection, on a real SQL engine (SQLite), string concatenation returned 1 row and the query with bind variables returned 0 rows. For XSS, in a real browser (Chromium-based), the script in the comment that was printed as is ran and read the cookie, it did not run when the output was escaped, and an HttpOnly cookie was not visible even when the script ran. For CSRF, on a POST submitted automatically from another site, a SameSite=None cookie was attached and a SameSite=Lax cookie was not. A cookie with no SameSite specified was attached right after it was issued, but was not attached after about 2 minutes. CSRF token verification is server-side logic, so it was not run separately.

Previous lab: Method security · Next lab: CORS

Concepts in this lab

What this lab shows

Settings

Code


      
    

Diagram

Run comparison

Try these