diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 00000000..2b51ab46
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,28 @@
+## Goal
+
+
+## Changes
+
+-
+-
+-
+
+## Testing
+
+- [ ] Application runs locally
+- [ ] Commands executed successfully
+- [ ] Documentation reviewed for accuracy
+
+## Artifacts & Screenshots
+
+- Screenshots:
+ -
+ -
+
+---
+
+### Checklist
+- [ ] PR title is clear and descriptive
+- [ ] Documentation updated (if applicable)
+- [ ] No secrets, credentials, or large temporary files committed
+
diff --git a/labs/lab2/baseline/data-asset-diagram.png b/labs/lab2/baseline/data-asset-diagram.png
new file mode 100644
index 00000000..4457d768
Binary files /dev/null and b/labs/lab2/baseline/data-asset-diagram.png differ
diff --git a/labs/lab2/baseline/data-flow-diagram.png b/labs/lab2/baseline/data-flow-diagram.png
new file mode 100644
index 00000000..a8803816
Binary files /dev/null and b/labs/lab2/baseline/data-flow-diagram.png differ
diff --git a/labs/lab2/baseline/report.pdf b/labs/lab2/baseline/report.pdf
new file mode 100644
index 00000000..369376fe
Binary files /dev/null and b/labs/lab2/baseline/report.pdf differ
diff --git a/labs/lab2/baseline/risks.json b/labs/lab2/baseline/risks.json
new file mode 100644
index 00000000..7e917d5d
--- /dev/null
+++ b/labs/lab2/baseline/risks.json
@@ -0,0 +1,410 @@
+[
+ {
+ "category": "missing-hardening",
+ "risk_status": "unchecked",
+ "severity": 2,
+ "exploitation_likelihood": 3,
+ "exploitation_impact": 1,
+ "title": "Missing Hardening risk at Juice Shop Application",
+ "synthetic_id": "missing-hardening@juice-shop",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "juice-shop",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "",
+ "data_breach_probability": "improbable",
+ "data_breach_technical_assets": [
+ "juice-shop"
+ ]
+ },
+ {
+ "category": "missing-hardening",
+ "risk_status": "unchecked",
+ "severity": 2,
+ "exploitation_likelihood": 3,
+ "exploitation_impact": 1,
+ "title": "Missing Hardening risk at Persistent Storage",
+ "synthetic_id": "missing-hardening@persistent-storage",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "persistent-storage",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "",
+ "data_breach_probability": "improbable",
+ "data_breach_technical_assets": [
+ "persistent-storage"
+ ]
+ },
+ {
+ "category": "missing-build-infrastructure",
+ "risk_status": "unchecked",
+ "severity": 2,
+ "exploitation_likelihood": 1,
+ "exploitation_impact": 2,
+ "title": "Missing Build Infrastructure in the threat model (referencing asset Juice Shop Application as an example)",
+ "synthetic_id": "missing-build-infrastructure@juice-shop",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "juice-shop",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "",
+ "data_breach_probability": "improbable",
+ "data_breach_technical_assets": []
+ },
+ {
+ "category": "server-side-request-forgery",
+ "risk_status": "unchecked",
+ "severity": 2,
+ "exploitation_likelihood": 3,
+ "exploitation_impact": 1,
+ "title": "Server-Side Request Forgery (SSRF) risk at Juice Shop Application server-side web-requesting the target Webhook Endpoint via To Challenge WebHook",
+ "synthetic_id": "server-side-request-forgery@juice-shop@webhook-endpoint@juice-shop>to-challenge-webhook",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "juice-shop",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "juice-shop>to-challenge-webhook",
+ "data_breach_probability": 2,
+ "data_breach_technical_assets": [
+ "juice-shop"
+ ]
+ },
+ {
+ "category": "server-side-request-forgery",
+ "risk_status": "unchecked",
+ "severity": 2,
+ "exploitation_likelihood": 3,
+ "exploitation_impact": 1,
+ "title": "Server-Side Request Forgery (SSRF) risk at Reverse Proxy server-side web-requesting the target Juice Shop Application via To App",
+ "synthetic_id": "server-side-request-forgery@reverse-proxy@juice-shop@reverse-proxy>to-app",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "reverse-proxy",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "reverse-proxy>to-app",
+ "data_breach_probability": 2,
+ "data_breach_technical_assets": [
+ "reverse-proxy"
+ ]
+ },
+ {
+ "category": "unnecessary-data-transfer",
+ "risk_status": "unchecked",
+ "severity": 1,
+ "exploitation_likelihood": 1,
+ "exploitation_impact": 1,
+ "title": "Unnecessary Data Transfer of Tokens & Sessions data at User Browser from/to Juice Shop Application",
+ "synthetic_id": "unnecessary-data-transfer@tokens-sessions@user-browser@juice-shop",
+ "most_relevant_data_asset": "tokens-sessions",
+ "most_relevant_technical_asset": "user-browser",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "",
+ "data_breach_probability": "improbable",
+ "data_breach_technical_assets": [
+ "user-browser"
+ ]
+ },
+ {
+ "category": "unnecessary-data-transfer",
+ "risk_status": "unchecked",
+ "severity": 1,
+ "exploitation_likelihood": 1,
+ "exploitation_impact": 1,
+ "title": "Unnecessary Data Transfer of Tokens & Sessions data at User Browser from/to Reverse Proxy",
+ "synthetic_id": "unnecessary-data-transfer@tokens-sessions@user-browser@reverse-proxy",
+ "most_relevant_data_asset": "tokens-sessions",
+ "most_relevant_technical_asset": "user-browser",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "",
+ "data_breach_probability": "improbable",
+ "data_breach_technical_assets": [
+ "user-browser"
+ ]
+ },
+ {
+ "category": "unnecessary-technical-asset",
+ "risk_status": "unchecked",
+ "severity": 1,
+ "exploitation_likelihood": 1,
+ "exploitation_impact": 1,
+ "title": "Unnecessary Technical Asset named Persistent Storage",
+ "synthetic_id": "unnecessary-technical-asset@persistent-storage",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "persistent-storage",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "",
+ "data_breach_probability": "improbable",
+ "data_breach_technical_assets": [
+ "persistent-storage"
+ ]
+ },
+ {
+ "category": "unnecessary-technical-asset",
+ "risk_status": "unchecked",
+ "severity": 1,
+ "exploitation_likelihood": 1,
+ "exploitation_impact": 1,
+ "title": "Unnecessary Technical Asset named User Browser",
+ "synthetic_id": "unnecessary-technical-asset@user-browser",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "user-browser",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "",
+ "data_breach_probability": "improbable",
+ "data_breach_technical_assets": [
+ "user-browser"
+ ]
+ },
+ {
+ "category": "cross-site-scripting",
+ "risk_status": "unchecked",
+ "severity": 4,
+ "exploitation_likelihood": 3,
+ "exploitation_impact": 2,
+ "title": "Cross-Site Scripting (XSS) risk at Juice Shop Application",
+ "synthetic_id": "cross-site-scripting@juice-shop",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "juice-shop",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "",
+ "data_breach_probability": 2,
+ "data_breach_technical_assets": [
+ "juice-shop"
+ ]
+ },
+ {
+ "category": "cross-site-request-forgery",
+ "risk_status": "unchecked",
+ "severity": 2,
+ "exploitation_likelihood": 4,
+ "exploitation_impact": 1,
+ "title": "Cross-Site Request Forgery (CSRF) risk at Juice Shop Application via Direct to App (no proxy) from User Browser",
+ "synthetic_id": "cross-site-request-forgery@juice-shop@user-browser>direct-to-app-no-proxy",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "juice-shop",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "user-browser>direct-to-app-no-proxy",
+ "data_breach_probability": "improbable",
+ "data_breach_technical_assets": [
+ "juice-shop"
+ ]
+ },
+ {
+ "category": "cross-site-request-forgery",
+ "risk_status": "unchecked",
+ "severity": 2,
+ "exploitation_likelihood": 4,
+ "exploitation_impact": 1,
+ "title": "Cross-Site Request Forgery (CSRF) risk at Juice Shop Application via To App from Reverse Proxy",
+ "synthetic_id": "cross-site-request-forgery@juice-shop@reverse-proxy>to-app",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "juice-shop",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "reverse-proxy>to-app",
+ "data_breach_probability": "improbable",
+ "data_breach_technical_assets": [
+ "juice-shop"
+ ]
+ },
+ {
+ "category": "missing-waf",
+ "risk_status": "unchecked",
+ "severity": 1,
+ "exploitation_likelihood": 1,
+ "exploitation_impact": 1,
+ "title": "Missing Web Application Firewall (WAF) risk at Juice Shop Application",
+ "synthetic_id": "missing-waf@juice-shop",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "juice-shop",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "",
+ "data_breach_probability": "improbable",
+ "data_breach_technical_assets": [
+ "juice-shop"
+ ]
+ },
+ {
+ "category": "unencrypted-communication",
+ "risk_status": "unchecked",
+ "severity": 4,
+ "exploitation_likelihood": 3,
+ "exploitation_impact": 3,
+ "title": "Unencrypted Communication named Direct to App (no proxy) between User Browser and Juice Shop Application transferring authentication data (like credentials, token, session-id, etc.)",
+ "synthetic_id": "unencrypted-communication@user-browser>direct-to-app-no-proxy@user-browser@juice-shop",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "user-browser",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "user-browser>direct-to-app-no-proxy",
+ "data_breach_probability": 2,
+ "data_breach_technical_assets": [
+ "juice-shop"
+ ]
+ },
+ {
+ "category": "unencrypted-communication",
+ "risk_status": "unchecked",
+ "severity": 4,
+ "exploitation_likelihood": 3,
+ "exploitation_impact": 2,
+ "title": "Unencrypted Communication named To App between Reverse Proxy and Juice Shop Application",
+ "synthetic_id": "unencrypted-communication@reverse-proxy>to-app@reverse-proxy@juice-shop",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "reverse-proxy",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "reverse-proxy>to-app",
+ "data_breach_probability": 2,
+ "data_breach_technical_assets": [
+ "juice-shop"
+ ]
+ },
+ {
+ "category": "missing-authentication",
+ "risk_status": "unchecked",
+ "severity": 4,
+ "exploitation_likelihood": 3,
+ "exploitation_impact": 2,
+ "title": "Missing Authentication covering communication link To App from Reverse Proxy to Juice Shop Application",
+ "synthetic_id": "missing-authentication@reverse-proxy>to-app@reverse-proxy@juice-shop",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "juice-shop",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "reverse-proxy>to-app",
+ "data_breach_probability": 2,
+ "data_breach_technical_assets": [
+ "juice-shop"
+ ]
+ },
+ {
+ "category": "missing-authentication-second-factor",
+ "risk_status": "unchecked",
+ "severity": 2,
+ "exploitation_likelihood": 1,
+ "exploitation_impact": 2,
+ "title": "Missing Two-Factor Authentication covering communication link Direct to App (no proxy) from User Browser to Juice Shop Application",
+ "synthetic_id": "missing-authentication-second-factor@user-browser>direct-to-app-no-proxy@user-browser@juice-shop",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "juice-shop",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "user-browser>direct-to-app-no-proxy",
+ "data_breach_probability": 2,
+ "data_breach_technical_assets": [
+ "juice-shop"
+ ]
+ },
+ {
+ "category": "missing-authentication-second-factor",
+ "risk_status": "unchecked",
+ "severity": 2,
+ "exploitation_likelihood": 1,
+ "exploitation_impact": 2,
+ "title": "Missing Two-Factor Authentication covering communication link To App from User Browser forwarded via Reverse Proxy to Juice Shop Application",
+ "synthetic_id": "missing-authentication-second-factor@reverse-proxy>to-app@reverse-proxy@juice-shop",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "juice-shop",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "reverse-proxy>to-app",
+ "data_breach_probability": 2,
+ "data_breach_technical_assets": [
+ "juice-shop"
+ ]
+ },
+ {
+ "category": "container-baseimage-backdooring",
+ "risk_status": "unchecked",
+ "severity": 2,
+ "exploitation_likelihood": 1,
+ "exploitation_impact": 2,
+ "title": "Container Base Image Backdooring risk at Juice Shop Application",
+ "synthetic_id": "container-baseimage-backdooring@juice-shop",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "juice-shop",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "",
+ "data_breach_probability": "probable",
+ "data_breach_technical_assets": [
+ "juice-shop"
+ ]
+ },
+ {
+ "category": "unencrypted-asset",
+ "risk_status": "unchecked",
+ "severity": 2,
+ "exploitation_likelihood": 1,
+ "exploitation_impact": 2,
+ "title": "Unencrypted Technical Asset named Juice Shop Application",
+ "synthetic_id": "unencrypted-asset@juice-shop",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "juice-shop",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "",
+ "data_breach_probability": "improbable",
+ "data_breach_technical_assets": [
+ "juice-shop"
+ ]
+ },
+ {
+ "category": "unencrypted-asset",
+ "risk_status": "unchecked",
+ "severity": 2,
+ "exploitation_likelihood": 1,
+ "exploitation_impact": 2,
+ "title": "Unencrypted Technical Asset named Persistent Storage",
+ "synthetic_id": "unencrypted-asset@persistent-storage",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "persistent-storage",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "",
+ "data_breach_probability": "improbable",
+ "data_breach_technical_assets": [
+ "persistent-storage"
+ ]
+ },
+ {
+ "category": "missing-vault",
+ "risk_status": "unchecked",
+ "severity": 2,
+ "exploitation_likelihood": 1,
+ "exploitation_impact": 2,
+ "title": "Missing Vault (Secret Storage) in the threat model (referencing asset Juice Shop Application as an example)",
+ "synthetic_id": "missing-vault@juice-shop",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "juice-shop",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "",
+ "data_breach_probability": "improbable",
+ "data_breach_technical_assets": []
+ },
+ {
+ "category": "missing-identity-store",
+ "risk_status": "unchecked",
+ "severity": 2,
+ "exploitation_likelihood": 1,
+ "exploitation_impact": 2,
+ "title": "Missing Identity Store in the threat model (referencing asset Reverse Proxy as an example)",
+ "synthetic_id": "missing-identity-store@reverse-proxy",
+ "most_relevant_data_asset": "",
+ "most_relevant_technical_asset": "reverse-proxy",
+ "most_relevant_trust_boundary": "",
+ "most_relevant_shared_runtime": "",
+ "most_relevant_communication_link": "",
+ "data_breach_probability": "improbable",
+ "data_breach_technical_assets": []
+ }
+]
diff --git a/labs/lab2/baseline/stats.json b/labs/lab2/baseline/stats.json
new file mode 100644
index 00000000..88cd78be
--- /dev/null
+++ b/labs/lab2/baseline/stats.json
@@ -0,0 +1 @@
+{"risks":{"critical":{"accepted":0,"false-positive":0,"in-discussion":0,"in-progress":0,"mitigated":0,"unchecked":0},"elevated":{"accepted":0,"false-positive":0,"in-discussion":0,"in-progress":0,"mitigated":0,"unchecked":4},"high":{"accepted":0,"false-positive":0,"in-discussion":0,"in-progress":0,"mitigated":0,"unchecked":0},"low":{"accepted":0,"false-positive":0,"in-discussion":0,"in-progress":0,"mitigated":0,"unchecked":5},"medium":{"accepted":0,"false-positive":0,"in-discussion":0,"in-progress":0,"mitigated":0,"unchecked":14}}}
\ No newline at end of file
diff --git a/labs/lab2/baseline/technical-assets.json b/labs/lab2/baseline/technical-assets.json
new file mode 100644
index 00000000..45457f1e
--- /dev/null
+++ b/labs/lab2/baseline/technical-assets.json
@@ -0,0 +1 @@
+{"juice-shop":{"Id":"juice-shop","Title":"Juice Shop Application","Description":"OWASP Juice Shop server (Node.js/Express, v19.0.0).","Usage":0,"Type":1,"Size":2,"Technology":6,"Machine":2,"Internet":false,"MultiTenant":false,"Redundant":false,"CustomDevelopedParts":true,"OutOfScope":false,"UsedAsClientByHuman":false,"Encryption":0,"JustificationOutOfScope":"","Owner":"Lab Owner","Confidentiality":1,"Integrity":2,"Availability":2,"JustificationCiaRating":"In-scope web application (contains all business logic and vulnerabilities by design).","Tags":["app","nodejs"],"DataAssetsProcessed":["user-accounts","orders","product-catalog","tokens-sessions"],"DataAssetsStored":["logs"],"DataFormatsAccepted":[0],"CommunicationLinks":[{"Id":"juice-shop\u003eto-challenge-webhook","SourceId":"juice-shop","TargetId":"webhook-endpoint","Title":"To Challenge WebHook","Description":"Optional outbound callback (HTTP POST) to external WebHook when a challenge is solved.","Protocol":2,"Tags":["egress"],"VPN":false,"IpFiltered":false,"Readonly":false,"Authentication":0,"Authorization":0,"Usage":0,"DataAssetsSent":["orders"],"DataAssetsReceived":null,"DiagramTweakWeight":1,"DiagramTweakConstraint":true}],"DiagramTweakOrder":0,"RAA":70.02881844380403},"persistent-storage":{"Id":"persistent-storage","Title":"Persistent Storage","Description":"Host-mounted volume for database, file uploads, and logs.","Usage":1,"Type":2,"Size":3,"Technology":10,"Machine":1,"Internet":false,"MultiTenant":false,"Redundant":false,"CustomDevelopedParts":false,"OutOfScope":false,"UsedAsClientByHuman":false,"Encryption":0,"JustificationOutOfScope":"","Owner":"Lab Owner","Confidentiality":1,"Integrity":2,"Availability":2,"JustificationCiaRating":"Local disk storage for the container – not directly exposed, but if compromised it contains sensitive data (database and logs).","Tags":["storage","volume"],"DataAssetsProcessed":[],"DataAssetsStored":["logs","user-accounts","orders","product-catalog"],"DataFormatsAccepted":[3],"CommunicationLinks":[],"DiagramTweakOrder":0,"RAA":100},"reverse-proxy":{"Id":"reverse-proxy","Title":"Reverse Proxy","Description":"Optional reverse proxy (e.g., Nginx) for TLS termination and adding security headers.","Usage":0,"Type":1,"Size":2,"Technology":20,"Machine":1,"Internet":false,"MultiTenant":false,"Redundant":false,"CustomDevelopedParts":false,"OutOfScope":false,"UsedAsClientByHuman":false,"Encryption":1,"JustificationOutOfScope":"","Owner":"Lab Owner","Confidentiality":1,"Integrity":2,"Availability":2,"JustificationCiaRating":"Not exposed to internet directly; improves security of inbound traffic.","Tags":["optional","proxy"],"DataAssetsProcessed":["product-catalog","tokens-sessions"],"DataAssetsStored":[],"DataFormatsAccepted":[0],"CommunicationLinks":[{"Id":"reverse-proxy\u003eto-app","SourceId":"reverse-proxy","TargetId":"juice-shop","Title":"To App","Description":"Proxy forwarding to app (HTTP on 3000 internally).","Protocol":1,"Tags":[],"VPN":false,"IpFiltered":false,"Readonly":false,"Authentication":0,"Authorization":0,"Usage":0,"DataAssetsSent":["tokens-sessions"],"DataAssetsReceived":["product-catalog"],"DiagramTweakWeight":1,"DiagramTweakConstraint":true}],"DiagramTweakOrder":0,"RAA":9.623538157950035},"user-browser":{"Id":"user-browser","Title":"User Browser","Description":"End-user web browser (client).","Usage":0,"Type":0,"Size":0,"Technology":2,"Machine":1,"Internet":true,"MultiTenant":false,"Redundant":false,"CustomDevelopedParts":false,"OutOfScope":false,"UsedAsClientByHuman":true,"Encryption":0,"JustificationOutOfScope":"","Owner":"External User","Confidentiality":0,"Integrity":1,"Availability":1,"JustificationCiaRating":"Client controlled by end user (potentially an attacker).","Tags":["actor","user"],"DataAssetsProcessed":[],"DataAssetsStored":[],"DataFormatsAccepted":[0],"CommunicationLinks":[{"Id":"user-browser\u003eto-reverse-proxy-preferred","SourceId":"user-browser","TargetId":"reverse-proxy","Title":"To Reverse Proxy (preferred)","Description":"User browser to reverse proxy (HTTPS on 443).","Protocol":2,"Tags":["primary"],"VPN":false,"IpFiltered":false,"Readonly":false,"Authentication":2,"Authorization":2,"Usage":0,"DataAssetsSent":["tokens-sessions"],"DataAssetsReceived":["product-catalog"],"DiagramTweakWeight":1,"DiagramTweakConstraint":true},{"Id":"user-browser\u003edirect-to-app-no-proxy","SourceId":"user-browser","TargetId":"juice-shop","Title":"Direct to App (no proxy)","Description":"Direct browser access to app (HTTP on 3000).","Protocol":1,"Tags":["direct"],"VPN":false,"IpFiltered":false,"Readonly":false,"Authentication":2,"Authorization":2,"Usage":0,"DataAssetsSent":["tokens-sessions"],"DataAssetsReceived":["product-catalog"],"DiagramTweakWeight":1,"DiagramTweakConstraint":true}],"DiagramTweakOrder":0,"RAA":25.859639506459924},"webhook-endpoint":{"Id":"webhook-endpoint","Title":"Webhook Endpoint","Description":"External WebHook service (3rd-party, if configured for integrations).","Usage":0,"Type":0,"Size":0,"Technology":14,"Machine":1,"Internet":true,"MultiTenant":true,"Redundant":true,"CustomDevelopedParts":false,"OutOfScope":true,"UsedAsClientByHuman":false,"Encryption":0,"JustificationOutOfScope":"Third-party service to receive notifications (not under our control).","Owner":"Third-Party","Confidentiality":1,"Integrity":1,"Availability":1,"JustificationCiaRating":"External service that receives data (like order or challenge info). Treated as a trusted integration point but could be abused if misconfigured.","Tags":["saas","webhook"],"DataAssetsProcessed":["orders"],"DataAssetsStored":[],"DataFormatsAccepted":[0],"CommunicationLinks":[],"DiagramTweakOrder":0,"RAA":1}}
\ No newline at end of file
diff --git a/labs/lab2/secure/data-asset-diagram.png b/labs/lab2/secure/data-asset-diagram.png
new file mode 100644
index 00000000..aacf4016
Binary files /dev/null and b/labs/lab2/secure/data-asset-diagram.png differ
diff --git a/labs/lab2/secure/data-flow-diagram.png b/labs/lab2/secure/data-flow-diagram.png
new file mode 100644
index 00000000..5ead09e2
Binary files /dev/null and b/labs/lab2/secure/data-flow-diagram.png differ
diff --git a/labs/lab2/secure/report.pdf b/labs/lab2/secure/report.pdf
new file mode 100644
index 00000000..66ddc3f2
Binary files /dev/null and b/labs/lab2/secure/report.pdf differ
diff --git a/labs/lab2/secure/risks.json b/labs/lab2/secure/risks.json
new file mode 100644
index 00000000..0988f32e
--- /dev/null
+++ b/labs/lab2/secure/risks.json
@@ -0,0 +1 @@
+[{"category":"missing-authentication","risk_status":"unchecked","severity":"elevated","exploitation_likelihood":"likely","exploitation_impact":"medium","title":"\u003cb\u003eMissing Authentication\u003c/b\u003e covering communication link \u003cb\u003eTo App\u003c/b\u003e from \u003cb\u003eReverse Proxy\u003c/b\u003e to \u003cb\u003eJuice Shop Application\u003c/b\u003e","synthetic_id":"missing-authentication@reverse-proxy\u003eto-app@reverse-proxy@juice-shop","most_relevant_data_asset":"","most_relevant_technical_asset":"juice-shop","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"reverse-proxy\u003eto-app","data_breach_probability":"possible","data_breach_technical_assets":["juice-shop"]},{"category":"unnecessary-data-transfer","risk_status":"unchecked","severity":"low","exploitation_likelihood":"unlikely","exploitation_impact":"low","title":"\u003cb\u003eUnnecessary Data Transfer\u003c/b\u003e of \u003cb\u003eTokens \u0026 Sessions\u003c/b\u003e data at \u003cb\u003eUser Browser\u003c/b\u003e from/to \u003cb\u003eJuice Shop Application\u003c/b\u003e","synthetic_id":"unnecessary-data-transfer@tokens-sessions@user-browser@juice-shop","most_relevant_data_asset":"tokens-sessions","most_relevant_technical_asset":"user-browser","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"","data_breach_probability":"improbable","data_breach_technical_assets":["user-browser"]},{"category":"unnecessary-data-transfer","risk_status":"unchecked","severity":"low","exploitation_likelihood":"unlikely","exploitation_impact":"low","title":"\u003cb\u003eUnnecessary Data Transfer\u003c/b\u003e of \u003cb\u003eTokens \u0026 Sessions\u003c/b\u003e data at \u003cb\u003eUser Browser\u003c/b\u003e from/to \u003cb\u003eReverse Proxy\u003c/b\u003e","synthetic_id":"unnecessary-data-transfer@tokens-sessions@user-browser@reverse-proxy","most_relevant_data_asset":"tokens-sessions","most_relevant_technical_asset":"user-browser","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"","data_breach_probability":"improbable","data_breach_technical_assets":["user-browser"]},{"category":"missing-waf","risk_status":"unchecked","severity":"low","exploitation_likelihood":"unlikely","exploitation_impact":"low","title":"\u003cb\u003eMissing Web Application Firewall (WAF)\u003c/b\u003e risk at \u003cb\u003eJuice Shop Application\u003c/b\u003e","synthetic_id":"missing-waf@juice-shop","most_relevant_data_asset":"","most_relevant_technical_asset":"juice-shop","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"","data_breach_probability":"improbable","data_breach_technical_assets":["juice-shop"]},{"category":"missing-identity-store","risk_status":"unchecked","severity":"medium","exploitation_likelihood":"unlikely","exploitation_impact":"medium","title":"\u003cb\u003eMissing Identity Store\u003c/b\u003e in the threat model (referencing asset \u003cb\u003eReverse Proxy\u003c/b\u003e as an example)","synthetic_id":"missing-identity-store@reverse-proxy","most_relevant_data_asset":"","most_relevant_technical_asset":"reverse-proxy","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"","data_breach_probability":"improbable","data_breach_technical_assets":[]},{"category":"missing-authentication-second-factor","risk_status":"unchecked","severity":"medium","exploitation_likelihood":"unlikely","exploitation_impact":"medium","title":"\u003cb\u003eMissing Two-Factor Authentication\u003c/b\u003e covering communication link \u003cb\u003eDirect to App (no proxy)\u003c/b\u003e from \u003cb\u003eUser Browser\u003c/b\u003e to \u003cb\u003eJuice Shop Application\u003c/b\u003e","synthetic_id":"missing-authentication-second-factor@user-browser\u003edirect-to-app-no-proxy@user-browser@juice-shop","most_relevant_data_asset":"","most_relevant_technical_asset":"juice-shop","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"user-browser\u003edirect-to-app-no-proxy","data_breach_probability":"possible","data_breach_technical_assets":["juice-shop"]},{"category":"missing-authentication-second-factor","risk_status":"unchecked","severity":"medium","exploitation_likelihood":"unlikely","exploitation_impact":"medium","title":"\u003cb\u003eMissing Two-Factor Authentication\u003c/b\u003e covering communication link \u003cb\u003eTo App\u003c/b\u003e from \u003cb\u003eUser Browser\u003c/b\u003e forwarded via \u003cb\u003eReverse Proxy\u003c/b\u003e to \u003cb\u003eJuice Shop Application\u003c/b\u003e","synthetic_id":"missing-authentication-second-factor@reverse-proxy\u003eto-app@reverse-proxy@juice-shop","most_relevant_data_asset":"","most_relevant_technical_asset":"juice-shop","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"reverse-proxy\u003eto-app","data_breach_probability":"possible","data_breach_technical_assets":["juice-shop"]},{"category":"container-baseimage-backdooring","risk_status":"unchecked","severity":"medium","exploitation_likelihood":"unlikely","exploitation_impact":"medium","title":"\u003cb\u003eContainer Base Image Backdooring\u003c/b\u003e risk at \u003cb\u003eJuice Shop Application\u003c/b\u003e","synthetic_id":"container-baseimage-backdooring@juice-shop","most_relevant_data_asset":"","most_relevant_technical_asset":"juice-shop","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"","data_breach_probability":"probable","data_breach_technical_assets":["juice-shop"]},{"category":"unnecessary-technical-asset","risk_status":"unchecked","severity":"low","exploitation_likelihood":"unlikely","exploitation_impact":"low","title":"\u003cb\u003eUnnecessary Technical Asset\u003c/b\u003e named \u003cb\u003ePersistent Storage\u003c/b\u003e","synthetic_id":"unnecessary-technical-asset@persistent-storage","most_relevant_data_asset":"","most_relevant_technical_asset":"persistent-storage","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"","data_breach_probability":"improbable","data_breach_technical_assets":["persistent-storage"]},{"category":"unnecessary-technical-asset","risk_status":"unchecked","severity":"low","exploitation_likelihood":"unlikely","exploitation_impact":"low","title":"\u003cb\u003eUnnecessary Technical Asset\u003c/b\u003e named \u003cb\u003eUser Browser\u003c/b\u003e","synthetic_id":"unnecessary-technical-asset@user-browser","most_relevant_data_asset":"","most_relevant_technical_asset":"user-browser","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"","data_breach_probability":"improbable","data_breach_technical_assets":["user-browser"]},{"category":"cross-site-request-forgery","risk_status":"unchecked","severity":"medium","exploitation_likelihood":"very-likely","exploitation_impact":"low","title":"\u003cb\u003eCross-Site Request Forgery (CSRF)\u003c/b\u003e risk at \u003cb\u003eJuice Shop Application\u003c/b\u003e via \u003cb\u003eDirect to App (no proxy)\u003c/b\u003e from \u003cb\u003eUser Browser\u003c/b\u003e","synthetic_id":"cross-site-request-forgery@juice-shop@user-browser\u003edirect-to-app-no-proxy","most_relevant_data_asset":"","most_relevant_technical_asset":"juice-shop","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"user-browser\u003edirect-to-app-no-proxy","data_breach_probability":"improbable","data_breach_technical_assets":["juice-shop"]},{"category":"cross-site-request-forgery","risk_status":"unchecked","severity":"medium","exploitation_likelihood":"very-likely","exploitation_impact":"low","title":"\u003cb\u003eCross-Site Request Forgery (CSRF)\u003c/b\u003e risk at \u003cb\u003eJuice Shop Application\u003c/b\u003e via \u003cb\u003eTo App\u003c/b\u003e from \u003cb\u003eReverse Proxy\u003c/b\u003e","synthetic_id":"cross-site-request-forgery@juice-shop@reverse-proxy\u003eto-app","most_relevant_data_asset":"","most_relevant_technical_asset":"juice-shop","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"reverse-proxy\u003eto-app","data_breach_probability":"improbable","data_breach_technical_assets":["juice-shop"]},{"category":"missing-build-infrastructure","risk_status":"unchecked","severity":"medium","exploitation_likelihood":"unlikely","exploitation_impact":"medium","title":"\u003cb\u003eMissing Build Infrastructure\u003c/b\u003e in the threat model (referencing asset \u003cb\u003eJuice Shop Application\u003c/b\u003e as an example)","synthetic_id":"missing-build-infrastructure@juice-shop","most_relevant_data_asset":"","most_relevant_technical_asset":"juice-shop","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"","data_breach_probability":"improbable","data_breach_technical_assets":[]},{"category":"missing-vault","risk_status":"unchecked","severity":"medium","exploitation_likelihood":"unlikely","exploitation_impact":"medium","title":"\u003cb\u003eMissing Vault (Secret Storage)\u003c/b\u003e in the threat model (referencing asset \u003cb\u003eJuice Shop Application\u003c/b\u003e as an example)","synthetic_id":"missing-vault@juice-shop","most_relevant_data_asset":"","most_relevant_technical_asset":"juice-shop","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"","data_breach_probability":"improbable","data_breach_technical_assets":[]},{"category":"unencrypted-asset","risk_status":"unchecked","severity":"medium","exploitation_likelihood":"unlikely","exploitation_impact":"medium","title":"\u003cb\u003eUnencrypted Technical Asset\u003c/b\u003e named \u003cb\u003eJuice Shop Application\u003c/b\u003e","synthetic_id":"unencrypted-asset@juice-shop","most_relevant_data_asset":"","most_relevant_technical_asset":"juice-shop","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"","data_breach_probability":"improbable","data_breach_technical_assets":["juice-shop"]},{"category":"cross-site-scripting","risk_status":"unchecked","severity":"elevated","exploitation_likelihood":"likely","exploitation_impact":"medium","title":"\u003cb\u003eCross-Site Scripting (XSS)\u003c/b\u003e risk at \u003cb\u003eJuice Shop Application\u003c/b\u003e","synthetic_id":"cross-site-scripting@juice-shop","most_relevant_data_asset":"","most_relevant_technical_asset":"juice-shop","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"","data_breach_probability":"possible","data_breach_technical_assets":["juice-shop"]},{"category":"server-side-request-forgery","risk_status":"unchecked","severity":"medium","exploitation_likelihood":"likely","exploitation_impact":"low","title":"\u003cb\u003eServer-Side Request Forgery (SSRF)\u003c/b\u003e risk at \u003cb\u003eJuice Shop Application\u003c/b\u003e server-side web-requesting the target \u003cb\u003eWebhook Endpoint\u003c/b\u003e via \u003cb\u003eTo Challenge WebHook\u003c/b\u003e","synthetic_id":"server-side-request-forgery@juice-shop@webhook-endpoint@juice-shop\u003eto-challenge-webhook","most_relevant_data_asset":"","most_relevant_technical_asset":"juice-shop","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"juice-shop\u003eto-challenge-webhook","data_breach_probability":"possible","data_breach_technical_assets":["juice-shop"]},{"category":"server-side-request-forgery","risk_status":"unchecked","severity":"medium","exploitation_likelihood":"likely","exploitation_impact":"low","title":"\u003cb\u003eServer-Side Request Forgery (SSRF)\u003c/b\u003e risk at \u003cb\u003eReverse Proxy\u003c/b\u003e server-side web-requesting the target \u003cb\u003eJuice Shop Application\u003c/b\u003e via \u003cb\u003eTo App\u003c/b\u003e","synthetic_id":"server-side-request-forgery@reverse-proxy@juice-shop@reverse-proxy\u003eto-app","most_relevant_data_asset":"","most_relevant_technical_asset":"reverse-proxy","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"reverse-proxy\u003eto-app","data_breach_probability":"possible","data_breach_technical_assets":["reverse-proxy"]},{"category":"missing-hardening","risk_status":"unchecked","severity":"medium","exploitation_likelihood":"likely","exploitation_impact":"low","title":"\u003cb\u003eMissing Hardening\u003c/b\u003e risk at \u003cb\u003eJuice Shop Application\u003c/b\u003e","synthetic_id":"missing-hardening@juice-shop","most_relevant_data_asset":"","most_relevant_technical_asset":"juice-shop","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"","data_breach_probability":"improbable","data_breach_technical_assets":["juice-shop"]},{"category":"missing-hardening","risk_status":"unchecked","severity":"medium","exploitation_likelihood":"likely","exploitation_impact":"low","title":"\u003cb\u003eMissing Hardening\u003c/b\u003e risk at \u003cb\u003ePersistent Storage\u003c/b\u003e","synthetic_id":"missing-hardening@persistent-storage","most_relevant_data_asset":"","most_relevant_technical_asset":"persistent-storage","most_relevant_trust_boundary":"","most_relevant_shared_runtime":"","most_relevant_communication_link":"","data_breach_probability":"improbable","data_breach_technical_assets":["persistent-storage"]}]
\ No newline at end of file
diff --git a/labs/lab2/secure/stats.json b/labs/lab2/secure/stats.json
new file mode 100644
index 00000000..c19a18a6
--- /dev/null
+++ b/labs/lab2/secure/stats.json
@@ -0,0 +1 @@
+{"risks":{"critical":{"accepted":0,"false-positive":0,"in-discussion":0,"in-progress":0,"mitigated":0,"unchecked":0},"elevated":{"accepted":0,"false-positive":0,"in-discussion":0,"in-progress":0,"mitigated":0,"unchecked":2},"high":{"accepted":0,"false-positive":0,"in-discussion":0,"in-progress":0,"mitigated":0,"unchecked":0},"low":{"accepted":0,"false-positive":0,"in-discussion":0,"in-progress":0,"mitigated":0,"unchecked":5},"medium":{"accepted":0,"false-positive":0,"in-discussion":0,"in-progress":0,"mitigated":0,"unchecked":13}}}
\ No newline at end of file
diff --git a/labs/lab2/secure/technical-assets.json b/labs/lab2/secure/technical-assets.json
new file mode 100644
index 00000000..a082acb4
--- /dev/null
+++ b/labs/lab2/secure/technical-assets.json
@@ -0,0 +1 @@
+{"juice-shop":{"Id":"juice-shop","Title":"Juice Shop Application","Description":"OWASP Juice Shop server (Node.js/Express, v19.0.0).","Usage":0,"Type":1,"Size":2,"Technology":6,"Machine":2,"Internet":false,"MultiTenant":false,"Redundant":false,"CustomDevelopedParts":true,"OutOfScope":false,"UsedAsClientByHuman":false,"Encryption":0,"JustificationOutOfScope":"","Owner":"Lab Owner","Confidentiality":1,"Integrity":2,"Availability":2,"JustificationCiaRating":"In-scope web application (contains all business logic and vulnerabilities by design).","Tags":["app","nodejs"],"DataAssetsProcessed":["user-accounts","orders","product-catalog","tokens-sessions"],"DataAssetsStored":["logs"],"DataFormatsAccepted":[0],"CommunicationLinks":[{"Id":"juice-shop\u003eto-challenge-webhook","SourceId":"juice-shop","TargetId":"webhook-endpoint","Title":"To Challenge WebHook","Description":"Optional outbound callback (HTTP POST) to external WebHook when a challenge is solved.","Protocol":2,"Tags":["egress"],"VPN":false,"IpFiltered":false,"Readonly":false,"Authentication":0,"Authorization":0,"Usage":0,"DataAssetsSent":["orders"],"DataAssetsReceived":null,"DiagramTweakWeight":1,"DiagramTweakConstraint":true}],"DiagramTweakOrder":0,"RAA":70.02881844380403},"persistent-storage":{"Id":"persistent-storage","Title":"Persistent Storage","Description":"Host-mounted volume for database, file uploads, and logs.","Usage":1,"Type":2,"Size":3,"Technology":10,"Machine":1,"Internet":false,"MultiTenant":false,"Redundant":false,"CustomDevelopedParts":false,"OutOfScope":false,"UsedAsClientByHuman":false,"Encryption":1,"JustificationOutOfScope":"","Owner":"Lab Owner","Confidentiality":1,"Integrity":2,"Availability":2,"JustificationCiaRating":"Local disk storage for the container – not directly exposed, but if compromised it contains sensitive data (database and logs).","Tags":["storage","volume"],"DataAssetsProcessed":[],"DataAssetsStored":["logs","user-accounts","orders","product-catalog"],"DataFormatsAccepted":[3],"CommunicationLinks":[],"DiagramTweakOrder":0,"RAA":100},"reverse-proxy":{"Id":"reverse-proxy","Title":"Reverse Proxy","Description":"Optional reverse proxy (e.g., Nginx) for TLS termination and adding security headers.","Usage":0,"Type":1,"Size":2,"Technology":20,"Machine":1,"Internet":false,"MultiTenant":false,"Redundant":false,"CustomDevelopedParts":false,"OutOfScope":false,"UsedAsClientByHuman":false,"Encryption":1,"JustificationOutOfScope":"","Owner":"Lab Owner","Confidentiality":1,"Integrity":2,"Availability":2,"JustificationCiaRating":"Not exposed to internet directly; improves security of inbound traffic.","Tags":["optional","proxy"],"DataAssetsProcessed":["product-catalog","tokens-sessions"],"DataAssetsStored":[],"DataFormatsAccepted":[0],"CommunicationLinks":[{"Id":"reverse-proxy\u003eto-app","SourceId":"reverse-proxy","TargetId":"juice-shop","Title":"To App","Description":"Proxy forwarding to app (HTTP on 3000 internally).","Protocol":2,"Tags":[],"VPN":false,"IpFiltered":false,"Readonly":false,"Authentication":0,"Authorization":0,"Usage":0,"DataAssetsSent":["tokens-sessions"],"DataAssetsReceived":["product-catalog"],"DiagramTweakWeight":1,"DiagramTweakConstraint":true}],"DiagramTweakOrder":0,"RAA":9.623538157950035},"user-browser":{"Id":"user-browser","Title":"User Browser","Description":"End-user web browser (client).","Usage":0,"Type":0,"Size":0,"Technology":2,"Machine":1,"Internet":true,"MultiTenant":false,"Redundant":false,"CustomDevelopedParts":false,"OutOfScope":false,"UsedAsClientByHuman":true,"Encryption":0,"JustificationOutOfScope":"","Owner":"External User","Confidentiality":0,"Integrity":1,"Availability":1,"JustificationCiaRating":"Client controlled by end user (potentially an attacker).","Tags":["actor","user"],"DataAssetsProcessed":[],"DataAssetsStored":[],"DataFormatsAccepted":[0],"CommunicationLinks":[{"Id":"user-browser\u003eto-reverse-proxy-preferred","SourceId":"user-browser","TargetId":"reverse-proxy","Title":"To Reverse Proxy (preferred)","Description":"User browser to reverse proxy (HTTPS on 443).","Protocol":2,"Tags":["primary"],"VPN":false,"IpFiltered":false,"Readonly":false,"Authentication":2,"Authorization":2,"Usage":0,"DataAssetsSent":["tokens-sessions"],"DataAssetsReceived":["product-catalog"],"DiagramTweakWeight":1,"DiagramTweakConstraint":true},{"Id":"user-browser\u003edirect-to-app-no-proxy","SourceId":"user-browser","TargetId":"juice-shop","Title":"Direct to App (no proxy)","Description":"Direct browser access to app (HTTP on 3000).","Protocol":2,"Tags":["direct"],"VPN":false,"IpFiltered":false,"Readonly":false,"Authentication":2,"Authorization":2,"Usage":0,"DataAssetsSent":["tokens-sessions"],"DataAssetsReceived":["product-catalog"],"DiagramTweakWeight":1,"DiagramTweakConstraint":true}],"DiagramTweakOrder":0,"RAA":25.859639506459924},"webhook-endpoint":{"Id":"webhook-endpoint","Title":"Webhook Endpoint","Description":"External WebHook service (3rd-party, if configured for integrations).","Usage":0,"Type":0,"Size":0,"Technology":14,"Machine":1,"Internet":true,"MultiTenant":true,"Redundant":true,"CustomDevelopedParts":false,"OutOfScope":true,"UsedAsClientByHuman":false,"Encryption":0,"JustificationOutOfScope":"Third-party service to receive notifications (not under our control).","Owner":"Third-Party","Confidentiality":1,"Integrity":1,"Availability":1,"JustificationCiaRating":"External service that receives data (like order or challenge info). Treated as a trusted integration point but could be abused if misconfigured.","Tags":["saas","webhook"],"DataAssetsProcessed":["orders"],"DataAssetsStored":[],"DataFormatsAccepted":[0],"CommunicationLinks":[],"DiagramTweakOrder":0,"RAA":1}}
\ 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 00000000..4bfdf2fd
--- /dev/null
+++ b/labs/lab2/threagile-model.secure.yaml
@@ -0,0 +1,429 @@
+threagile_version: 1.0.0
+
+title: OWASP Juice Shop — Local Lab Threat Model
+date: 2025-02-16
+
+author:
+ name: Daniel Gevorgyan
+ 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: []
+ data_assets_stored: []
+ 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 (HTTP on 3000)."
+ 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 (HTTP on 3000 internally)."
+ protocol: https
+ authentication: none
+ authorization: none
+ 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 (HTTP 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
+
+ Persistent Storage:
+ id: persistent-storage
+ description: "Host-mounted volume for database, file uploads, and logs."
+ type: datastore
+ usage: devops
+ used_as_client_by_human: false
+ out_of_scope: false
+ justification_out_of_scope:
+ size: component
+ technology: file-server
+ tags: ["storage", "volume"]
+ internet: false
+ machine: virtual
+ encryption: transparent
+ 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
diff --git a/labs/lab2/threagile-model.yaml b/labs/lab2/threagile-model.yaml
index 85c01a79..a6092993 100644
--- a/labs/lab2/threagile-model.yaml
+++ b/labs/lab2/threagile-model.yaml
@@ -1,10 +1,10 @@
threagile_version: 1.0.0
title: OWASP Juice Shop — Local Lab Threat Model
-date: 2025-09-18
+date: 2025-02-16
author:
- name: Student Name
+ name: Daniel Gevorgyan
homepage: https://example.edu
management_summary_comment: >
diff --git a/labs/submission1.md b/labs/submission1.md
new file mode 100644
index 00000000..dbb1ccc3
--- /dev/null
+++ b/labs/submission1.md
@@ -0,0 +1,41 @@
+# Triage Report — OWASP Juice Shop
+
+## Scope & Asset
+- Asset: OWASP Juice Shop (local lab instance)
+- Image: bkimminich/juice-shop:v19.0.0
+- Release link/date: —
+- Image digest (optional):
+
+## Environment
+- Host OS: NixOS 26.05 (Yarara) x86_64
+- Docker: 29.1.5
+
+## Deployment Details
+- Run command used: `docker run -d --name juice-shop -p 127.0.0.1:3000:3000 bkimminich/juice-shop:v19.0.0`
+- Access URL: http://127.0.0.1:3000
+- Network exposure: 127.0.0.1 only [x] Yes [ ] No
+
+## Health Check
+- Page load: 
+- API check: first 5–10 lines from `curl -s http://127.0.0.1:3000/rest/products | head`
+
+## Surface Snapshot (Triage)
+- Login/Registration visible: [x] Yes [ ] No — notes: Login is visible under Account button on a page header
+- Product listing/search present: [x] Yes [ ] No — notes: Products are displayed
+- Admin or account area discoverable: [x] Yes [ ] No
+- Client-side errors in console: [ ] Yes [x] No — notes: no errors are leaked
+- Security headers (quick look — optional): `curl -I http://127.0.0.1:3000` → CSP/HSTS present? notes: Basic security headers present but missing CSP and HSTS headers
+
+## Risks Observed (Top 3)
+1) Missing Content Security Policy (CSP) --
+ Application lacks CSP headers, making it vulnerable to XSS attacks as there are no restrictions on script sources or inline execution.
+2) No HTTP Strict Transport Security (HSTS) --
+ Absence of HSTS headers leaves the application susceptible to SSL stripping attacks and protocol downgrades.
+3) Exposed Admin Interface --
+ Administrative endpoints are discoverable without proper rate limiting or multi-factor authentication, potentially allowing brute force attacks.
+
+
+## GitHub Community
+
+Starring repositories helps signal project quality and usefulness, supports maintainers through visible appreciation, and improves discoverability of valuable open-source tools. Following developers makes it easier to track relevant work, learn from others’ approaches, and build professional connections that support effective collaboration and long-term career growth.
+
diff --git a/labs/submission1/page-load.png b/labs/submission1/page-load.png
new file mode 100644
index 00000000..af73e664
Binary files /dev/null and b/labs/submission1/page-load.png differ
diff --git a/labs/submission2.md b/labs/submission2.md
new file mode 100644
index 00000000..40510b3a
--- /dev/null
+++ b/labs/submission2.md
@@ -0,0 +1,136 @@
+# Lab 2 — Threat Modeling with Threagile
+
+## Overview
+
+This submission documents the threat modeling of the OWASP Juice Shop (`bkimminich/juice-shop:v19.0.0`) using Threagile.
+The lab includes a baseline threat model, a secure HTTPS variant, and a comparative risk analysis demonstrating how security controls affect the risk landscape.
+
+---
+
+## Task 1 — Threagile Baseline Model
+
+### Baseline Model Generation
+
+- Threagile was executed using the provided YAML model:
+ - Model file: `lab2/threagile-model.yaml`
+ - Output directory: `lab2/baseline/`
+- The Docker-based Threagile run successfully generated:
+ - `report.pdf`
+ - Risk data (`risks.json`, `stats.json`, `technical-assets.json`)
+ - Data-flow and asset diagrams (PNG)
+
+### Generated Artifacts
+
+- PDF Report: `lab2/baseline/report.pdf`
+- Diagrams:
+ - Data Flow Diagram: `lab2/baseline/data-flow-diagram.png`
+ - Data Asset Diagram: `lab2/baseline/data-asset-diagram.png`
+- Risk Export: `lab2/baseline/risks.json`
+
+---
+
+### Risk Ranking Methodology
+
+Risks were ranked using a composite score calculated as follows:
+
+```
+Composite Score = Severity × 100 + Likelihood × 10 + Impact
+```
+
+**Scoring values used:**
+
+| Dimension | Values |
+|-----------|--------|
+| Severity | critical (5), elevated (4), high (3), medium (2), low (1) |
+| Likelihood| very-likely (4), likely (3), possible (2), unlikely (1) |
+| Impact | high (3), medium (2), low (1) |
+
+The Top 5 risks were selected based on the highest composite scores.
+
+---
+
+### Top 5 Risks (Baseline)
+
+| Rank | Risk Title | Category | Asset | Severity | Likelihood | Impact | Composite Score |
+|-----:|------------------------------------|-----------------------------|-------------|--------------|-------------|----------|-----------------|
+| 1 | Unencrypted Communicatin | unencrypted-communication | Application | elevated (4) | likely (3) | high (3) | 433 |
+| 2 | Missing Authentication | missing-authentication | Application | elevated (4) | likely (3) | high (3) | 432 |
+| 3 | Cross-Site Scripting (XSS) | cross-site-scripting | Application | elevated (4) | likely (3) | high (3) | 432 |
+| 4 | Cross-Site Request Forgery (CSRF) | cross-site-request-forgery | Application | high (3) | likely (3) | high (3) | 241 |
+| 5 | Server-Side Request Forgery (SSRF) | server-side-request-forgery | Application | high (3) | possible (2)| high (3) | 231 |
+
+---
+
+### Baseline Risk Analysis
+
+The baseline threat model highlights several critical application-layer risks. Unencrypted communication represents the highest risk due to the potential for credential leakage and data interception. Authentication-related weaknesses and common web vulnerabilities such as XSS and CSRF further increase the attack surface, particularly in a deliberately vulnerable application like OWASP Juice Shop. SSRF remains a concern due to its potential to access internal resources.
+
+---
+
+## Task 2 — Secure HTTPS Variant & Risk Comparison
+
+### Secure Model Changes
+
+A secure variant of the baseline model was created at: `lab2/threagile-model.secure.yaml`
+
+The following changes were applied:
+
+- Communication between **User Browser → Application** set to `protocol: https`
+- Communication involving the **Reverse Proxy** set to `protocol: https`
+- **Persistent Storage** configured with `encryption: transparent`
+
+No asset names or architectural structure were changed to ensure accurate risk comparison.
+
+---
+
+### Secure Variant Generation
+
+- Output directory: `lab2/secure/`
+- Generated artifacts:
+ - `report.pdf`
+ - Updated diagrams
+ - Updated `risks.json`
+
+---
+
+### Risk Category Delta Table
+
+The following table compares the number of risks per category between the baseline and secure models:
+
+| Category | Baseline | Secure | Δ |
+|---|---:|---:|---:|
+| container-baseimage-backdooring | 1 | 1 | 0 |
+| cross-site-request-forgery | 2 | 2 | 0 |
+| cross-site-scripting | 1 | 1 | 0 |
+| missing-authentication | 1 | 1 | 0 |
+| missing-authentication-second-factor | 2 | 2 | 0 |
+| missing-build-infrastructure | 1 | 1 | 0 |
+| missing-hardening | 2 | 2 | 0 |
+| missing-identity-store | 1 | 1 | 0 |
+| missing-vault | 1 | 1 | 0 |
+| missing-waf | 1 | 1 | 0 |
+| server-side-request-forgery | 2 | 2 | 0 |
+| unencrypted-asset | 2 | 1 | -1 |
+| unencrypted-communication | 2 | 0 | -2 |
+| unnecessary-data-transfer | 2 | 2 | 0 |
+| unnecessary-technical-asset | 2 | 2 | 0 |
+
+---
+
+### Delta Analysis
+
+The baseline threat model highlights several critical application-layer risks. Unencrypted communication represents the highest risk due to the potential for credential leakage and data interception. Authentication-related weaknesses and common web vulnerabilities such as XSS and CSRF further increase the attack surface, particularly in a deliberately vulnerable application like OWASP Juice Shop. SSRF remains a concern due to its potential to access internal resources.
+
+---
+
+### Diagram Comparison
+- Baseline Diagrams: `lab2/baseline/data-flow-diagram.png`, `lab2/baseline/data-asset-diagram.png`
+- Secure Diagram: `lab2/secure/data-flow-diagram.png`, `lab2/baseline/data-asset-diagram.png`
+
+The data-flow diagram reflects the transition to HTTPS, while the data-asset diagram remains unchanged, as encryption at rest does not alter asset relationships.
+
+---
+
+## Conclusion
+
+This lab demonstrates how threat modeling as code enables systematic evaluation of security controls. Introducing HTTPS and encryption at rest significantly reduced transport and storage-related risks while leaving application-layer vulnerabilities unchanged. This highlights the importance of layered defenses and complementary controls when securing web applications.