hectoday
DocsCoursesChangelog GitHub
DocsCoursesChangelog GitHub

Access Required

Enter your access code to view courses.

Invalid code

← All courses Web Security Fundamentals with @hectoday/http

The Attacker's Mindset

  • Thinking Like an Attacker
  • Project Setup

Injection Attacks

  • SQL Injection
  • SQL Injection: Beyond the Basics
  • Command Injection
  • Header Injection

Cross-Site Scripting (XSS)

  • What Is XSS?
  • Output Encoding
  • Content Security Policy in Practice

Broken Access and Redirects

  • Insecure Direct Object References (IDOR)
  • Open Redirects
  • Server-Side Request Forgery (SSRF)

File and Data Handling

  • Path Traversal
  • Mass Assignment
  • Denial of Service via Input

Putting It All Together

  • Security Testing
  • The OWASP Top 10
  • Capstone: Hardened Notes API

Thinking Like an Attacker

A different way to look at your app

When you build an app, you think about what it should do. When an attacker looks at your app, they think about what it can be made to do.

Every field, every URL parameter, every header, every cookie, every file upload is a question the attacker asks: “What happens if I put something unexpected here?”

Your login form expects an email address. What happens if the attacker types ' OR 1=1 --? Your search bar expects a keyword. What happens if the attacker types <script>alert('hacked')</script>? Your file download expects a filename. What happens if the attacker types ../../../etc/passwd?

This course teaches you to ask these questions yourself, before an attacker does.

The trust boundary

Your app has a boundary between things you control and things you do not. Everything that crosses this boundary from the outside is untrusted input.

Untrusted input includes request bodies, URL parameters, HTTP headers (including cookies), file uploads, data from external APIs, and even data from your own database — because it may have been stored from untrusted input earlier.

That last one surprises people. If a user’s name is stored as <script>alert(1)</script> in your database, it was untrusted input when it went in, and it is still dangerous when it comes out. The database does not sanitize it for you.

Trusted input is limited to code you wrote, environment variables you set, and constants in your source code.

The trust boundary rule: never use untrusted input without validating, encoding, or escaping it first. The specific technique depends on where the input is going (SQL query, HTML template, shell command, file path), and this course covers each one.

How each lesson works

Every vulnerability lesson follows the same structure:

  1. The attack: We build a vulnerable version of a feature and demonstrate the exploit
  2. Why it works: We explain what makes the code vulnerable
  3. The fix: We write the defense, usually a small function
  4. Verification: We try the attack again and confirm it fails

You will attack your own code. This is the most effective way to understand vulnerabilities: if you can exploit it, you understand it.

What this course covers

Injection (Section 2): SQL injection, command injection, header injection. The attacker injects code into a system that interprets it. The fix: separate code from data.

Cross-site scripting (Section 3): Stored, reflected, and DOM-based XSS. The attacker injects JavaScript into your pages. The fix: encode output for its context, and use CSP as a safety net.

Broken access (Section 4): IDOR, open redirects, SSRF. The attacker accesses data or functionality they should not have. The fix: always verify authorization, validate redirect targets, restrict outbound requests.

File and data handling (Section 5): Path traversal, mass assignment, denial of service via input. The fix: validate paths, pick fields explicitly, limit input size.

A user's display name is stored in your database as '<script>alert(1)</script>'. When is this value considered untrusted input?

Project Setup →

© 2026 hectoday. All rights reserved.