Classroom Public page

SEC-101 Week 8: OWASP Top 10 II

1,435 words

XML external entities (XXE), broken access control (A01), security misconfiguration (A05), cross-site scripting (XSS). Lab walk (ungraded): XSS variants on OWASP Juice Shop.


Reading (~30 min)

Read the OWASP Broken Access Control category page (owasp.org/Top10/A01_2021-Broken_Access_Control/). Pay attention to the list of common access-control vulnerabilities. Then read the OWASP XSS Prevention Cheat Sheet. The cheat sheet will make more sense after the XSS lecture, so it's fine to re-read it after the lecture.


Lecture outline (~1.5 hr)

Part 1: Broken access control (A01) (25 min)

Access control (authorization enforcement) is the most common web-application vulnerability class as of 2021. It appears in 94% of tested applications in some form.

Insecure Direct Object Reference (IDOR):

An IDOR occurs when the application uses a user-controllable identifier (an account ID, a document ID, a filename) to access a resource, without checking whether the requesting user is authorized to access that specific resource.

Example: A web application exposes a user profile at /api/user/12345. A logged-in user at /api/user/12346 can access another user's profile by changing the URL parameter to 12345, if the server only checks "is the user authenticated" and not "is the user authorized to access user 12345."

The fix: for every API call that accesses a resource, check both:

  1. Is the user authenticated?
  2. Is the authenticated user authorized to access this specific resource?

The check must happen on the server. Client-side checks (hiding the link in the UI, greying out the button) do not stop an attacker who sends the HTTP request directly.

Privilege escalation:

Horizontal privilege escalation: accessing resources belonging to another user at the same privilege level (the IDOR example above).

Vertical privilege escalation: accessing resources or performing actions that require a higher privilege level than the user has. Example: a regular user accessing an admin API endpoint because the server checks "is the user logged in" but not "is the user an admin."

Missing function-level access control:

API endpoints that perform sensitive operations (delete a user, access raw database exports, trigger admin functions) often require a different front-end than the normal user interface. Developers sometimes assume that "users won't know about this endpoint." Security through obscurity fails when the endpoint is discoverable through API documentation, JavaScript source, network traffic analysis, or brute-force URL enumeration.

Part 2: XML External Entities (XXE) (15 min)

XXE is an injection attack specific to XML parsers. XML supports a feature called "external entities" that allows the XML document to reference external resources (files, URLs) by name. A vulnerable XML parser that processes untrusted input may follow external entity references, exposing local files or triggering server-side requests.

Classic XXE payload:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<user><name>&xxe;</name></user>

If the parser processes this and returns the <name> field's value, the response includes the contents of /etc/passwd.

The fix: disable external entity processing in the XML parser. Most modern XML parser libraries have this as a configuration option; the OWASP XXE Prevention Cheat Sheet lists the setting for each major language/library. Because XXE is a parser configuration issue, not an application logic issue, it often appears in applications that use XML only peripherally (configuration file parsing, document upload, SOAP endpoints).

XXE was A04 in the 2017 list and was folded into A05 (Security Misconfiguration) in 2021, because the fix is almost always a parser configuration, not an application design change.

Part 3: Security misconfiguration (A05) (15 min)

Security misconfiguration covers the broad category of failures that result from insecure default settings, missing security hardening, unnecessary features left enabled, or incomplete patching.

Common examples:

  • Default credentials not changed (admin/admin, admin/password on network equipment or web applications)
  • Directory listing enabled on a web server (allows an attacker to browse the file structure)
  • Detailed error messages displayed to users (stack traces, SQL query contents, internal hostnames exposed in error pages)
  • Unnecessary services running on a server (a web server with an FTP daemon and a debug SMTP relay all running and exposed)
  • Cloud storage buckets misconfigured as public (S3, Azure Blob, GCS objects readable by anyone on the internet)
  • Missing security headers (no Content-Security-Policy, no X-Frame-Options, no Strict-Transport-Security)

The pattern: security misconfiguration is often the failure to take an explicit action (change defaults, apply hardening guides, configure headers). Most misconfiguration vulnerabilities are straightforward to find with automated scanning and straightforward to fix. The failure mode is operational: no one checked.

Part 4: Cross-site scripting (XSS) (25 min)

XSS occurs when an attacker's script is delivered to and executed by a victim's browser in the context of a trusted website. The key phrase is "in the context of a trusted website": the victim's browser trusts the website's origin, so the script runs with the same privileges as legitimate site scripts.

Three XSS variants:

Reflected XSS: The attacker crafts a URL with a malicious script in a parameter; the server reflects the parameter value into the response page without sanitization. The victim clicks the link; the script runs in their browser.

Example: a search page that displays "You searched for: [input]" where [input] is not sanitized. A URL like https://example.com/search?q=<script>alert(1)</script> causes the script to run in the victim's browser.

Stored XSS: The malicious script is stored in the application's database (in a comment field, a profile name, a message body) and served to every user who views the page. No crafted URL is needed: the script runs for any user who loads the page.

Stored XSS is generally more dangerous than reflected XSS because it affects all users without requiring them to click a specific link.

DOM-based XSS: The vulnerability is in the client-side JavaScript, not the server response. The page's own JavaScript reads from a location (URL fragment, document.cookie, localStorage) and writes it to the DOM without sanitization. The server response may be perfectly safe; the script embedded in the page creates the vulnerability.

What XSS enables:

  • Session token theft: document.cookie is accessible to scripts (unless the HttpOnly flag is set). A script that exfiltrates document.cookie to an attacker-controlled server gives the attacker the victim's session.
  • Keylogging: a script can intercept keyboard events on the page.
  • Credential phishing: a script can inject a fake login form over the real page.
  • CSRF as XSS payload: a script can make authenticated requests on behalf of the user.

The fix:

Output encoding: HTML-encode all user-controlled content before writing it to the page. The string <script> becomes &lt;script&gt; and is rendered as text by the browser, not executed as code. The encoding must match the context (HTML encoding for HTML content, JavaScript encoding for JavaScript strings, URL encoding for URL parameters).

Content-Security-Policy (CSP) as defense-in-depth: a CSP header instructs the browser to refuse to execute inline scripts or load scripts from unauthorized origins. A strict CSP substantially limits XSS impact even when the output encoding fails.


Lab exercises (~1.5 hr)

Lab walk: XSS on OWASP Juice Shop (ungraded, instructor-led)

Follow along (or work independently) to complete at least two XSS challenges on OWASP Juice Shop: one reflected XSS and one DOM-based XSS. Document in your lab notebook: which input field was vulnerable, what payload was used, and what evidence confirmed the script executed.

Juice Shop should already be running from Lab 5 (Week 6). If not, start it: docker run -p 3000:3000 bkimminich/juice-shop.


Independent practice (~5 hr)

  • Reading (1 hr): Read the OWASP XSS Prevention Cheat Sheet. Focus on the "Context: HTML Body" and "Context: HTML Attribute" sections. The context matters: the same string needs different encoding in different rendering contexts.
  • picoCTF spine (3 hr): Continue in Web Exploitation challenges. Push toward intermediate difficulty if you've completed beginner. Also try one Forensics challenge involving steganography or file-format analysis.
  • Reflection (1 hr): Write the prompts below.

Reflection prompts

  1. An IDOR vulnerability in a healthcare application allows a logged-in patient to access another patient's records by changing an ID number in the URL. The patient portal's UI doesn't show a link to other patients' records, so the development team assumed this was safe. Which Saltzer and Schroeder principle did they violate? What would a correct access-control check look like on the server?

  2. Stored XSS is generally considered more severe than reflected XSS because it does not require the attacker to trick each victim into clicking a link. Describe an attack scenario where stored XSS in a social-network comment section is used to steal session tokens. What would the attacker need to do with the stolen tokens?

  3. The HttpOnly cookie attribute prevents JavaScript from reading the cookie. If the Juice Shop's session cookie has HttpOnly set, can XSS still steal the session? What can XSS still do even when HttpOnly prevents cookie theft?


Week 8 of 14. Next: OWASP Top 10 III (insecure deserialization, components with known vulnerabilities / Log4Shell, logging failures).