diff --git a/labs/lab2/threagile-model-auth.yaml b/labs/lab2/threagile-model-auth.yaml new file mode 100644 index 000000000..f946e606e --- /dev/null +++ b/labs/lab2/threagile-model-auth.yaml @@ -0,0 +1,574 @@ +threagile_version: 1.0.0 + +title: OWASP Juice Shop — Auth Flow Threat Model +date: 2026-06-12 + +author: + name: Marat Diiarov + homepage: https://github.com/Muratich + +management_summary_comment: > + Focused threat model for the authentication and authorization path of a local + OWASP Juice Shop setup. The model covers login, token issuance, protected API + access, admin access, and the backend credential store. + +business_criticality: critical + +business_overview: + description: > + This model focuses on the identity and access path of OWASP Juice Shop in a + local Docker environment. It keeps the architecture intentionally small so + the main spoofing and elevation risks around credentials, JWTs, and admin + access are easy to see and discuss. + + images: [] + +technical_overview: + description: > + A user's web browser connects to the Juice Shop auth endpoints over HTTPS. + Login requests go to the Auth API, which asks a token service to issue and + verify JWTs. Protected API requests and admin requests also carry JWTs in + the Authorization header. Credential checks and session lookups are done + against a user database inside the container trust boundary. + images: [] + +questions: + How are admin clients managed/protected against compromise?: > + Admin access is restricted to requests carrying a valid JWT with admin + privileges. + How are the development clients managed/protected against compromise?: > + Development clients are out of scope for this focused auth-flow model. + How are the build pipeline components managed/protected against compromise?: > + Build pipeline components are out of scope for this focused auth-flow model. + +abuse_cases: + Credential stuffing / brute force: > + An attacker repeatedly tries usernames and passwords until valid credentials + are found. + JWT theft and replay: > + An attacker steals a token and reuses it to impersonate a victim or admin. + Privilege escalation: > + An attacker attempts to use a normal-user session to reach privileged admin + functionality. + Session fixation: > + An attacker tries to force or reuse a session identifier to hijack an account. + +security_requirements: + Strong authentication: > + Login must require real credentials and reject weak or malformed input. + Signed tokens: > + JWTs must be signed and verified on every protected request. + Role checks on admin paths: > + Admin routes must verify the admin role before processing the request. + Encrypted credential lookup: > + Credential checks against the user store must use encrypted transport. + No secrets in telemetry: > + Credentials, session identifiers, and JWTs must never appear in logs or + telemetry. + +tags_available: + - internet + - browser + - container + - auth + - jwt + - admin + - database + - logs + - https + - api + - datastore + - credentials + - signing-key + - primary + - direct + - egress + +# ========================= +# DATA ASSETS +# ========================= +data_assets: + + Credentials: + id: credentials + description: "Username and password entered during login or registration." + usage: business + tags: ["auth"] + origin: user-supplied + owner: End User + quantity: many + confidentiality: strictly-confidential + integrity: critical + availability: operational + justification_cia_rating: > + Credentials are the first target in an account-takeover attack. + + JWT Token: + id: jwt + description: "Signed token issued by the auth service and used on protected routes." + usage: business + tags: ["auth", "jwt"] + origin: application + owner: Juice Shop + quantity: many + confidentiality: confidential + integrity: critical + availability: important + justification_cia_rating: > + JWT integrity and authenticity directly control access decisions. + + User Session State: + id: session-state + description: "Session state associated with the logged-in user." + usage: business + tags: ["auth"] + origin: application + owner: Juice Shop + quantity: many + confidentiality: confidential + integrity: critical + availability: important + justification_cia_rating: > + Session state binds identity to actions; corruption or disclosure is harmful. + + Admin Operation Request: + id: admin-request + description: "Request to perform a privileged administrative action." + usage: business + tags: ["admin"] + origin: application + owner: Juice Shop + quantity: many + confidentiality: restricted + integrity: critical + availability: operational + justification_cia_rating: > + Unauthorized admin requests can lead to full application compromise. + + JWT Signing Key: + id: jwt-signing-key + description: "Secret key used to sign and verify JWTs." + usage: business + tags: ["auth", "jwt"] + origin: application + owner: Juice Shop + quantity: few + confidentiality: strictly-confidential + integrity: critical + availability: important + justification_cia_rating: > + If the signing key is exposed, an attacker can forge valid tokens. + + Audit Event: + id: audit-event + description: "Security event emitted for auth and admin actions." + usage: devops + tags: ["logs"] + origin: application + owner: Juice Shop + quantity: many + confidentiality: restricted + integrity: important + availability: operational + justification_cia_rating: > + Audit events help detection and response, but should remain sanitized. + +# ========================= +# TECHNICAL ASSETS +# ========================= +technical_assets: + + Browser: + id: browser + description: "End-user web browser used to log in and call protected endpoints." + type: external-entity + usage: business + used_as_client_by_human: true + out_of_scope: false + justification_out_of_scope: "Owned and controlled by the end user." + size: component + technology: browser + tags: ["browser"] + internet: true + machine: physical + encryption: none + owner: Customer + confidentiality: internal + integrity: operational + availability: operational + justification_cia_rating: "Browser used by a human to interact with Juice Shop." + multi_tenant: false + redundant: false + custom_developed_parts: false + data_assets_processed: + - credentials + - jwt + - session-state + - admin-request + data_assets_stored: [] + data_formats_accepted: + - json + communication_links: + Browser to Auth API: + target: auth-api + description: "Login and registration traffic travels over HTTPS." + protocol: https + authentication: none + authorization: none + tags: ["primary"] + vpn: false + ip_filtered: false + readonly: false + usage: business + data_assets_sent: + - credentials + data_assets_received: + - jwt + - session-state + Browser to Protected API: + target: protected-api + description: "Browser sends a JWT in the Authorization header for protected requests." + protocol: https + authentication: token + authorization: enduser-identity-propagation + tags: ["primary"] + vpn: false + ip_filtered: false + readonly: false + usage: business + data_assets_sent: + - jwt + - session-state + data_assets_received: + - session-state + - audit-event + Browser to Admin Endpoint: + target: admin-endpoint + description: "Administrative requests use the same JWT but must include admin privileges." + protocol: https + authentication: token + authorization: enduser-identity-propagation + tags: ["primary"] + vpn: false + ip_filtered: false + readonly: false + usage: business + data_assets_sent: + - jwt + - admin-request + data_assets_received: + - admin-request + + Auth API: + id: auth-api + description: "Login and registration endpoint." + type: process + usage: business + used_as_client_by_human: false + out_of_scope: false + justification_out_of_scope: "" + size: service + technology: web-service-rest + tags: ["auth", "https", "container"] + internet: false + machine: container + encryption: none + owner: Juice Shop + confidentiality: internal + integrity: critical + availability: important + justification_cia_rating: "Handles credential submission and token issuance." + multi_tenant: false + redundant: false + custom_developed_parts: true + data_assets_processed: + - credentials + - jwt + - session-state + data_assets_stored: [] + data_formats_accepted: + - json + communication_links: + Auth API to Token Service: + target: token-service + description: "Requests JWT signing and verification over HTTPS." + protocol: https + authentication: token + authorization: technical-user + tags: [] + vpn: false + ip_filtered: false + readonly: false + usage: business + data_assets_sent: + - credentials + - jwt + data_assets_received: + - jwt + Auth API to User DB: + target: user-db + description: "Credential lookup and session retrieval use encrypted transport." + protocol: jdbc + authentication: credentials + authorization: technical-user + tags: [] + vpn: false + ip_filtered: false + readonly: false + usage: business + data_assets_sent: + - credentials + - session-state + data_assets_received: + - credentials + - session-state + + Token Service: + id: token-service + description: "Token signing and verification component." + type: process + usage: business + used_as_client_by_human: false + out_of_scope: false + justification_out_of_scope: "" + size: service + technology: web-service-rest + tags: ["jwt", "auth", "https", "container"] + internet: false + machine: container + encryption: none + owner: Juice Shop + confidentiality: internal + integrity: critical + availability: important + justification_cia_rating: "Protects signing and verification logic for JWTs." + multi_tenant: false + redundant: false + custom_developed_parts: true + data_assets_processed: + - jwt + - session-state + - jwt-signing-key + data_assets_stored: [] + data_formats_accepted: + - json + communication_links: + Token Service to User DB: + target: user-db + description: "Reads and updates credential/session metadata using encrypted transport." + protocol: jdbc + authentication: credentials + authorization: technical-user + tags: [] + vpn: false + ip_filtered: false + readonly: false + usage: business + data_assets_sent: + - session-state + data_assets_received: + - credentials + - session-state + + User DB: + id: user-db + description: "Credential store for user accounts and session state." + type: datastore + usage: business + used_as_client_by_human: false + out_of_scope: false + justification_out_of_scope: "" + size: service + technology: database + tags: ["database"] + internet: false + machine: container + encryption: data-with-symmetric-shared-key + owner: Juice Shop + confidentiality: strictly-confidential + integrity: critical + availability: important + justification_cia_rating: "Holds the secrets used to authenticate users." + multi_tenant: false + redundant: false + custom_developed_parts: false + data_assets_processed: + - credentials + - session-state + data_assets_stored: + - credentials + - session-state + data_formats_accepted: + - file + communication_links: {} + + Protected API: + id: protected-api + description: "General protected API for authenticated users." + type: process + usage: business + used_as_client_by_human: false + out_of_scope: false + justification_out_of_scope: "" + size: service + technology: web-service-rest + tags: ["api", "https", "container"] + internet: false + machine: container + encryption: none + owner: Juice Shop + confidentiality: internal + integrity: critical + availability: important + justification_cia_rating: "Exposes authenticated endpoints and consumes verified JWTs." + multi_tenant: false + redundant: false + custom_developed_parts: true + data_assets_processed: + - jwt + - session-state + - audit-event + data_assets_stored: [] + data_formats_accepted: + - json + communication_links: + Protected API to Token Service: + target: token-service + description: "Verifies every incoming JWT before processing the request." + protocol: https + authentication: token + authorization: technical-user + tags: [] + vpn: false + ip_filtered: false + readonly: false + usage: business + data_assets_sent: + - jwt + data_assets_received: + - jwt + Protected API to User DB: + target: user-db + description: "Uses encrypted transport for session and account lookups." + protocol: jdbc + authentication: credentials + authorization: technical-user + tags: [] + vpn: false + ip_filtered: false + readonly: false + usage: business + data_assets_sent: + - session-state + data_assets_received: + - credentials + - session-state + + Admin Endpoint: + id: admin-endpoint + description: "Administrative endpoint that requires an admin JWT role." + type: process + usage: business + used_as_client_by_human: false + out_of_scope: false + justification_out_of_scope: "" + size: service + technology: web-service-rest + tags: ["admin", "https", "container"] + internet: false + machine: container + encryption: none + owner: Juice Shop + confidentiality: internal + integrity: critical + availability: important + justification_cia_rating: "Exposes privileged management operations." + multi_tenant: false + redundant: false + custom_developed_parts: true + data_assets_processed: + - jwt + - admin-request + - audit-event + data_assets_stored: [] + data_formats_accepted: + - json + communication_links: + Admin Endpoint to Token Service: + target: token-service + description: "Re-verifies the JWT and checks admin privileges before continuing." + protocol: https + authentication: token + authorization: technical-user + tags: [] + vpn: false + ip_filtered: false + readonly: false + usage: business + data_assets_sent: + - jwt + data_assets_received: + - jwt + Admin Endpoint to User DB: + target: user-db + description: "Uses encrypted transport for admin-side account operations." + protocol: jdbc + authentication: credentials + authorization: technical-user + tags: [] + vpn: false + ip_filtered: false + readonly: false + usage: business + data_assets_sent: + - admin-request + data_assets_received: + - credentials + - session-state + +# ========================= +# TRUST BOUNDARIES +# ========================= +trust_boundaries: + + Internet: + id: internet + description: "Untrusted public network (Internet)." + type: network-dedicated-hoster + tags: [] + technical_assets_inside: + - browser + trust_boundaries_nested: + - container + + Container: + id: container + description: "Container runtime boundary for the auth-flow services and data store." + type: network-dedicated-hoster + tags: [] + technical_assets_inside: + - auth-api + - token-service + - protected-api + - admin-endpoint + - user-db + trust_boundaries_nested: [] + +# ========================= +# SHARED RUNTIMES +# ========================= +shared_runtimes: + + Juice Shop Runtime: + id: juice-shop-runtime + description: "Shared runtime for the containerized Juice Shop auth flow." + tags: ["container"] + technical_assets_running: + - auth-api + - token-service + - protected-api + - admin-endpoint + - user-db + +individual_risk_categories: {} +risk_tracking: {} \ No newline at end of file diff --git a/labs/lab2/threagile-model-secure.yaml b/labs/lab2/threagile-model-secure.yaml new file mode 100644 index 000000000..1fc150b58 --- /dev/null +++ b/labs/lab2/threagile-model-secure.yaml @@ -0,0 +1,452 @@ +threagile_version: 1.0.0 + +title: OWASP Juice Shop — Local Lab Threat Model +date: 2025-09-18 + +author: + name: Student Name + homepage: https://example.edu + +management_summary_comment: > + Threat model for a local OWASP Juice Shop setup. Users access the app + either directly via HTTP on port 3000 or through an optional reverse proxy that + terminates TLS and adds security headers. The app runs in a container + and writes data to a host-mounted volume (for database, uploads, logs). + Optional outbound notifications (e.g., a challenge-solution WebHook) can be configured for integrations. + +business_criticality: important # archive, operational, important, critical, mission-critical + +business_overview: + description: > + Training environment for DevSecOps. This model covers a deliberately vulnerable + web application (OWASP Juice Shop) running locally in a Docker container. The focus is on a minimal architecture, STRIDE threat analysis, and actionable mitigations for the identified risks. + + images: + # - dfd.png: Data Flow Diagram (if exported from the tool) + +technical_overview: + description: > + A user’s web browser connects to the Juice Shop application (Node.js/Express server) either directly on **localhost:3000** (HTTP) or via a **reverse proxy** on ports 80/443 (with HTTPS). The Juice Shop server may issue outbound requests to external services (e.g., a configured **WebHook** for solved challenge notifications). All application data (the SQLite database, file uploads, logs) is stored on the host’s filesystem via a mounted volume. Key trust boundaries include the **Internet** (user & external services) → **Host** (local machine/VM) → **Container Network** (isolated app container). + images: [] + +questions: + Do you expose port 3000 beyond localhost?: "" + Do you use a reverse proxy with TLS and security headers?: "" + Are any outbound integrations (webhooks) configured?: "" + Is any sensitive data stored in logs or files?: "" + +abuse_cases: + Credential Stuffing / Brute Force: > + Attackers attempt repeated login attempts to guess credentials or exhaust system resources. + Stored XSS via Product Reviews: > + Malicious scripts are inserted into product reviews, getting stored and executed in other users’ browsers. + SSRF via Outbound Requests: > + Server-side requests (e.g. profile image URL fetch or WebHook callback) are abused to access internal network resources. + +security_requirements: + TLS in transit: Enforce HTTPS for user traffic via a TLS-terminating reverse proxy with strong ciphers and certificate management. + AuthZ on sensitive routes: Implement strict server-side authorization checks (role/permission) on admin or sensitive functionalities. + Rate limiting & lockouts: Apply rate limiting and account lockout policies to mitigate brute-force and automated attacks on authentication and expensive operations. + Secure headers: Add security headers (HSTS, CSP, X-Frame-Options, X-Content-Type-Options, etc.) at the proxy or app to mitigate client-side attacks. + Secrets management: Protect secret keys and credentials (JWT signing keys, OAuth client secrets) – keep them out of code repos and avoid logging them. + +tags_available: + # Relevant technologies and environment tags + - docker + - nodejs + # Data and asset tags + - pii + - auth + - tokens + - logs + - public + - actor + - user + - optional + - proxy + - app + - storage + - volume + - saas + - webhook + # Communication tags + - primary + - direct + - egress + +# ========================= +# DATA ASSETS +# ========================= +data_assets: + + User Accounts: + id: user-accounts + description: "User profile data, credential hashes, emails." + usage: business + tags: ["pii", "auth"] + origin: user-supplied + owner: Lab Owner + quantity: many + confidentiality: confidential + integrity: critical + availability: important + justification_cia_rating: > + Contains personal identifiers and authentication data. High confidentiality is required to protect user privacy, and integrity is critical to prevent account takeovers. + + Orders: + id: orders + description: "Order history, addresses, and payment metadata (no raw card numbers)." + usage: business + tags: ["pii"] + origin: application + owner: Lab Owner + quantity: many + confidentiality: confidential + integrity: important + availability: important + justification_cia_rating: > + Contains users’ personal data and business transaction records. Integrity and confidentiality are important to prevent fraud or privacy breaches. + + Product Catalog: + id: product-catalog + description: "Product information (names, descriptions, prices) available to all users." + usage: business + tags: ["public"] + origin: application + owner: Lab Owner + quantity: many + confidentiality: public + integrity: important + availability: important + justification_cia_rating: > + Product data is intended to be public, but its integrity is important (to avoid defacement or price manipulation that could mislead users). + + Tokens & Sessions: + id: tokens-sessions + description: "Session identifiers, JWTs for authenticated sessions, CSRF tokens." + usage: business + tags: ["auth", "tokens"] + origin: application + owner: Lab Owner + quantity: many + confidentiality: confidential + integrity: important + availability: important + justification_cia_rating: > + If session tokens are compromised, attackers can hijack user sessions. They must be kept confidential and intact; availability is less critical (tokens can be reissued). + + Logs: + id: logs + description: "Application and access logs (may inadvertently contain PII or secrets)." + usage: devops + tags: ["logs"] + origin: application + owner: Lab Owner + quantity: many + confidentiality: internal + integrity: important + availability: important + justification_cia_rating: > + Logs are for internal use (troubleshooting, monitoring). They should not be exposed publicly, and sensitive data should be sanitized to protect confidentiality. + +# ========================= +# TECHNICAL ASSETS +# ========================= +technical_assets: + + User Browser: + id: user-browser + description: "End-user web browser (client)." + type: external-entity + usage: business + used_as_client_by_human: true + out_of_scope: false + justification_out_of_scope: + size: system + technology: browser + tags: ["actor", "user"] + internet: true + machine: virtual + encryption: none + owner: External User + confidentiality: public + integrity: operational + availability: operational + justification_cia_rating: "Client controlled by end user (potentially an attacker)." + multi_tenant: false + redundant: false + custom_developed_parts: false + data_assets_processed: + - tokens-sessions + - product-catalog + data_assets_stored: + - tokens-sessions + data_formats_accepted: + - json + communication_links: + To Reverse Proxy (preferred): + target: reverse-proxy + description: "User browser to reverse proxy (HTTPS on 443)." + protocol: https + authentication: session-id + authorization: enduser-identity-propagation + tags: ["primary"] + vpn: false + ip_filtered: false + readonly: false + usage: business + data_assets_sent: + - tokens-sessions + data_assets_received: + - product-catalog + Direct to App (no proxy): + target: juice-shop + description: "Direct browser access to app is only allowed over HTTPS; no plaintext port 3000 exposure." + protocol: https + authentication: session-id + authorization: enduser-identity-propagation + tags: ["direct"] + vpn: false + ip_filtered: false + readonly: false + usage: business + data_assets_sent: + - tokens-sessions + data_assets_received: + - product-catalog + + Reverse Proxy: + id: reverse-proxy + description: "Optional reverse proxy (e.g., Nginx) for TLS termination and adding security headers." + type: process + usage: business + used_as_client_by_human: false + out_of_scope: false + justification_out_of_scope: + size: application + technology: reverse-proxy + tags: ["optional", "proxy"] + internet: false + machine: virtual + encryption: transparent + owner: Lab Owner + confidentiality: internal + integrity: important + availability: important + justification_cia_rating: "Not exposed to internet directly; improves security of inbound traffic." + multi_tenant: false + redundant: false + custom_developed_parts: false + data_assets_processed: + - product-catalog + - tokens-sessions + data_assets_stored: [] + data_formats_accepted: + - json + communication_links: + To App: + target: juice-shop + description: "Proxy forwarding to app over encrypted backend traffic with mutual service authentication." + protocol: https + authentication: client-certificate + authorization: technical-user + tags: [] + vpn: false + ip_filtered: false + readonly: false + usage: business + data_assets_sent: + - tokens-sessions + data_assets_received: + - product-catalog + + Juice Shop Application: + id: juice-shop + description: "OWASP Juice Shop server (Node.js/Express, v19.0.0)." + type: process + usage: business + used_as_client_by_human: false + out_of_scope: false + justification_out_of_scope: + size: application + technology: web-server + tags: ["app", "nodejs"] + internet: false + machine: container + encryption: none + owner: Lab Owner + confidentiality: internal + integrity: important + availability: important + justification_cia_rating: "In-scope web application (contains all business logic and vulnerabilities by design)." + multi_tenant: false + redundant: false + custom_developed_parts: true + data_assets_processed: + - user-accounts + - orders + - product-catalog + - tokens-sessions + data_assets_stored: + - logs + data_formats_accepted: + - json + communication_links: + To Challenge WebHook: + target: webhook-endpoint + description: "Optional outbound callback (HTTPS POST) to external WebHook when a challenge is solved." + protocol: https + authentication: none + authorization: none + tags: ["egress"] + vpn: false + ip_filtered: false + readonly: false + usage: business + data_assets_sent: + - orders + To Persistent Storage: + target: persistent-storage + description: "Prepared statements / parameterized SQLite queries and sanitized log writes to encrypted host-mounted database storage; no plaintext secrets are written to logs." + protocol: sql-access-protocol-encrypted + authentication: credentials + authorization: technical-user + tags: ["storage"] + vpn: false + ip_filtered: false + readonly: false + usage: business + data_assets_sent: + - user-accounts + - orders + - product-catalog + - logs + data_assets_received: + - user-accounts + - orders + - product-catalog + + Persistent Storage: + id: persistent-storage + description: "Host-mounted encrypted database volume for application data and sanitized logs." + type: datastore + usage: devops + used_as_client_by_human: false + out_of_scope: false + justification_out_of_scope: + size: component + technology: database + tags: ["storage", "volume"] + internet: false + machine: virtual + encryption: data-with-symmetric-shared-key + owner: Lab Owner + confidentiality: internal + integrity: important + availability: important + justification_cia_rating: "Local disk storage for the container – not directly exposed, but if compromised it contains sensitive data (database and logs)." + multi_tenant: false + redundant: false + custom_developed_parts: false + data_assets_processed: [] + data_assets_stored: + - logs + - user-accounts + - orders + - product-catalog + data_formats_accepted: + - file + communication_links: {} + + Webhook Endpoint: + id: webhook-endpoint + description: "External WebHook service (3rd-party, if configured for integrations)." + type: external-entity + usage: business + used_as_client_by_human: false + out_of_scope: true + justification_out_of_scope: "Third-party service to receive notifications (not under our control)." + size: system + technology: web-service-rest + tags: ["saas", "webhook"] + internet: true + machine: virtual + encryption: none + owner: Third-Party + confidentiality: internal + integrity: operational + availability: operational + justification_cia_rating: "External service that receives data (like order or challenge info). Treated as a trusted integration point but could be abused if misconfigured." + multi_tenant: true + redundant: true + custom_developed_parts: false + data_assets_processed: + - orders + data_assets_stored: [] + data_formats_accepted: + - json + communication_links: {} + +# ========================= +# TRUST BOUNDARIES +# ========================= +trust_boundaries: + + Internet: + id: internet + description: "Untrusted public network (Internet)." + type: network-dedicated-hoster + tags: [] + technical_assets_inside: + - user-browser + - webhook-endpoint + trust_boundaries_nested: + - host + + Host: + id: host + description: "Local host machine / VM running the Docker environment." + type: network-dedicated-hoster + tags: [] + technical_assets_inside: + - reverse-proxy + - persistent-storage + trust_boundaries_nested: + - container-network + + Container Network: + id: container-network + description: "Docker container network (isolated internal network for containers)." + type: network-dedicated-hoster + tags: [] + technical_assets_inside: + - juice-shop + trust_boundaries_nested: [] + +# ========================= +# SHARED RUNTIMES +# ========================= +shared_runtimes: + + Docker Host: + id: docker-host + description: "Docker Engine and default bridge network on the host." + tags: ["docker"] + technical_assets_running: + - juice-shop + # If the reverse proxy is containerized, include it: + # - reverse-proxy + +# ========================= +# INDIVIDUAL RISK CATEGORIES (optional) +# ========================= +individual_risk_categories: {} + +# ========================= +# RISK TRACKING (optional) +# ========================= +risk_tracking: {} + +# (Optional diagram layout tweaks can be added here) +#diagram_tweak_edge_layout: spline +#diagram_tweak_layout_left_to_right: true \ No newline at end of file diff --git a/submissions/lab2.md b/submissions/lab2.md new file mode 100644 index 000000000..dd22b7ebf --- /dev/null +++ b/submissions/lab2.md @@ -0,0 +1,97 @@ +# Lab 2: Threat Modeling with Threagile + +## Task 1: Initial Threat Model + +### Risk Distribution by Severity + +| Severity | Count | +| --------- | -----: | +| Critical | 0 | +| High | 0 | +| Elevated | 4 | +| Medium | 14 | +| Low | 5 | +| **Total** | **23** | + +### Five Most Significant Risks + +1. **missing-authentication** — Lack of authentication on the `To App` communication path connecting the `Reverse Proxy` and the `Juice Shop Application`; severity: Elevated; impacts `juice-shop`. +2. **unencrypted-communication** — Unencrypted communication over `Direct to App (no proxy)` between the `User Browser` and the `Juice Shop Application`, including transmission of authentication-related information; severity: Elevated; impacts `user-browser`. +3. **unencrypted-communication** — Unencrypted communication on the `To App` link between the `Reverse Proxy` and the `Juice Shop Application`; severity: Elevated; impacts `reverse-proxy`. +4. **cross-site-scripting** — Cross-Site Scripting vulnerability affecting the `Juice Shop Application`; severity: Elevated; impacts `juice-shop`. +5. **missing-identity-store** — Absence of a modeled identity store within the architecture, associated with the `Reverse Proxy`; severity: Medium; impacts `reverse-proxy`. + +### STRIDE Classification + +* Risk 1: **S/E** — Missing authentication on backend communication enables attackers to imitate trusted proxy traffic and potentially access application functionality without the required trust validation. +* Risk 2: **I/S** — The use of plain HTTP may expose session tokens, allowing attackers to reuse them and impersonate legitimate users. +* Risk 3: **I/T** — Unencrypted traffic between the proxy and application can be intercepted or altered within the host or container environment. +* Risk 4: **T/E** — XSS can modify content executed in the browser and may lead to session hijacking or unauthorized actions. +* Risk 5: **S/R** — Without a defined identity store, the system cannot reliably demonstrate who authenticated or maintain a trustworthy audit trail. + +### Trust Boundary Analysis + +The communication path `User Browser -> Direct to App (no proxy) -> Juice Shop Application` crosses from the untrusted Internet boundary into the containerized application environment. This path is particularly attractive to attackers because it carries authentication and session information directly to the application. If HTTP remains in use, attackers may attempt to intercept or modify tokens before downstream security controls can inspect the request. + +## Task 2: Hardened Variant and Comparison + +### Security Improvements Implemented + +* Updated direct browser-to-application communication from `http` to `https`. +* Replaced unauthenticated `http` communication between the reverse proxy and application with `https`, using `client-certificate` authentication and `technical-user` authorization. +* Retained outbound WebHook communication over `https` and explicitly documented it as an HTTPS POST request. +* Added a dedicated application-to-storage database connection secured with `sql-access-protocol-encrypted`. +* Configured persistent storage as encrypted using `data-with-symmetric-shared-key`. +* Documented the use of prepared statements, parameterized SQLite queries, and sanitized logging practices to prevent plaintext secrets from appearing in logs. +* Clarified that the browser processes and stores session and product information, eliminating model-noise findings related to unnecessary data transfers. + +### Risk Comparison + +| Severity | Baseline | Secure | Δ | +| --------- | -------: | -----: | -----: | +| Critical | 0 | 0 | 0 | +| High | 0 | 0 | 0 | +| Elevated | 4 | 2 | -2 | +| Medium | 14 | 14 | 0 | +| Low | 5 | 1 | -4 | +| **Total** | **23** | **17** | **-6** | + +### Risks Eliminated in the Secure Variant + +1. **missing-authentication** — Resolved by introducing authenticated communication between the reverse proxy and application using `client-certificate` authentication and `technical-user` authorization. +2. **unencrypted-communication** — Resolved by migrating browser and proxy communication to HTTPS and encrypting SQL-based storage access. +3. **unnecessary-data-transfer** — Resolved by explicitly specifying that the browser processes and stores the received session and catalog information. +4. **unnecessary-technical-asset** — Eliminated through the same browser data-asset clarification, meaning the browser is no longer modeled as an unused component. + +### Risks Remaining in the Secure Variant + +1. **cross-site-scripting** — Neither HTTPS nor storage encryption addresses input/output encoding weaknesses in a web application. The Juice Shop application still processes user-controlled input and therefore requires contextual output encoding, CSP, and server-side validation. +2. **sql-nosql-injection** — Although the model documents parameterized queries, Threagile continues to flag database access as a potential risk because the application communicates with a database via a SQL protocol. In practice, this risk would only be considered mitigated after code review and SAST verification confirm consistent use of parameterized queries. +3. **missing-vault** — Encrypting stored data does not provide a dedicated secrets-management solution. JWT signing keys, database credentials, and integration secrets would still require a vault or equivalent secret-storage mechanism. + +### Validation of Results + +No, the total number of risks was not reduced by more than 50%. The count decreased from 23 to 17, representing approximately a 26% reduction. While these security improvements effectively eliminate avoidable authentication and plaintext communication weaknesses, the remaining findings relate to deeper application and platform-level concerns that require code remediation, WAF/CSRF protections, secrets management, CI/CD modeling, and runtime hardening. + +## Bonus Task: Authentication Flow Threat Model + +### Risk Distribution + +| Severity | Count | +| --------- | -----: | +| Critical | 0 | +| High | 0 | +| Elevated | 5 | +| Medium | 19 | +| Low | 4 | +| **Total** | **28** | + +### Three Authentication-Specific Risks Absent from the Baseline Top Five + +1. **sql-nosql-injection** — STRIDE: **T/E** — The query path `Auth API -> Credential Store` could be exploited to manipulate credential lookup logic or bypass authentication mechanisms. Mitigation: enforce parameterized queries for all authentication-related lookups and introduce SAST/DAST testing focused on login and registration workflows. +2. **unguarded-access-from-internet** — STRIDE: **D/E** — The focused model indicates that both the Auth API and Admin API are directly accessible from the browser without a modeled protective layer. Mitigation: place a reverse proxy, WAF, or API gateway in front of these services, apply rate limiting to authentication endpoints, and enforce explicit authorization checks for administrative functions. +3. **missing-authentication-second-factor** — STRIDE: **S/E** — Relying solely on JWT-based access for administrative routes means that stolen credentials or tokens may be sufficient to gain privileged access. Mitigation: require MFA or step-up authentication for administrative operations and use short-lived admin tokens. + +### Reflection + +The focused authentication model revealed feature-specific security concerns that were less visible in the broader architectural model, particularly around database-backed credential validation, administrative JWT usage, and the absence of two-factor authentication for privileged operations. While the baseline model effectively highlights insecure communication channels and major architectural weaknesses, the authentication-focused model provides greater insight into how a seemingly valid token can become a focal point for spoofing and privilege-escalation attacks.