From 0c988112903874d03ae550242de4cd1d24ae7358 Mon Sep 17 00:00:00 2001 From: Veronika Gorbatovskaia Date: Fri, 12 Jun 2026 07:11:03 +1000 Subject: [PATCH 1/3] lab1 - Juice Shop deploy + PR template + triage report --- .github/PULL_REQUEST_TEMPLATE.md | 23 ++++++ .github/workflows/lab1-smoke.yaml | 41 ++++++++++ submissions/lab1.md | 128 ++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/workflows/lab1-smoke.yaml 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..7ba4847f3 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,23 @@ +## Goal + +## Changes + +- + +## Testing + +``` + +``` + +--- + +## Artifacts & Screenshots + +- + +### Checklist + +- [ ] Title is clear (`feat(labN): `) +- [ ] No secrets/large temp files committed +- [ ] `submissions/labN.md` exists diff --git a/.github/workflows/lab1-smoke.yaml b/.github/workflows/lab1-smoke.yaml new file mode 100644 index 000000000..851d8d286 --- /dev/null +++ b/.github/workflows/lab1-smoke.yaml @@ -0,0 +1,41 @@ +name: Lab 1 — Juice Shop Smoke Test + +on: + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + smoke-test: + runs-on: ubuntu-latest + services: + juice-shop: + image: bkimminich/juice-shop:v20.0.0 + ports: + - 3000:3000 + steps: + - name: Wait for Juice Shop to be healthy + run: | + for i in $(seq 1 30); do + echo "Attempt $i/30..." + if curl --silent --fail http://localhost:3000/rest/admin/application-version; then + echo "" + echo "Juice Shop is healthy" + exit 0 + fi + sleep 2 + done + echo "Juice Shop failed to start within 60s" + exit 1 + + - name: Verify homepage returns 200 + run: | + HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000) + echo "Homepage HTTP status: $HTTP_CODE" + if [ "$HTTP_CODE" != "200" ]; then + echo "Expected 200, got $HTTP_CODE" + exit 1 + fi + echo "Homepage OK" diff --git a/submissions/lab1.md b/submissions/lab1.md new file mode 100644 index 000000000..9120a8552 --- /dev/null +++ b/submissions/lab1.md @@ -0,0 +1,128 @@ +# 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.1.3, build f52814d + +### 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 [ ] No (explain if No) +- Container restart policy: default `no` + +### Health Check + +- HTTP code on `/`: 200 +- API check (first 200 chars of `/rest/products`): 46 products +- Container uptime: + +``` +NAMES STATUS PORTS +juice-shop Up 11 minutes 127.0.0.1:3000->3000/tcp +``` + +### Initial Surface Snapshot (from browser exploration) + +- Login/Registration visible: [x] Yes [ ] No — notes: Account menu top-right, Login + Register forms functional +- Product listing/search present: [x] Yes [ ] No — notes: Grid view with search bar, 46 products loaded +- Admin or account area discoverable: [x] Yes [ ] No — notes: `/administration` hinted in page source, no access control visible +- Client-side errors in DevTools console: [ ] Yes [x] No — notes: console clean on landing +- Pre-populated local storage / cookies: token, bid, email keys present with placeholder values; welcomebanner_status = dismiss. In cookies was found language cookie with value en. + +### Security Headers (Quick Look) + +Run: `curl -I http://127.0.0.1:3000 2>&1 | head -20`. Paste output: + +``` + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 0 9903 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 +HTTP/1.1 200 OK +Access-Control-Allow-Origin: * +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +Feature-Policy: payment 'self' +X-Recruiting: /#/jobs +Accept-Ranges: bytes +Cache-Control: public, max-age=0 +Last-Modified: Thu, 11 Jun 2026 18:32:39 GMT +ETag: W/"26af-19eb7f52f1f" +Content-Type: text/html; charset=UTF-8 +Content-Length: 9903 +Vary: Accept-Encoding +Date: Thu, 11 Jun 2026 19:20:21 GMT +Connection: keep-alive +Keep-Alive: timeout=5 +``` + +Which of these are MISSING? (cross-reference Lecture 1 OWASP Top 10:2025 — A06) + +- [x] `Content-Security-Policy` +- [x] `Strict-Transport-Security` +- [ ] `X-Content-Type-Options: nosniff` +- [ ] `X-Frame-Options` + +### Top 3 Risks Observed (2-3 sentences each, in your own words) + +1. — No CSP, HSTS, or clickjacking protection. Any XSS payload injected will execute without browser-enforced restrictions. The X-Recruitment header leaks internal tech stack (Express). +2. — `/administration` path is referenced in client-side code with no server-side enforcement. The app trusts client-side visibility to hide admin functions. An attacker enumerating paths or reading page source lands directly on administrative controls — classic direct object reference pattern. +3. — tdoken and email keys in localStorage with placeholder values suggest stateless JWT-based auth persisted client-side. No HttpOnly/Secure flags possible in localStorage. Any XSS instantly steals session tokens. + +### 1.4: Cleanup (when done) + +```bash +docker stop juice-shop +# Keep the container around for future labs — Lab 4 (SBOM), Lab 5 (SAST/DAST), Lab 7 (image scan) all use it +# To remove: docker rm juice-shop +``` + +## PR Template Setup + +- File: `.github/PULL_REQUEST_TEMPLATE.md` +- Sections included: Goal / Changes / Testing / Artifacts & Screenshots +- Checklist items: +- [x] Title is clear (`feat(lab1): Triage Report: OWASP Juice Shop`) +- [x] No secrets/large temp files committed +- [x] `submissions/lab1.md` exists +- Auto-fill verified: [x] Yes — PR description showed my template (open the PR from feature/lab1) + +### Task 3 — GitHub Community Engagement (1 pt) + +### Actions completed + +1. [x] Starred [inno-devops-labs/DevSecOps-Intro](https://github.com/inno-devops-labs/DevSecOps-Intro) +2. [x] Starred [simple-container-com/api](https://github.com/simple-container-com/api) +3. Following professor and TAs on GitHub: + - [x] [@Cre-eD](https://github.com/Cre-eD) (professor) + - [x] [@Naghme98](https://github.com/Naghme98) (TA) + - [x] [@pierrepicaud](https://github.com/pierrepicaud) (TA) + +- Following 3 classmates: + - [x] [@m1d0rfeed](https://github.com/m1d0rfeed) + - [x] [@Meliman1000-7](https://github.com/Meliman1000-7) + - [x] [@RC-5555](https://github.com/labRC-5555) + +### Why stars matter + +Starring repositories helps projects find their audience and contributors, while also showing maintainers that their work matters. + +Following developers keeps you informed about their activity, lays the groundwork for collaboration, and exposes you to approaches that accelerate your professional growth. + +## Bonus: CI Smoke Test + +- Workflow file: `.github/workflows/lab1-smoke.yml` +- Trigger: `pull_request` on main +- Run URL (must be green): [](https://github.com/AskoRBINKAs/DevSecOps-Intro/actions/runs/27238144616/job/80435256342) +- Workflow run duration: +- Curl response excerpt: + +``` + +``` From 055c13a10ee785f05c527b780310b49420181a05 Mon Sep 17 00:00:00 2001 From: Veronika Gorbatovskaia Date: Fri, 12 Jun 2026 07:28:05 +1000 Subject: [PATCH 2/3] =?UTF-8?q?lab1=20-=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D1=82=D1=8C=20lab1-smoke.yaml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/lab1-smoke.yaml | 44 ++++++++++++++++++------------- submissions/lab1.md | 2 +- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/.github/workflows/lab1-smoke.yaml b/.github/workflows/lab1-smoke.yaml index 851d8d286..79b92fda8 100644 --- a/.github/workflows/lab1-smoke.yaml +++ b/.github/workflows/lab1-smoke.yaml @@ -8,34 +8,40 @@ permissions: contents: read jobs: - smoke-test: + smoke: + name: Smoke-test Juice Shop runs-on: ubuntu-latest - services: - juice-shop: - image: bkimminich/juice-shop:v20.0.0 - ports: - - 3000:3000 steps: - - name: Wait for Juice Shop to be healthy + - name: Checkout + uses: actions/checkout@v4 + + - name: Run Juice Shop container + run: | + docker run -d --name juice-shop -p 3000:3000 bkimminich/juice-shop:v20.0.0 + + - name: Wait for Juice Shop to respond run: | for i in $(seq 1 30); do echo "Attempt $i/30..." - if curl --silent --fail http://localhost:3000/rest/admin/application-version; then - echo "" - echo "Juice Shop is healthy" + if curl --silent --fail http://localhost:3000/rest/admin/application-version >/dev/null 2>&1; then + echo "✅ Juice Shop healthy on attempt $i" exit 0 fi sleep 2 done - echo "Juice Shop failed to start within 60s" + echo "❌ Juice Shop did not become healthy" + docker logs juice-shop || true exit 1 - - name: Verify homepage returns 200 + - name: Curl homepage + run: | + echo "=== Response headers ===" + curl --silent --fail -I http://localhost:3000 2>&1 | head -n 20 + echo "" + echo "=== Version check ===" + curl --silent --fail http://localhost:3000/rest/admin/application-version + + - name: Stop container + if: always() run: | - HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000) - echo "Homepage HTTP status: $HTTP_CODE" - if [ "$HTTP_CODE" != "200" ]; then - echo "Expected 200, got $HTTP_CODE" - exit 1 - fi - echo "Homepage OK" + docker stop juice-shop || true diff --git a/submissions/lab1.md b/submissions/lab1.md index 9120a8552..cecef1bae 100644 --- a/submissions/lab1.md +++ b/submissions/lab1.md @@ -119,7 +119,7 @@ Following developers keeps you informed about their activity, lays the groundwor - Workflow file: `.github/workflows/lab1-smoke.yml` - Trigger: `pull_request` on main -- Run URL (must be green): [](https://github.com/AskoRBINKAs/DevSecOps-Intro/actions/runs/27238144616/job/80435256342) +- Run URL (must be green): [](https://github.com/Maflock/DevSecOps-Intro/actions/runs/27378047940/job/80907374905) - Workflow run duration: - Curl response excerpt: From b359be5bcbd9022840fe491c7ca46a5e91ec8ebd Mon Sep 17 00:00:00 2001 From: Veronika Gorbatovskaia Date: Fri, 12 Jun 2026 07:32:09 +1000 Subject: [PATCH 3/3] lab1 - fix triage report --- submissions/lab1.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/submissions/lab1.md b/submissions/lab1.md index cecef1bae..c45d15aaa 100644 --- a/submissions/lab1.md +++ b/submissions/lab1.md @@ -119,10 +119,25 @@ Following developers keeps you informed about their activity, lays the groundwor - Workflow file: `.github/workflows/lab1-smoke.yml` - Trigger: `pull_request` on main -- Run URL (must be green): [](https://github.com/Maflock/DevSecOps-Intro/actions/runs/27378047940/job/80907374905) -- Workflow run duration: +- Run URL (must be green): [](https://github.com/Maflock/DevSecOps-Intro/actions/runs/27378571404/job/80909140566) +- Workflow run duration: 29s - Curl response excerpt: ``` - +HTTP/1.1 200 OK +Access-Control-Allow-Origin: * +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +Feature-Policy: payment 'self' +X-Recruiting: /#/jobs +Accept-Ranges: bytes +Cache-Control: public, max-age=0 +Last-Modified: Thu, 11 Jun 2026 21:28:49 GMT +ETag: W/"26af-19eb89678fe" +Content-Type: text/html; charset=UTF-8 +Content-Length: 9903 +Vary: Accept-Encoding +Date: Thu, 11 Jun 2026 21:28:51 GMT +Connection: keep-alive +Keep-Alive: timeout=5 ```