diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..8e755f44 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,18 @@ +## Goal + + +## Changes + + +## Testing + + +## Artifacts & Screenshots + + +--- + +### Checklist +- [ ] PR title is clear and descriptive +- [ ] Documentation updated if needed +- [ ] No secrets or large temporary files included diff --git a/labs/lab12/scripts/configure-containerd-kata.sh b/labs/lab12/scripts/configure-containerd-kata.sh old mode 100755 new mode 100644 diff --git a/labs/lab12/scripts/install-kata-assets.sh b/labs/lab12/scripts/install-kata-assets.sh old mode 100755 new mode 100644 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..b46c22e4 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..439d9385 --- /dev/null +++ b/labs/lab2/baseline/risks.json @@ -0,0 +1 @@ +[{"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":"unencrypted-communication","risk_status":"unchecked","severity":"elevated","exploitation_likelihood":"likely","exploitation_impact":"medium","title":"\u003cb\u003eUnencrypted Communication\u003c/b\u003e named \u003cb\u003eTo App\u003c/b\u003e between \u003cb\u003eReverse Proxy\u003c/b\u003e and \u003cb\u003eJuice Shop Application\u003c/b\u003e","synthetic_id":"unencrypted-communication@reverse-proxy\u003eto-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\u003eto-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":"\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":"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":"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":"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"]},{"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":"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"]},{"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":"unencrypted-asset","risk_status":"unchecked","severity":"medium","exploitation_likelihood":"unlikely","exploitation_impact":"medium","title":"\u003cb\u003eUnencrypted Technical Asset\u003c/b\u003e named \u003cb\u003ePersistent Storage\u003c/b\u003e","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","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":"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":"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":"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":[]}] \ 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/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..0a3b1b8b 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..dacb0180 --- /dev/null +++ b/labs/lab2/secure/risks.json @@ -0,0 +1 @@ +[{"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":"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":"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":"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":"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":"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":"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-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-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-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-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":"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"]}] \ 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..78a42d9d --- /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 with transparent encryption layer – provides additional protection for 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 (HTTPS 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 (HTTPS 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..f300675b --- /dev/null +++ b/labs/lab2/threagile-model.secure.yaml @@ -0,0 +1,360 @@ +threagile_version: 1.0.0 + +title: OWASP Juice Shop — Local Lab Threat Model (Secure Variant) +date: 2026-02-16 + +business_criticality: important + +# ========================= +# 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 (HTTPS 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 (HTTPS 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 with transparent encryption layer – provides additional protection for 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/submission1.md b/labs/submission1.md new file mode 100644 index 00000000..bb28a003 --- /dev/null +++ b/labs/submission1.md @@ -0,0 +1,45 @@ +# Triage Report — OWASP Juice Shop + +## Scope & Asset +- Asset: OWASP Juice Shop (local lab instance) +- Image: bkimminich/juice-shop:v19.0.0 +- Release link: https://hub.docker.com/r/bkimminich/juice-shop +- Image digest (optional): sha256:37cc73163c4c269c044e890fee868d62637109cad126a26dab13dc442ef2ae76 + +## Environment +- Host OS: Ubuntu 24.04 +- Docker: 28.3.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 [x] Yes [ ] No (explain if No) + +## Health Check +- Page load: +![alt text](../screenshots/page_load.png) +- API check: first 5–10 lines from `curl -s http://127.0.0.1:3000/rest/products | head`\ +This path is wrong. I checked API and found path for products: `/api/products`./ +![alt text](../screenshots/api_check.png) + +## Surface Snapshot (Triage) +- Login/Registration visible: [x] Yes [ ] No +![alt text](../screenshots/login.png) +- Product listing/search present: [x] Yes [ ] No +![alt text](../screenshots/products.png) +- Admin or account area discoverable: [X] Yes [ ] No +![alt text](../screenshots/account.png) +- Client-side errors in console: [X] Yes [ ] No +![alt text](../screenshots/errors.png) +- Security headers (quick look — optional): `curl -I http://127.0.0.1:3000` → CSP/HSTS present? +![alt text](../screenshots/headers.png) + +## Risks Observed (Top 3) +1) Injection (login as an admin) +2) DOM XSS (weakness in search panel) +3) Miscellaneous (privacy policy works without confirmation) + +6. GitHub Community +Starring repositories in open source helps acknowledge maintainers' work, increases project visibility, and encourages continued development by signaling community interest. It also helps developers bookmark useful projects for future reference. + +Following developers on GitHub makes it easier to track their work, learn from their coding practices, and stay updated on technologies relevant to team projects and professional growth. \ No newline at end of file diff --git a/labs/submission2.md b/labs/submission2.md new file mode 100644 index 00000000..f099fdbf --- /dev/null +++ b/labs/submission2.md @@ -0,0 +1,109 @@ +# Lab 2 Submission: Threat Modeling with Threagile + +## Task 1: Threagile Baseline Model + +### Generated Artifacts + +Baseline threat model generated from `labs/lab2/threagile-model.yaml`: +- ✅ `labs/lab2/baseline/report.pdf` — Threat report with embedded diagrams +- ✅ `data-flow-diagram.png`, `data-asset-diagram.png` +- ✅ `risks.json`, `stats.json`, `technical-assets.json` + +### Risk Ranking Methodology + +Composite scores calculated using: +- **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) +- **Composite Score**: `Severity × 100 + Likelihood × 10 + Impact` + +### Top 5 Risks + +| Rank | Category | Asset | Severity | Likelihood | Impact | Score | +|---:|---|---|---|---|---|---:| +| 1 | Unencrypted Communication | User Browser → Juice Shop | elevated | likely | high | **433** | +| 2 | Unencrypted Communication | Reverse Proxy → Juice Shop | elevated | likely | medium | **432** | +| 3 | Missing Authentication | Reverse Proxy → Juice Shop | elevated | likely | medium | **432** | +| 4 | Cross-Site Scripting (XSS) | Juice Shop Application | elevated | likely | medium | **432** | +| 5 | Cross-Site Request Forgery (CSRF) | Juice Shop Application | medium | very-likely | low | **241** | + +### Critical Security Findings + +**Elevated Severity Issues:** +- **Unencrypted Communication (Direct to App)**: HTTP on port 3000 transmits credentials/tokens in cleartext → MITM risk +- **Unencrypted Communication (Proxy to App)**: Internal communication uses unencrypted HTTP → lateral movement risk +- **Missing Authentication (Proxy to App)**: No auth between reverse proxy and app → spoofing risk +- **Cross-Site Scripting (XSS)**: Inadequate input validation → session hijacking risk + +**Risk Distribution**: 23 total risks (13% elevated, 61% medium, 26% low) + + +## Task 2: HTTPS Variant & Risk Comparison + +### Secure Model Changes + +File: `labs/lab2/threagile-model.secure.yaml` + +Changes made: +1. User Browser → Direct to App: `http` → `https` +2. Reverse Proxy → To App: `http` → `https` +3. Persistent Storage: encryption `none` → `transparent` + +### Generated Artifacts + +- ✅ `labs/lab2/secure/report.pdf` — Updated threat report +- ✅ `data-flow-diagram.png`, `data-asset-diagram.png` +- ✅ `risks.json`, `stats.json`, `technical-assets.json` + +### Risk Category Delta Comparison + +| Category | Baseline | Secure | Delta | +|---|---:|---:|---:| +| 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 | + +**Summary**: Baseline 23 risks → Secure 20 risks (**-3 risks / -13% reduction**) + +### Delta Run Explanation + +**Eliminated Risks: Unencrypted Communication (-2)** +- Changed HTTP → HTTPS on user-browser→app and proxy→app connections +- Eliminates cleartext credential transmission (eliminates MITM attack vectors) +- These were the #1 and #2 highest-scoring risks (433 and 432 composite scores) + +**Reduced Risks: Unencrypted Asset (-1)** +- Changed Persistent Storage encryption from `none` → `transparent` +- Protects data at rest (database, uploads, logs) +- Reduces offline filesystem attack risk + +**Unchanged Risks (14 categories)** +- Application-level vulnerabilities (XSS, CSRF, SSRF) remain unchanged because they require code fixes, not deployment changes +- Missing architectural controls (WAF, vault, identity store) unchanged +- Encryption alone does not address logic-level flaws in the application + +**Key Finding**: 13% risk reduction demonstrates encryption in transit is critical for eliminating high-impact threats, but application hardening and security architecture improvements remain necessary for comprehensive protection. + +### Diagram Comparison + +**Baseline Diagrams** (`labs/lab2/baseline/`): +- **Data Flow Diagram**: Shows HTTP flows with unencrypted communication links +- **Data Asset Diagram**: Sensitive data flowing through unencrypted channels + +**Secure Variant Diagrams** (`labs/lab2/secure/`): +- **Data Flow Diagram**: Updated with HTTPS on user-browser→app and proxy→app connections +- **Data Asset Diagram**: Same assets with encrypted channel indicators and transparent storage encryption + +**Observation**: Encryption controls are visually reflected in diagrams, confirming the security improvements quantified in the risk analysis. diff --git a/screenshots/account.png b/screenshots/account.png new file mode 100644 index 00000000..c1557567 Binary files /dev/null and b/screenshots/account.png differ diff --git a/screenshots/api_check.png b/screenshots/api_check.png new file mode 100644 index 00000000..7208e524 Binary files /dev/null and b/screenshots/api_check.png differ diff --git a/screenshots/errors.png b/screenshots/errors.png new file mode 100644 index 00000000..0535b0f4 Binary files /dev/null and b/screenshots/errors.png differ diff --git a/screenshots/headers.png b/screenshots/headers.png new file mode 100644 index 00000000..b7f7f95b Binary files /dev/null and b/screenshots/headers.png differ diff --git a/screenshots/login.png b/screenshots/login.png new file mode 100644 index 00000000..572b5327 Binary files /dev/null and b/screenshots/login.png differ diff --git a/screenshots/page_load.png b/screenshots/page_load.png new file mode 100644 index 00000000..fc209ed7 Binary files /dev/null and b/screenshots/page_load.png differ diff --git a/screenshots/products.png b/screenshots/products.png new file mode 100644 index 00000000..c0dcd4be Binary files /dev/null and b/screenshots/products.png differ