From dbe714c86d276cd1bbc83c312b78467605fb9e0f Mon Sep 17 00:00:00 2001 From: Meliman1000-7 Date: Thu, 11 Jun 2026 17:16:10 +0300 Subject: [PATCH 1/7] feat(lab1): juice shop deploy + PR template + triage report --- .github/PULL_REQUEST_TEMPLATE.md | 34 ++++++++++ .github/workflows/lab1-smoke.yml | 34 ++++++++++ submissions/lab1.md | 106 +++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/workflows/lab1-smoke.yml create mode 100644 submissions/lab1.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..72a56e2bd --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,34 @@ +## Goal + + + + + +## Changes + + + +* + +## Testing + + + +``` + +``` + +## Artifacts \& Screenshots + + + +* [`submissions/labN.md`](submissions/labN.md) + +\--- + +## Checklist + +* \[ ] Title is clear (`feat(labN): ` style) +* \[ ] No secrets or large temp files committed +* \[ ] Submission file at `submissions/labN.md` exists + diff --git a/.github/workflows/lab1-smoke.yml b/.github/workflows/lab1-smoke.yml new file mode 100644 index 000000000..e46a3248a --- /dev/null +++ b/.github/workflows/lab1-smoke.yml @@ -0,0 +1,34 @@ +name: Lab 1 — Juice Shop Smoke Test + +on: + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + smoke-test: + runs-on: ubuntu-latest + + steps: + - name: Start Juice Shop + run: | + docker run -d --name juice-shop \ + -p 127.0.0.1:3000:3000 \ + bkimminich/juice-shop:v20.0.0 + + - name: Wait for Juice Shop to be ready (up to 60s) + run: | + for i in $(seq 1 30); do + curl --silent --fail http://127.0.0.1:3000/rest/admin/application-version > /dev/null && exit 0 + sleep 2 + done + docker logs juice-shop + exit 1 + + - name: Verify homepage returns HTTP 200 + run: | + STATUS=$(curl --silent --output /dev/null --write-out "%{http_code}" http://127.0.0.1:3000) + echo "HTTP status: $STATUS" + [ "$STATUS" = "200" ] diff --git a/submissions/lab1.md b/submissions/lab1.md new file mode 100644 index 000000000..48a8b5385 --- /dev/null +++ b/submissions/lab1.md @@ -0,0 +1,106 @@ +# Lab 1 — Submission + +## Triage Report: OWASP Juice Shop + +### Scope \& Asset + +* Asset: OWASP Juice Shop (local lab instance) +* Image: `bkimminich/juice-shop:v20.0.0` +* Image digest: `sha256:fd58bdc9745416afce8184ee0666278a436574633ea7880365153a63bfd418b0` +* Host OS: Windows 11 +* Docker version: Docker version 29.4.2, build 055a478 + +### Deployment Details + +* Run command used: `docker run -d --name juice-shop -p 127.0.0.1:3000:3000 bkimminich/juice-shop:v20.0.0` +* Access URL: http://127.0.0.1:3000 +* Network exposure: 127.0.0.1 only? \[x] Yes +* Container restart policy: default (`no` — no `--restart` flag was specified) + +### Health Check + +* HTTP code on `/`: 200 +* Product count from `/api/Products`: 46 items returned +* Container uptime (from `docker ps`): + +``` + NAMES STATUS PORTS + juice-shop Up 12 minutes 127.0.0.1:3000->3000/tcp + ``` + +* Version check (`/rest/admin/application-version`): + +```json + {"version":"20.0.0"} + ``` + +### Initial Surface Snapshot (from browser exploration) + +* Login/Registration visible: \[x] Yes — Account menu (top-right) leads to `/#/login`; registration available from the login page +* Product listing/search present: \[x] Yes — product grid loads on the homepage with images, prices, and add-to-cart buttons +* Admin or account area discoverable: \[x] Yes — Account menu is visible without authentication; admin panel path (`/#/administration`) is discoverable via JavaScript source +* Client-side errors in DevTools console: \[x] No — Firefox DevTools console showed no errors on page load +* Pre-populated local storage / cookies: Two cookies set automatically on first visit: + + * `language=en` — stores the selected UI language + * `welcomebanner\_status=dismiss` — tracks dismissal of the welcome banner + +### Network Observations (from Firefox DevTools → Network tab) + +* `GET /rest/user/whoami?fields=email` — returns `304 Not Modified` (cached); called on every page load **without requiring authentication**, leaking the unauthenticated state check +* `GET /rest/products/1/reviews` — returns `200 OK`; product reviews are **publicly accessible without any authentication token**, returning full review data including user identifiers + +### Security Headers (from `Invoke-WebRequest` response headers) + +``` +Access-Control-Allow-Origin : \* +X-Content-Type-Options : nosniff +X-Frame-Options : SAMEORIGIN +Feature-Policy : payment 'self' +X-Recruiting : /#/jobs +Content-Type : text/html; charset=UTF-8 +Cache-Control : public, max-age=0 +``` + +Headers that are **MISSING** (cross-referenced with OWASP Top 10:2025 — A05: Security Misconfiguration): + +* \[x] `Content-Security-Policy` — **MISSING** +* \[x] `Strict-Transport-Security` — **MISSING** (app runs over plain HTTP) +* \[ ] `X-Content-Type-Options: nosniff` — present ✅ +* \[ ] `X-Frame-Options` — present (`SAMEORIGIN`) ✅ + +Additional concern: `Access-Control-Allow-Origin: \*` is a wildcard CORS policy, meaning any origin can make cross-origin requests to this API. + +### Top 3 Risks Observed + +1. **Missing Content-Security-Policy** — The application does not set a `Content-Security-Policy` header, meaning the browser applies no restrictions on which scripts, styles, or frames can be loaded. An attacker who injects malicious JavaScript (e.g., via a stored XSS payload in a product review) can execute arbitrary code in any victim's browser with no CSP barrier. Maps to **A05:2025 – Security Misconfiguration**. +2. **Unauthenticated Access to Reviews and User Endpoints** — The `/rest/products//reviews` endpoint returns full review data including user references with no authentication required, and `/rest/user/whoami` is queried on every page load without a token. This exposes internal user data and API structure to any unauthenticated visitor or automated scanner. Maps to **A01:2025 – Broken Access Control**. +3. **Wildcard CORS Policy** — Every API response includes Access-Control-Allow-Origin: \*, allowing any website to read API responses from a victim's browser via cross-origin requests. Combined with unauthenticated endpoints, a malicious page can silently enumerate products, read reviews, and probe the API structure on behalf of any visitor — no user interaction required beyond visiting the attacker's site. Maps to A05:2025 – Security Misconfiguration. + +\--- + +## PR Template Setup + +* File: `.github/PULL\_REQUEST\_TEMPLATE.md` +* Sections included: Goal / Changes / Testing / Artifacts \& Screenshots +* Checklist items: + + * \[ ] Title is clear (`feat(labN): ` style) + * \[ ] No secrets or large temp files committed + * \[ ] Submission file at `submissions/labN.md` exists +* Auto-fill verified: \[x] Yes — PR description showed the template automatically when opening the PR from `feature/lab1` + +\--- + +## Bonus: CI Smoke Test + +* Workflow file: `.github/workflows/lab1-smoke.yml` +* Trigger: `pull\_request` on `main` +* Run URL (must be green): ** +* Workflow run duration: ** +* Curl response excerpt: + +``` + {"version":"20.0.0"} + ``` + From b1b9336fff4c2206aeef872ce1b97de1820ae202 Mon Sep 17 00:00:00 2001 From: Meliman1000-7 <84561726+Meliman1000-7@users.noreply.github.com> Date: Thu, 11 Jun 2026 21:40:28 +0300 Subject: [PATCH 2/7] fix(lab1): fix placeholder link in PR template --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 72a56e2bd..27245f336 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -22,7 +22,7 @@ -* [`submissions/labN.md`](submissions/labN.md) +* [`submissions/labN.md`](submissions/lab1.md) \--- From 10313457f175bf1fbd79eeac793e2d5318650fb9 Mon Sep 17 00:00:00 2001 From: Meliman1000-7 <84561726+Meliman1000-7@users.noreply.github.com> Date: Thu, 11 Jun 2026 21:42:47 +0300 Subject: [PATCH 3/7] fix(lab1): fix placeholder link in PR template --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 27245f336..bfab87ea2 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -22,7 +22,7 @@ -* [`submissions/labN.md`](submissions/lab1.md) +- `submissions/labN.md` \--- From c45b8980587d8f392b9b75798f0c18875f11ce93 Mon Sep 17 00:00:00 2001 From: Meliman1000-7 <84561726+Meliman1000-7@users.noreply.github.com> Date: Thu, 11 Jun 2026 22:04:00 +0300 Subject: [PATCH 4/7] Include GitHub Community information in lab1.md --- submissions/lab1.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/submissions/lab1.md b/submissions/lab1.md index 48a8b5385..dfc8df554 100644 --- a/submissions/lab1.md +++ b/submissions/lab1.md @@ -92,6 +92,13 @@ Additional concern: `Access-Control-Allow-Origin: \*` is a wildcard CORS policy, \--- +## GitHub Community + +Starring a repository bookmarks it for later and signals community trust — +star count is a common indicator of a project's popularity and adoption. +Following professors, TAs, and classmates surfaces their activity in your feed, +making it easy to discover new tools and stay updated on each other's work. + ## Bonus: CI Smoke Test * Workflow file: `.github/workflows/lab1-smoke.yml` From 6695e9a9b6af5ce16431c679db60c18bbb9b99b5 Mon Sep 17 00:00:00 2001 From: Meliman1000-7 <84561726+Meliman1000-7@users.noreply.github.com> Date: Thu, 11 Jun 2026 23:03:26 +0300 Subject: [PATCH 5/7] Add CI smoke test run URL and duration --- submissions/lab1.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/submissions/lab1.md b/submissions/lab1.md index dfc8df554..cc44367bd 100644 --- a/submissions/lab1.md +++ b/submissions/lab1.md @@ -103,8 +103,8 @@ making it easy to discover new tools and stay updated on each other's work. * Workflow file: `.github/workflows/lab1-smoke.yml` * Trigger: `pull\_request` on `main` -* Run URL (must be green): ** -* Workflow run duration: ** +* Run URL (must be green): https://github.com/Meliman1000-7/DevSecOps-Intro/actions/runs/27373488077 +* Workflow run duration: 21s * Curl response excerpt: ``` From ee905b80713392dc9594ff234417ff4ada879953 Mon Sep 17 00:00:00 2001 From: Meliman1000-7 <84561726+Meliman1000-7@users.noreply.github.com> Date: Fri, 12 Jun 2026 11:18:30 +0300 Subject: [PATCH 6/7] Fix markdown formatting and update deployment details --- submissions/lab1.md | 48 +++++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/submissions/lab1.md b/submissions/lab1.md index cc44367bd..bbcfbc5a0 100644 --- a/submissions/lab1.md +++ b/submissions/lab1.md @@ -14,8 +14,8 @@ * Run command used: `docker run -d --name juice-shop -p 127.0.0.1:3000:3000 bkimminich/juice-shop:v20.0.0` * Access URL: http://127.0.0.1:3000 -* Network exposure: 127.0.0.1 only? \[x] Yes -* Container restart policy: default (`no` — no `--restart` flag was specified) +* Network exposure: 127.0.0.1 only? \[x] Yes \[ ] No +* Container restart policy: default `no` ### Health Check @@ -36,24 +36,19 @@ ### Initial Surface Snapshot (from browser exploration) -* Login/Registration visible: \[x] Yes — Account menu (top-right) leads to `/#/login`; registration available from the login page -* Product listing/search present: \[x] Yes — product grid loads on the homepage with images, prices, and add-to-cart buttons -* Admin or account area discoverable: \[x] Yes — Account menu is visible without authentication; admin panel path (`/#/administration`) is discoverable via JavaScript source -* Client-side errors in DevTools console: \[x] No — Firefox DevTools console showed no errors on page load +* Login/Registration visible: \[x] Yes \[ ] No — Account menu (top-right) leads to `/#/login`; registration available from the login page +* Product listing/search present: \[x] Yes \[ ] No — product grid loads on the homepage with images, prices, and add-to-cart buttons +* Admin or account area discoverable: \[x] Yes \[ ] No — Account menu is visible without authentication; admin panel path (`/#/administration`) is discoverable via JavaScript source +* Client-side errors in DevTools console: \[ ] Yes \[x] No — Firefox DevTools console showed no errors on page load * Pre-populated local storage / cookies: Two cookies set automatically on first visit: * `language=en` — stores the selected UI language - * `welcomebanner\_status=dismiss` — tracks dismissal of the welcome banner - -### Network Observations (from Firefox DevTools → Network tab) - -* `GET /rest/user/whoami?fields=email` — returns `304 Not Modified` (cached); called on every page load **without requiring authentication**, leaking the unauthenticated state check -* `GET /rest/products/1/reviews` — returns `200 OK`; product reviews are **publicly accessible without any authentication token**, returning full review data including user identifiers + * `welcomebanner\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_status=dismiss` — tracks dismissal of the welcome banner ### Security Headers (from `Invoke-WebRequest` response headers) ``` -Access-Control-Allow-Origin : \* +Access-Control-Allow-Origin : \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* X-Content-Type-Options : nosniff X-Frame-Options : SAMEORIGIN Feature-Policy : payment 'self' @@ -66,10 +61,10 @@ Headers that are **MISSING** (cross-referenced with OWASP Top 10:2025 — A05: S * \[x] `Content-Security-Policy` — **MISSING** * \[x] `Strict-Transport-Security` — **MISSING** (app runs over plain HTTP) -* \[ ] `X-Content-Type-Options: nosniff` — present ✅ -* \[ ] `X-Frame-Options` — present (`SAMEORIGIN`) ✅ +* \[ ] `X-Content-Type-Options: nosniff` — present +* \[ ] `X-Frame-Options` — present (`SAMEORIGIN`) -Additional concern: `Access-Control-Allow-Origin: \*` is a wildcard CORS policy, meaning any origin can make cross-origin requests to this API. +Additional concern: `Access-Control-Allow-Origin: \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*` is a wildcard CORS policy, meaning any origin can make cross-origin requests to this API. ### Top 3 Risks Observed @@ -77,7 +72,6 @@ Additional concern: `Access-Control-Allow-Origin: \*` is a wildcard CORS policy, 2. **Unauthenticated Access to Reviews and User Endpoints** — The `/rest/products//reviews` endpoint returns full review data including user references with no authentication required, and `/rest/user/whoami` is queried on every page load without a token. This exposes internal user data and API structure to any unauthenticated visitor or automated scanner. Maps to **A01:2025 – Broken Access Control**. 3. **Wildcard CORS Policy** — Every API response includes Access-Control-Allow-Origin: \*, allowing any website to read API responses from a victim's browser via cross-origin requests. Combined with unauthenticated endpoints, a malicious page can silently enumerate products, read reviews, and probe the API structure on behalf of any visitor — no user interaction required beyond visiting the attacker's site. Maps to A05:2025 – Security Misconfiguration. -\--- ## PR Template Setup @@ -90,24 +84,18 @@ Additional concern: `Access-Control-Allow-Origin: \*` is a wildcard CORS policy, * \[ ] Submission file at `submissions/labN.md` exists * Auto-fill verified: \[x] Yes — PR description showed the template automatically when opening the PR from `feature/lab1` -\--- -## GitHub Community +### GitHub Community -Starring a repository bookmarks it for later and signals community trust — -star count is a common indicator of a project's popularity and adoption. -Following professors, TAs, and classmates surfaces their activity in your feed, -making it easy to discover new tools and stay updated on each other's work. +Starring a repository bookmarks it for later and signals community trust — star count is a common indicator of a project's popularity and adoption. Following professors, TAs, and classmates surfaces their activity in your feed, making it easy to discover new tools and stay updated on each other's work. ## Bonus: CI Smoke Test * Workflow file: `.github/workflows/lab1-smoke.yml` -* Trigger: `pull\_request` on `main` -* Run URL (must be green): https://github.com/Meliman1000-7/DevSecOps-Intro/actions/runs/27373488077 -* Workflow run duration: 21s +* Trigger: `pull\_request` on main +* Run URL (must be green): *https://github.com/Meliman1000-7/DevSecOps-Intro/actions/runs/27373488077* +* Workflow run duration: *21s* * Curl response excerpt: - ``` - {"version":"20.0.0"} - ``` - +HTTP status: 200 +``` From ae8fc399986d251c0d310cff3b37e428db23a9b0 Mon Sep 17 00:00:00 2001 From: Meliman1000-7 <84561726+Meliman1000-7@users.noreply.github.com> Date: Fri, 12 Jun 2026 11:19:34 +0300 Subject: [PATCH 7/7] Refine pull request template for better usability --- .github/PULL_REQUEST_TEMPLATE.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index bfab87ea2..0c9eb5964 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,12 +3,10 @@ - ## Changes -* ## Testing @@ -17,18 +15,14 @@ ``` ``` - ## Artifacts \& Screenshots -- `submissions/labN.md` - -\--- +* [`submissions/labN.md`](submissions/labN.md) ## Checklist * \[ ] Title is clear (`feat(labN): ` style) * \[ ] No secrets or large temp files committed * \[ ] Submission file at `submissions/labN.md` exists -