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..3b6c09b4 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..05c41156 --- /dev/null +++ b/labs/lab2/baseline/risks.json @@ -0,0 +1,410 @@ +[ + { + "category": "unnecessary-data-transfer", + "risk_status": "unchecked", + "severity": "low", + "exploitation_likelihood": "unlikely", + "exploitation_impact": "low", + "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": "low", + "exploitation_likelihood": "unlikely", + "exploitation_impact": "low", + "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": "server-side-request-forgery", + "risk_status": "unchecked", + "severity": "medium", + "exploitation_likelihood": "likely", + "exploitation_impact": "low", + "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": "possible", + "data_breach_technical_assets": [ + "juice-shop" + ] + }, + { + "category": "server-side-request-forgery", + "risk_status": "unchecked", + "severity": "medium", + "exploitation_likelihood": "likely", + "exploitation_impact": "low", + "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": "possible", + "data_breach_technical_assets": [ + "reverse-proxy" + ] + }, + { + "category": "missing-hardening", + "risk_status": "unchecked", + "severity": "medium", + "exploitation_likelihood": "likely", + "exploitation_impact": "low", + "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": "medium", + "exploitation_likelihood": "likely", + "exploitation_impact": "low", + "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": "container-baseimage-backdooring", + "risk_status": "unchecked", + "severity": "medium", + "exploitation_likelihood": "unlikely", + "exploitation_impact": "medium", + "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": "missing-build-infrastructure", + "risk_status": "unchecked", + "severity": "medium", + "exploitation_likelihood": "unlikely", + "exploitation_impact": "medium", + "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": "missing-authentication", + "risk_status": "unchecked", + "severity": "elevated", + "exploitation_likelihood": "likely", + "exploitation_impact": "medium", + "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": "possible", + "data_breach_technical_assets": [ + "juice-shop" + ] + }, + { + "category": "unnecessary-technical-asset", + "risk_status": "unchecked", + "severity": "low", + "exploitation_likelihood": "unlikely", + "exploitation_impact": "low", + "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": "low", + "exploitation_likelihood": "unlikely", + "exploitation_impact": "low", + "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": "unencrypted-asset", + "risk_status": "unchecked", + "severity": "medium", + "exploitation_likelihood": "unlikely", + "exploitation_impact": "medium", + "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": "medium", + "exploitation_likelihood": "unlikely", + "exploitation_impact": "medium", + "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-authentication-second-factor", + "risk_status": "unchecked", + "severity": "medium", + "exploitation_likelihood": "unlikely", + "exploitation_impact": "medium", + "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": "possible", + "data_breach_technical_assets": [ + "juice-shop" + ] + }, + { + "category": "missing-authentication-second-factor", + "risk_status": "unchecked", + "severity": "medium", + "exploitation_likelihood": "unlikely", + "exploitation_impact": "medium", + "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": "possible", + "data_breach_technical_assets": [ + "juice-shop" + ] + }, + { + "category": "missing-vault", + "risk_status": "unchecked", + "severity": "medium", + "exploitation_likelihood": "unlikely", + "exploitation_impact": "medium", + "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-waf", + "risk_status": "unchecked", + "severity": "low", + "exploitation_likelihood": "unlikely", + "exploitation_impact": "low", + "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": "elevated", + "exploitation_likelihood": "likely", + "exploitation_impact": "high", + "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": "possible", + "data_breach_technical_assets": [ + "juice-shop" + ] + }, + { + "category": "unencrypted-communication", + "risk_status": "unchecked", + "severity": "elevated", + "exploitation_likelihood": "likely", + "exploitation_impact": "medium", + "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": "possible", + "data_breach_technical_assets": [ + "juice-shop" + ] + }, + { + "category": "missing-identity-store", + "risk_status": "unchecked", + "severity": "medium", + "exploitation_likelihood": "unlikely", + "exploitation_impact": "medium", + "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": [] + }, + { + "category": "cross-site-scripting", + "risk_status": "unchecked", + "severity": "elevated", + "exploitation_likelihood": "likely", + "exploitation_impact": "medium", + "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": "possible", + "data_breach_technical_assets": [ + "juice-shop" + ] + }, + { + "category": "cross-site-request-forgery", + "risk_status": "unchecked", + "severity": "medium", + "exploitation_likelihood": "very-likely", + "exploitation_impact": "low", + "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": "medium", + "exploitation_likelihood": "very-likely", + "exploitation_impact": "low", + "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" + ] + } +] \ No newline at end of file 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/scripts/calculate_risk_score.py b/labs/lab2/scripts/calculate_risk_score.py new file mode 100644 index 00000000..e3f48666 --- /dev/null +++ b/labs/lab2/scripts/calculate_risk_score.py @@ -0,0 +1,30 @@ +import json + +# Define the weights +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} + +def calculate_score(risk): + s = SEVERITY.get(risk.get("severity", "low"), 1) + l = LIKELIHOOD.get(risk.get("exploitation_likelihood", "unlikely"), 1) + i = IMPACT.get(risk.get("exploitation_impact", "low"), 1) + + return (s * 100) + (l * 10) + i + +try: + with open("./../baseline/risks.json", "r") as f: + risks = json.load(f) + + for r in risks: + r["composite_score"] = calculate_score(r) + sorted_risks = sorted(risks, key=lambda x: x["composite_score"], reverse=True) + + print("| Score | Severity | Category | Asset | Likelihood | Impact |") + print("|---|---|---|---|---|---|") + + for r in sorted_risks[:5]: + print(f"| {r['composite_score']} | {r['severity']} | {r['category']} | {r.get('most_relevant_technical_asset', 'N/A')} | {r['exploitation_likelihood']} | {r['exploitation_impact']} |") + +except FileNotFoundError: + print("Error: not found") \ 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..0b4de059 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..fd3f58d0 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..c4bdd9a4 --- /dev/null +++ b/labs/lab2/secure/risks.json @@ -0,0 +1 @@ +[{"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":"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-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":"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":"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":"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":"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":"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":"unencrypted-communication","risk_status":"unchecked","severity":"elevated","exploitation_likelihood":"likely","exploitation_impact":"high","title":"\u003cb\u003eUnencrypted Communication\u003c/b\u003e named \u003cb\u003eDirect to App (no proxy)\u003c/b\u003e between \u003cb\u003eUser Browser\u003c/b\u003e and \u003cb\u003eJuice Shop Application\u003c/b\u003e transferring authentication data (like credentials, token, session-id, etc.)","synthetic_id":"unencrypted-communication@user-browser\u003edirect-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\u003edirect-to-app-no-proxy","data_breach_probability":"possible","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":"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"]},{"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":"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"]}] \ 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..b57e372b --- /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":3},"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..ea528fe1 --- /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":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/threagile-model.secure.yaml b/labs/lab2/threagile-model.secure.yaml new file mode 100644 index 00000000..56c4ab42 --- /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-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: [] + 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: http + 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/lab3.md b/labs/lab3.md index 47ec06df..fe05e44e 100644 --- a/labs/lab3.md +++ b/labs/lab3.md @@ -47,7 +47,7 @@ Study why commit signing is crucial for verifying the integrity and authenticity ```sh git config --global user.signingkey git config --global commit.gpgSign true - git config --global gpg.format ssh + ``` #### 1.3: Create Signed Commit diff --git a/labs/lab7.md b/labs/lab7.md deleted file mode 100644 index 48c23111..00000000 --- a/labs/lab7.md +++ /dev/null @@ -1,414 +0,0 @@ -# Lab 7 — Container Security: Image Scanning & Deployment Hardening - -![difficulty](https://img.shields.io/badge/difficulty-intermediate-orange) -![topic](https://img.shields.io/badge/topic-Container%20Security-blue) -![points](https://img.shields.io/badge/points-10-orange) - -> **Goal:** Analyze container images for vulnerabilities, audit Docker host security, and compare secure deployment configurations. -> **Deliverable:** A PR from `feature/lab7` to the course repo with `labs/submission7.md` containing vulnerability analysis, CIS benchmark results, and deployment security comparison. Submit the PR link via Moodle. - ---- - -## Overview - -In this lab you will practice: -- **Container image vulnerability scanning** using next-generation tools (Docker Scout, Snyk) -- **Docker security benchmarking** with CIS Docker Benchmark compliance assessment -- **Secure container deployment** analysis and configuration comparison -- **Container security assessment** using modern scanning and analysis tools -- **Security configuration impact** analysis for production deployments - -These skills are essential for implementing container security in DevSecOps pipelines and production environments. - -> Target application: OWASP Juice Shop (`bkimminich/juice-shop:v19.0.0`) - ---- - -## Prerequisites - -### Docker Scout CLI Setup - -Docker Scout requires authentication and a CLI plugin installation. - -#### Step 1: Install Docker Scout CLI Plugin - -**For Linux/macOS:** -```bash -curl -sSfL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s -- -``` - -**Verify installation:** -```bash -docker scout version -``` - -You should see output like: `version: v1.x.x` - -#### Step 2: Docker Hub Authentication - -Docker Scout requires a Docker Hub account and Personal Access Token (PAT). - -**Create account and generate PAT:** - -1. **Create Docker Hub account** (if needed): Visit https://hub.docker.com - -2. **Generate PAT:** - - - Log in → Account Settings → Security → Personal Access Tokens - - Click **New Access Token** - - Description: `Lab7 Docker Scout Access` - - Permissions: Select **Read, Write, Delete** - - Click **Generate** and copy the token immediately - -3. **Authenticate:** - - ```bash - docker login - # Username: your-docker-hub-username - # Password: paste-your-PAT (not your password!) - ``` - -4. **Verify access:** - - ```bash - docker scout quickview busybox:latest - # Should display vulnerability scan results - ``` - -**Why PAT over password?** -- Limited scope permissions for least privilege -- Easy to revoke without changing account password -- Required for SSO-enabled organizations -- Better audit trail - -Learn more: https://docs.docker.com/go/access-tokens/ - ---- - -## Tasks - -### Task 1 — Image Vulnerability & Configuration Analysis (3 pts) - -**Objective:** Scan container images for vulnerabilities and configuration issues. - -#### 1.1: Setup Working Directory - -```bash -mkdir -p labs/lab7/{scanning,hardening,analysis} -cd labs/lab7 -``` - -#### 1.2: Vulnerability Scanning - -```bash -# Pull the image to scan locally -docker pull bkimminich/juice-shop:v19.0.0 - -# Detailed CVE analysis -docker scout cves bkimminich/juice-shop:v19.0.0 | tee scanning/scout-cves.txt -``` - -**Understanding the output:** -- **C/H/M/L** = Critical/High/Medium/Low severity counts -- Look for CVE IDs, affected packages, and potential impact - -#### 1.3: Snyk comparison - -```bash -# Requires Snyk account: https://snyk.io -# Set token: export SNYK_TOKEN=your-token -docker run --rm \ - -e SNYK_TOKEN \ - -v /var/run/docker.sock:/var/run/docker.sock \ - snyk/snyk:docker snyk test --docker bkimminich/juice-shop:v19.0.0 --severity-threshold=high \ - | tee scanning/snyk-results.txt -``` - -#### 1.4: Configuration Assessment - -```bash -# Scan for security and best practice issues -docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ - goodwithtech/dockle:latest \ - bkimminich/juice-shop:v19.0.0 | tee scanning/dockle-results.txt -``` - -**Look for:** -- **FATAL/WARN** issues about running as root -- Exposed secrets in environment variables -- Missing security configurations -- File permission issues - -**📊 Document in `labs/submission7.md`:** - -1. **Top 5 Critical/High Vulnerabilities** - - CVE ID, affected package, severity, and impact - -2. **Dockle Configuration Findings** - - List FATAL and WARN issues - - Explain why each is a security concern - -3. **Security Posture Assessment** - - Does the image run as root? - - What security improvements would you recommend? - ---- - -### Task 2 — Docker Host Security Benchmarking (3 pts) - -**Objective:** Audit Docker host configuration against CIS Docker Benchmark. - -#### 2.1: Run CIS Docker Benchmark - -```bash -# Run CIS Docker Benchmark security audit -docker run --rm --net host --pid host --userns host --cap-add audit_control \ - -e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \ - -v /var/lib:/var/lib:ro \ - -v /var/run/docker.sock:/var/run/docker.sock:ro \ - -v /usr/lib/systemd:/usr/lib/systemd:ro \ - -v /etc:/etc:ro --label docker_bench_security \ - docker/docker-bench-security | tee hardening/docker-bench-results.txt -``` - -**Understanding the output:** -- **[PASS]** - Security control properly configured -- **[WARN]** - Potential issue requiring review -- **[FAIL]** - Security control not properly configured -- **[INFO]** - Informational (no action needed) - -**Key sections:** -1. Host Configuration -2. Docker daemon configuration -3. Docker daemon configuration files -4. Container Images and Build Files -5. Container Runtime - -**📊 Document in `labs/submission7.md`:** - -1. **Summary Statistics** - - Total PASS/WARN/FAIL/INFO counts - -2. **Analysis of Failures** (if any) - - List failures and explain security impact - - Propose specific remediation steps - ---- - -### Task 3 — Deployment Security Configuration Analysis (4 pts) - -**Objective:** Compare deployment configurations to understand security hardening trade-offs. - -#### 3.1: Deploy Three Security Profiles - -```bash -# Profile 1: Default (baseline) -docker run -d --name juice-default -p 3001:3000 \ - bkimminich/juice-shop:v19.0.0 - -# Profile 2: Hardened (security restrictions) -docker run -d --name juice-hardened -p 3002:3000 \ - --cap-drop=ALL \ - --security-opt=no-new-privileges \ - --memory=512m \ - --cpus=1.0 \ - bkimminich/juice-shop:v19.0.0 - -# Profile 3: Production (maximum hardening) -docker run -d --name juice-production -p 3003:3000 \ - --cap-drop=ALL \ - --cap-add=NET_BIND_SERVICE \ - --security-opt=no-new-privileges \ - --security-opt=seccomp=default \ - --memory=512m \ - --memory-swap=512m \ - --cpus=1.0 \ - --pids-limit=100 \ - --restart=on-failure:3 \ - bkimminich/juice-shop:v19.0.0 - -# Wait for startup -sleep 15 - -# Verify all containers are running -docker ps -a --filter name=juice- -``` - -#### 3.2: Compare Configurations - -```bash -# Test functionality -echo "=== Functionality Test ===" | tee analysis/deployment-comparison.txt -curl -s -o /dev/null -w "Default: HTTP %{http_code}\n" http://localhost:3001 | tee -a analysis/deployment-comparison.txt -curl -s -o /dev/null -w "Hardened: HTTP %{http_code}\n" http://localhost:3002 | tee -a analysis/deployment-comparison.txt -curl -s -o /dev/null -w "Production: HTTP %{http_code}\n" http://localhost:3003 | tee -a analysis/deployment-comparison.txt - -# Check resource usage -echo "" | tee -a analysis/deployment-comparison.txt -echo "=== Resource Usage ===" | tee -a analysis/deployment-comparison.txt -docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}" \ - juice-default juice-hardened juice-production | tee -a analysis/deployment-comparison.txt - -# Inspect security settings -echo "" | tee -a analysis/deployment-comparison.txt -echo "=== Security Configurations ===" | tee -a analysis/deployment-comparison.txt -for container in juice-default juice-hardened juice-production; do - echo "" | tee -a analysis/deployment-comparison.txt - echo "Container: $container" | tee -a analysis/deployment-comparison.txt - docker inspect $container --format 'CapDrop: {{.HostConfig.CapDrop}} -SecurityOpt: {{.HostConfig.SecurityOpt}} -Memory: {{.HostConfig.Memory}} -CPU: {{.HostConfig.CpuQuota}} -PIDs: {{.HostConfig.PidsLimit}} -Restart: {{.HostConfig.RestartPolicy.Name}}' | tee -a analysis/deployment-comparison.txt -done -``` - -#### 3.3: Cleanup - -```bash -docker stop juice-default juice-hardened juice-production -docker rm juice-default juice-hardened juice-production -``` - -**📊 Document in `labs/submission7.md`:** - -#### 1. Configuration Comparison Table - -Create a table from `docker inspect` output comparing all three profiles: -- Capabilities (dropped/added) -- Security options -- Resource limits (memory, CPU, PIDs) -- Restart policy - -#### 2. Security Measure Analysis - -Research and explain EACH security flag: - -**a) `--cap-drop=ALL` and `--cap-add=NET_BIND_SERVICE`** -- What are Linux capabilities? (Research this!) -- What attack vector does dropping ALL capabilities prevent? -- Why do we need to add back NET_BIND_SERVICE? -- What's the security trade-off? - -**b) `--security-opt=no-new-privileges`** -- What does this flag do? (Look it up!) -- What type of attack does it prevent? -- Are there any downsides to enabling it? - -**c) `--memory=512m` and `--cpus=1.0`** -- What happens if a container doesn't have resource limits? -- What attack does memory limiting prevent? -- What's the risk of setting limits too low? - -**d) `--pids-limit=100`** -- What is a fork bomb? -- How does PID limiting help? -- How to determine the right limit? - -**e) `--restart=on-failure:3`** -- What does this policy do? -- When is auto-restart beneficial? When is it risky? -- Compare `on-failure` vs `always` - -#### 3. Critical Thinking Questions - -1. **Which profile for DEVELOPMENT? Why?** - -2. **Which profile for PRODUCTION? Why?** - -3. **What real-world problem do resource limits solve?** - -4. **If an attacker exploits Default vs Production, what actions are blocked in Production?** - -5. **What additional hardening would you add?** - - ---- - -## Acceptance Criteria - -- ✅ Branch `feature/lab7` exists with commits for each task -- ✅ File `labs/submission7.md` contains required analysis for Tasks 1-3 -- ✅ Vulnerability scanning completed with Docker Scout -- ✅ CIS Docker Benchmark audit completed -- ✅ Deployment security comparison completed -- ✅ All scan outputs committed to `labs/lab7/` -- ✅ PR from `feature/lab7` → **course repo main branch** is open -- ✅ PR link submitted via Moodle before the deadline - ---- - -## How to Submit - -1. Create a branch for this lab and push it to your fork: - - ```bash - git switch -c feature/lab7 - # create labs/submission7.md with your findings - git add labs/submission7.md labs/lab7/ - git commit -m "docs: add lab7 submission - container security analysis" - git push -u origin feature/lab7 - ``` - -2. Open a PR from your fork's `feature/lab7` branch → **course repository's main branch**. - -3. In the PR description, include: - - ```text - - [x] Task 1 done — Advanced Image Security & Configuration Analysis - - [x] Task 2 done — Docker Security Benchmarking & Assessment - - [x] Task 3 done — Secure Container Deployment Analysis - ``` - -4. **Copy the PR URL** and submit it via **Moodle before the deadline**. - ---- - -## Rubric (10 pts) - -| Criterion | Points | -| ---------------------------------------------------------------- | -----: | -| Task 1 — Image vulnerability & configuration analysis | **3** | -| Task 2 — Docker host security benchmarking | **3** | -| Task 3 — Deployment security configuration analysis | **4** | -| **Total** | **10** | - ---- - -## Guidelines - -- Use clear Markdown headers to organize sections in `submission7.md` -- Include evidence from tool outputs to support your analysis -- Research security concepts thoroughly—don't copy-paste -- Focus on understanding trade-offs between security and usability - -
-Container Security Resources - -**Documentation:** -- [Docker Security](https://docs.docker.com/engine/security/) -- [CIS Docker Benchmark](https://www.cisecurity.org/benchmark/docker) -- [Linux Capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html) - -
- -
-Expected Security Findings - -**Image Vulnerabilities:** -- Outdated base packages with CVEs -- Vulnerable dependencies -- Missing security patches - -**CIS Benchmark:** -- Insecure daemon configuration -- Missing resource limits -- Excessive privileges - -**Deployment Gaps:** -- Running as root -- Unnecessary capabilities -- No resource limits - -
\ No newline at end of file diff --git a/labs/screenshots/submission1/curl.png b/labs/screenshots/submission1/curl.png new file mode 100644 index 00000000..2faa4480 Binary files /dev/null and b/labs/screenshots/submission1/curl.png differ diff --git a/labs/screenshots/submission1/home-page.png b/labs/screenshots/submission1/home-page.png new file mode 100644 index 00000000..cb99c995 Binary files /dev/null and b/labs/screenshots/submission1/home-page.png differ diff --git a/labs/screenshots/submission1/sql-injection.png b/labs/screenshots/submission1/sql-injection.png new file mode 100644 index 00000000..4677165f Binary files /dev/null and b/labs/screenshots/submission1/sql-injection.png differ diff --git a/labs/screenshots/submission3/blocked-commit.png b/labs/screenshots/submission3/blocked-commit.png new file mode 100644 index 00000000..03c7809c Binary files /dev/null and b/labs/screenshots/submission3/blocked-commit.png differ diff --git a/labs/screenshots/submission3/signing-key.png b/labs/screenshots/submission3/signing-key.png new file mode 100644 index 00000000..288474cb Binary files /dev/null and b/labs/screenshots/submission3/signing-key.png differ diff --git a/labs/screenshots/submission3/success-commit.png b/labs/screenshots/submission3/success-commit.png new file mode 100644 index 00000000..1b55f6b5 Binary files /dev/null and b/labs/screenshots/submission3/success-commit.png differ diff --git a/labs/screenshots/submission3/verified-commit.png b/labs/screenshots/submission3/verified-commit.png new file mode 100644 index 00000000..c5f8b126 Binary files /dev/null and b/labs/screenshots/submission3/verified-commit.png differ diff --git a/labs/submission1.md b/labs/submission1.md new file mode 100644 index 00000000..366bf196 --- /dev/null +++ b/labs/submission1.md @@ -0,0 +1,52 @@ +# Triage Report — OWASP Juice Shop + +## Scope & Asset +- Asset: OWASP Juice Shop (local lab instance) +- Image: bkimminich/juice-shop:v19.0.0 +- Release link/date: [link](https://hub.docker.com/layers/bkimminich/juice-shop/v19.0.0/images/sha256-547bd3fef4a6d7e25e131da68f454e6dc4a59d281f8793df6853e6796c9bbf58) — 4 sept 2025 +- Image digest (optional): `sha256:547bd3fef4a6d7e25e131da68f454e6dc4a59d281f8793df6853e6796c9bbf58` + +## Environment +- Host OS: `macOS 26.2` +- Docker: 29.1.3 + +## 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 [V] Yes [ ] No (explain if No) + +## Health Check +- Page load: + +![Home page](./screenshots/submission1/home-page.png) + +- API check: first 5–10 lines from `curl -s http://127.0.0.1:3000/rest/products | head` + +``` + + + + Error: Unexpected path: /rest/products +