From 4b0b7eebed5c30000811cd01314bdfc815968936 Mon Sep 17 00:00:00 2001 From: SamiKO228 Date: Fri, 12 Jun 2026 21:01:19 +0300 Subject: [PATCH 01/10] feat(lab1): add github actions smoke test workflow --- .github/workflows/lab1-smoke.yml | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/workflows/lab1-smoke.yml diff --git a/.github/workflows/lab1-smoke.yml b/.github/workflows/lab1-smoke.yml new file mode 100644 index 000000000..d70eaaae1 --- /dev/null +++ b/.github/workflows/lab1-smoke.yml @@ -0,0 +1,40 @@ +name: Lab 1 Smoke Test + +on: + pull_request: + branches: + - main + +permissions: + contents: read + +jobs: + smoke-test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository code + uses: actions/checkout@v4 + + - name: Deploy Juice Shop Container + run: | + docker run -d --name juice-shop-ci -p 3000:3000 bkimminich/juice-shop:v20.0.0 + + - name: Wait for Juice Shop to be ready (Polling Loop) + run: | + echo "Waiting for Juice Shop to initialize..." + for i in $(seq 1 30); do + if curl --silent --fail http://localhost:3000/rest/admin/application-version > /dev/null; then + echo "Juice Shop is healthy and responding!" + exit 0 + fi + echo "Container is not ready yet, retrying in 2 seconds... ($i/30)" + sleep 2 + done + echo "Error: Juice Shop failed to start within 60 seconds." + docker logs juice-shop-ci + exit 1 + + - name: Log Health Check Response + run: | + curl -I http://localhost:3000/rest/admin/application-version \ No newline at end of file From c8ebb995162c8223ad05f2262b9e678ce13a95c9 Mon Sep 17 00:00:00 2001 From: SamiKO228 Date: Fri, 12 Jun 2026 21:27:43 +0300 Subject: [PATCH 02/10] fix(workflow): fix indentation and syntax in smoke-test --- .github/workflows/lab1-smoke.yml | 34 ++++++++++++++------------------ 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/.github/workflows/lab1-smoke.yml b/.github/workflows/lab1-smoke.yml index d70eaaae1..29977db9c 100644 --- a/.github/workflows/lab1-smoke.yml +++ b/.github/workflows/lab1-smoke.yml @@ -5,36 +5,32 @@ on: branches: - main -permissions: - contents: read - jobs: smoke-test: runs-on: ubuntu-latest + services: + juice-shop: + image: bkimminich/juice-shop:v16.0.0 + ports: + - 3000:3000 + steps: - - name: Checkout repository code + - name: Check out repository code uses: actions/checkout@v4 - - name: Deploy Juice Shop Container + - name: Wait for Juice Shop to be ready run: | - docker run -d --name juice-shop-ci -p 3000:3000 bkimminich/juice-shop:v20.0.0 - - - name: Wait for Juice Shop to be ready (Polling Loop) - run: | - echo "Waiting for Juice Shop to initialize..." - for i in $(seq 1 30); do - if curl --silent --fail http://localhost:3000/rest/admin/application-version > /dev/null; then - echo "Juice Shop is healthy and responding!" + echo "Waiting for Juice Shop to start..." + for i in {1..20}; do + if curl -s -I http://localhost:3000 | grep -q "HTTP/"; then + echo "Juice Shop is up and running!" exit 0 fi - echo "Container is not ready yet, retrying in 2 seconds... ($i/30)" - sleep 2 + sleep 3 done - echo "Error: Juice Shop failed to start within 60 seconds." - docker logs juice-shop-ci + echo "Juice Shop failed to start in time" exit 1 - name: Log Health Check Response - run: | - curl -I http://localhost:3000/rest/admin/application-version \ No newline at end of file + run: curl -I http://localhost:3000 From 727146f0d970138d9c692c79383b19941b9064d9 Mon Sep 17 00:00:00 2001 From: SamiKO228 Date: Fri, 12 Jun 2026 21:39:20 +0300 Subject: [PATCH 03/10] fix(workflow): 2nd fix indentation and syntax in smoke-test --- .github/workflows/lab1-smoke.yml | 66 ++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/.github/workflows/lab1-smoke.yml b/.github/workflows/lab1-smoke.yml index 29977db9c..fce4880ae 100644 --- a/.github/workflows/lab1-smoke.yml +++ b/.github/workflows/lab1-smoke.yml @@ -1,36 +1,70 @@ -name: Lab 1 Smoke Test +name: lab1-smoke on: pull_request: branches: - main +permissions: + contents: read + jobs: smoke-test: + name: Juice Shop smoke test runs-on: ubuntu-latest - services: - juice-shop: - image: bkimminich/juice-shop:v16.0.0 - ports: - - 3000:3000 - steps: - - name: Check out repository code + - name: Checkout repository uses: actions/checkout@v4 - - name: Wait for Juice Shop to be ready + - name: Pull and 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 (max 60s) run: | echo "Waiting for Juice Shop to start..." - for i in {1..20}; do - if curl -s -I http://localhost:3000 | grep -q "HTTP/"; then - echo "Juice Shop is up and running!" + for i in $(seq 1 30); do + if curl --silent --fail http://localhost:3000/rest/admin/application-version > /dev/null; then + echo "Juice Shop is up after $((i * 2))s" exit 0 fi - sleep 3 + echo "Attempt $i/30 — not ready yet, sleeping 2s..." + sleep 2 done - echo "Juice Shop failed to start in time" + echo "ERROR: Juice Shop did not start within 60 seconds" + docker logs juice-shop exit 1 - - name: Log Health Check Response - run: curl -I http://localhost:3000 + - name: Verify homepage returns HTTP 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 "ERROR: Expected 200, got $HTTP_CODE" + exit 1 + fi + echo "HTTP 200 confirmed — smoke test passed." + + - name: Verify version endpoint + run: | + RESPONSE=$(curl -s http://localhost:3000/rest/admin/application-version) + echo "Version endpoint response: $RESPONSE" + echo "$RESPONSE" | grep -q '"version":"20.0.0"' || (echo "ERROR: unexpected version response" && exit 1) + echo "Version check passed." + + - name: Verify product count + run: | + COUNT=$(curl -s http://localhost:3000/api/Products | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d['data']))") + echo "Product count: $COUNT" + if [ "$COUNT" -lt 1 ]; then + echo "ERROR: No products returned" + exit 1 + fi + echo "Product count check passed: $COUNT products found." + + - name: Cleanup + if: always() + run: docker rm -f juice-shop || true From 43b7c55b642b2d31228cce3a39111bae4826d723 Mon Sep 17 00:00:00 2001 From: SamiKO228 Date: Fri, 12 Jun 2026 21:43:02 +0300 Subject: [PATCH 04/10] fix(workflow): 3rd fix indentation and syntax in smoke-test --- .github/workflows/lab1-smoke.yml | 52 ++++++++------------------------ 1 file changed, 13 insertions(+), 39 deletions(-) diff --git a/.github/workflows/lab1-smoke.yml b/.github/workflows/lab1-smoke.yml index fce4880ae..1d9eefe79 100644 --- a/.github/workflows/lab1-smoke.yml +++ b/.github/workflows/lab1-smoke.yml @@ -1,4 +1,4 @@ -name: lab1-smoke +1name: Lab 1 Juice Shop Smoke Test on: pull_request: @@ -10,61 +10,35 @@ permissions: jobs: smoke-test: - name: Juice Shop smoke test runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Pull and start Juice Shop + - name: Run 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 (max 60s) + - name: Wait for Juice Shop run: | - echo "Waiting for Juice Shop to start..." for i in $(seq 1 30); do - if curl --silent --fail http://localhost:3000/rest/admin/application-version > /dev/null; then - echo "Juice Shop is up after $((i * 2))s" + if curl --silent --fail http://127.0.0.1:3000/rest/admin/application-version >/dev/null; then + echo "Juice Shop is ready after $((i * 2)) seconds" exit 0 fi - echo "Attempt $i/30 — not ready yet, sleeping 2s..." sleep 2 done - echo "ERROR: Juice Shop did not start within 60 seconds" + + echo "Juice Shop did not become ready within 60 seconds" docker logs juice-shop exit 1 - - name: Verify homepage returns HTTP 200 + - name: Verify homepage 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 "ERROR: Expected 200, got $HTTP_CODE" - exit 1 - fi - echo "HTTP 200 confirmed — smoke test passed." + http_status="$(curl --silent --output /dev/null --write-out '%{http_code}' http://127.0.0.1:3000)" + echo "Homepage HTTP status: ${http_status}" + test "${http_status}" = "200" - - name: Verify version endpoint + - name: Capture version response run: | - RESPONSE=$(curl -s http://localhost:3000/rest/admin/application-version) - echo "Version endpoint response: $RESPONSE" - echo "$RESPONSE" | grep -q '"version":"20.0.0"' || (echo "ERROR: unexpected version response" && exit 1) - echo "Version check passed." - - - name: Verify product count - run: | - COUNT=$(curl -s http://localhost:3000/api/Products | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d['data']))") - echo "Product count: $COUNT" - if [ "$COUNT" -lt 1 ]; then - echo "ERROR: No products returned" - exit 1 - fi - echo "Product count check passed: $COUNT products found." - - - name: Cleanup - if: always() - run: docker rm -f juice-shop || true + curl --include --silent --fail http://127.0.0.1:3000/rest/admin/application-version From 7dff1d218d764875d290aaf83fb90b60a0ffa9b7 Mon Sep 17 00:00:00 2001 From: SamiKO228 Date: Fri, 12 Jun 2026 21:50:50 +0300 Subject: [PATCH 05/10] fix(workflow): 4th fix indentation and syntax in smoke-test --- .github/workflows/lab1-smoke.yml | 34 ++++++++++++++------------------ 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/.github/workflows/lab1-smoke.yml b/.github/workflows/lab1-smoke.yml index 1d9eefe79..3027fa16c 100644 --- a/.github/workflows/lab1-smoke.yml +++ b/.github/workflows/lab1-smoke.yml @@ -1,4 +1,4 @@ -1name: Lab 1 Juice Shop Smoke Test +name: Lab 1 Smoke Test on: pull_request: @@ -13,32 +13,28 @@ jobs: runs-on: ubuntu-latest steps: - - name: Run Juice Shop + - name: Checkout repository code + uses: actions/checkout@v4 + + - name: Deploy Juice Shop Container run: | - docker run -d --name juice-shop \ - -p 127.0.0.1:3000:3000 \ - bkimminich/juice-shop:v20.0.0 + docker run -d --name juice-shop-ci -p 3000:3000 bkimminich/juice-shop:v20.0.0 - - name: Wait for Juice Shop + - name: Wait for Juice Shop to be ready (Polling Loop) run: | + echo "Waiting for Juice Shop to initialize..." for i in $(seq 1 30); do - if curl --silent --fail http://127.0.0.1:3000/rest/admin/application-version >/dev/null; then - echo "Juice Shop is ready after $((i * 2)) seconds" + if curl --silent --fail http://localhost:3000/rest/admin/application-version > /dev/null; then + echo "Juice Shop is healthy and responding!" exit 0 fi + echo "Container is not ready yet, retrying in 2 seconds... ($i/30)" sleep 2 done - - echo "Juice Shop did not become ready within 60 seconds" - docker logs juice-shop + echo "Error: Juice Shop failed to start within 60 seconds." + docker logs juice-shop-ci exit 1 - - name: Verify homepage - run: | - http_status="$(curl --silent --output /dev/null --write-out '%{http_code}' http://127.0.0.1:3000)" - echo "Homepage HTTP status: ${http_status}" - test "${http_status}" = "200" - - - name: Capture version response + - name: Log Health Check Response run: | - curl --include --silent --fail http://127.0.0.1:3000/rest/admin/application-version + curl -I http://localhost:3000/rest/admin/application-version From 5b210cd51eb175f14ac1c84b808d68da2474c639 Mon Sep 17 00:00:00 2001 From: SamiKO228 Date: Fri, 12 Jun 2026 21:54:29 +0300 Subject: [PATCH 06/10] fix(workflow): 5th fix indentation and syntax in smoke-test --- .github/workflows/lab1-smoke.yml | 54 +++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/.github/workflows/lab1-smoke.yml b/.github/workflows/lab1-smoke.yml index 3027fa16c..fce4880ae 100644 --- a/.github/workflows/lab1-smoke.yml +++ b/.github/workflows/lab1-smoke.yml @@ -1,4 +1,4 @@ -name: Lab 1 Smoke Test +name: lab1-smoke on: pull_request: @@ -10,31 +10,61 @@ permissions: jobs: smoke-test: + name: Juice Shop smoke test runs-on: ubuntu-latest steps: - - name: Checkout repository code + - name: Checkout repository uses: actions/checkout@v4 - - name: Deploy Juice Shop Container + - name: Pull and start Juice Shop run: | - docker run -d --name juice-shop-ci -p 3000:3000 bkimminich/juice-shop:v20.0.0 + 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 (Polling Loop) + - name: Wait for Juice Shop to be ready (max 60s) run: | - echo "Waiting for Juice Shop to initialize..." + echo "Waiting for Juice Shop to start..." for i in $(seq 1 30); do if curl --silent --fail http://localhost:3000/rest/admin/application-version > /dev/null; then - echo "Juice Shop is healthy and responding!" + echo "Juice Shop is up after $((i * 2))s" exit 0 fi - echo "Container is not ready yet, retrying in 2 seconds... ($i/30)" + echo "Attempt $i/30 — not ready yet, sleeping 2s..." sleep 2 done - echo "Error: Juice Shop failed to start within 60 seconds." - docker logs juice-shop-ci + echo "ERROR: Juice Shop did not start within 60 seconds" + docker logs juice-shop exit 1 - - name: Log Health Check Response + - name: Verify homepage returns HTTP 200 run: | - curl -I http://localhost:3000/rest/admin/application-version + 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 "ERROR: Expected 200, got $HTTP_CODE" + exit 1 + fi + echo "HTTP 200 confirmed — smoke test passed." + + - name: Verify version endpoint + run: | + RESPONSE=$(curl -s http://localhost:3000/rest/admin/application-version) + echo "Version endpoint response: $RESPONSE" + echo "$RESPONSE" | grep -q '"version":"20.0.0"' || (echo "ERROR: unexpected version response" && exit 1) + echo "Version check passed." + + - name: Verify product count + run: | + COUNT=$(curl -s http://localhost:3000/api/Products | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d['data']))") + echo "Product count: $COUNT" + if [ "$COUNT" -lt 1 ]; then + echo "ERROR: No products returned" + exit 1 + fi + echo "Product count check passed: $COUNT products found." + + - name: Cleanup + if: always() + run: docker rm -f juice-shop || true From 67ea8798e8259a9df9704090fbb08460fd504ca4 Mon Sep 17 00:00:00 2001 From: SamiKO228 Date: Fri, 12 Jun 2026 22:06:23 +0300 Subject: [PATCH 07/10] fix(workflow): 6th fix indentation and syntax in smoke-test --- .github/workflows/lab1-smoke.yml | 54 +++++++------------------------- 1 file changed, 12 insertions(+), 42 deletions(-) diff --git a/.github/workflows/lab1-smoke.yml b/.github/workflows/lab1-smoke.yml index fce4880ae..e2a779221 100644 --- a/.github/workflows/lab1-smoke.yml +++ b/.github/workflows/lab1-smoke.yml @@ -1,4 +1,4 @@ -name: lab1-smoke +name: Lab 1 Juice Shop Smoke Test on: pull_request: @@ -10,61 +10,31 @@ permissions: jobs: smoke-test: - name: Juice Shop smoke test runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Pull and start Juice Shop + - name: Run 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 (max 60s) + - name: Wait for Juice Shop run: | - echo "Waiting for Juice Shop to start..." for i in $(seq 1 30); do - if curl --silent --fail http://localhost:3000/rest/admin/application-version > /dev/null; then - echo "Juice Shop is up after $((i * 2))s" + if curl --silent --fail http://127.0.0.1:3000/rest/admin/application-version >/dev/null; then + echo "Juice Shop is ready after $((i * 2)) seconds" exit 0 fi - echo "Attempt $i/30 — not ready yet, sleeping 2s..." sleep 2 done - echo "ERROR: Juice Shop did not start within 60 seconds" + echo "Juice Shop did not become ready within 60 seconds" docker logs juice-shop exit 1 - - - name: Verify homepage returns HTTP 200 + - name: Verify homepage 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 "ERROR: Expected 200, got $HTTP_CODE" - exit 1 - fi - echo "HTTP 200 confirmed — smoke test passed." - - - name: Verify version endpoint + http_status="$(curl --silent --output /dev/null --write-out '%{http_code}' http://127.0.0.1:3000)" + echo "Homepage HTTP status: ${http_status}" + test "${http_status}" = "200" + - name: Capture version response run: | - RESPONSE=$(curl -s http://localhost:3000/rest/admin/application-version) - echo "Version endpoint response: $RESPONSE" - echo "$RESPONSE" | grep -q '"version":"20.0.0"' || (echo "ERROR: unexpected version response" && exit 1) - echo "Version check passed." - - - name: Verify product count - run: | - COUNT=$(curl -s http://localhost:3000/api/Products | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d['data']))") - echo "Product count: $COUNT" - if [ "$COUNT" -lt 1 ]; then - echo "ERROR: No products returned" - exit 1 - fi - echo "Product count check passed: $COUNT products found." - - - name: Cleanup - if: always() - run: docker rm -f juice-shop || true + curl --include --silent --fail http://127.0.0.1:3000/rest/admin/application-version From 62141f5795526071e4717041249e63c7ec3c7f77 Mon Sep 17 00:00:00 2001 From: SamiKO228 Date: Fri, 12 Jun 2026 22:08:34 +0300 Subject: [PATCH 08/10] fix(workflow): 7th fix indentation and syntax in smoke-test --- .github/workflows/lab1-smoke.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lab1-smoke.yml b/.github/workflows/lab1-smoke.yml index e2a779221..d9347e604 100644 --- a/.github/workflows/lab1-smoke.yml +++ b/.github/workflows/lab1-smoke.yml @@ -1,4 +1,4 @@ -name: Lab 1 Juice Shop Smoke Test +1name: Lab 1 Juice Shop Smoke Test on: pull_request: From 7b1eb41f59092b5cb1c4e379c31c92741bf6c818 Mon Sep 17 00:00:00 2001 From: SamiKO228 Date: Fri, 12 Jun 2026 22:11:53 +0300 Subject: [PATCH 09/10] fix(workflow): 8th fix indentation and syntax in smoke-test --- .github/workflows/lab1-smoke.yml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/lab1-smoke.yml b/.github/workflows/lab1-smoke.yml index d9347e604..58b0ecec5 100644 --- a/.github/workflows/lab1-smoke.yml +++ b/.github/workflows/lab1-smoke.yml @@ -1,4 +1,4 @@ -1name: Lab 1 Juice Shop Smoke Test +name: lab1-smoke on: pull_request: @@ -13,28 +13,28 @@ jobs: runs-on: ubuntu-latest steps: - - name: Run Juice Shop + - name: Check out repository + uses: actions/checkout@v4 + + - 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 + 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 become ready run: | for i in $(seq 1 30); do if curl --silent --fail http://127.0.0.1:3000/rest/admin/application-version >/dev/null; then - echo "Juice Shop is ready after $((i * 2)) seconds" + echo "Juice Shop is ready" exit 0 fi + echo "Waiting for Juice Shop..." sleep 2 done - echo "Juice Shop did not become ready within 60 seconds" - docker logs juice-shop + echo "Juice Shop does not seem to be ready" + docker logs juice-shop || true exit 1 + - name: Verify homepage run: | - http_status="$(curl --silent --output /dev/null --write-out '%{http_code}' http://127.0.0.1:3000)" - echo "Homepage HTTP status: ${http_status}" - test "${http_status}" = "200" - - name: Capture version response - run: | - curl --include --silent --fail http://127.0.0.1:3000/rest/admin/application-version + curl --silent --fail http://127.0.0.1:3000 >/dev/null + echo "Homepage returned HTTP 200" From f267fb89415e6995a79234b762801607679ba241 Mon Sep 17 00:00:00 2001 From: SamiKO228 Date: Fri, 12 Jun 2026 22:32:28 +0300 Subject: [PATCH 10/10] feat(lab1): juice shop deploy + PR template + triage report --- .github/PULL_REQUEST_TEMPLATE.md | 18 ++++++ submissions/lab1.md | 98 ++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md 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..fcac107a3 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,18 @@ +## Goal +[Опиши в одном предложении, что делает этот PR] + +## Changes +* Добавлен отчет submissions/labX.md +* Добавлены скриншоты/артефакты (если есть) + +## Testing +* Запущены команды: `docker ps`, `curl` +* Все проверки пройдены локально + +## Artifacts & Screenshots +* [Ссылки или изображения] + +## Checklist +- [ ] Title is clear (`feat(labN): ` style) +- [ ] No secrets/large temp files committed +- [ ] Submission file at `submissions/labN.md` exists diff --git a/submissions/lab1.md b/submissions/lab1.md new file mode 100644 index 000000000..f49576429 --- /dev/null +++ b/submissions/lab1.md @@ -0,0 +1,98 @@ +# 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: `Ubuntu 24.04` +- Docker version: `Docker version 29.1.3, build 29.1.3-0ubuntu3~24.04.2` + +### 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: `no` (default policy, since no `--restart` flag was specified in the run command) + +### Health Check +- HTTP code on `/`: `200 OK` +- API check (first 200 chars of `/api/Products`): + ```json + {"status":"success","data":[{"id":1,"name":"Apple Juice (1000ml)","description":"The all-time classic.","price":1.99,"deluxePrice":0.99,"image":"apple_juice.jpg","createdAt":"2026-06-12T14:43:23.024Z" + ``` +- Container uptime: `Up 2 hours` + +### Initial Surface Snapshot (from browser exploration) +- Login/Registration visible: [x] Yes [ ] No — notes: Accessible via the "Account" dropdown menu in the top right corner. +- Product listing/search present: [x] Yes [ ] No — notes: The main dashboard displays a grid of available products with a functional search bar at the top. +- Admin or account area discoverable: [x] Yes [ ] No — notes: While a standard account profile updates post-authentication, a dedicated administrative interface was discovered by directly navigating to the `/#/administration` path. +- Client-side errors in DevTools console: [x] Yes [ ] No — notes: DevTools console catches a `401 Unauthorized` block on the `/api/Addresss` endpoint due to unauthenticated guest access, an Angular runtime error regarding a missing mandatory `"key"` parameter, and minor font asset loading failures (`FontMfizz`). +
+ Click to view full console log snapshot + + ```text + XHRGET [http://127.0.0.1:3000/api/Addresss](http://127.0.0.1:3000/api/Addresss) [HTTP/1.1 401 Unauthorized 1ms] + ERROR Error: Parameter "key" is required and cannot be empty + get [http://127.0.0.1:3000/chunk-GJJPXCX3.js:5](http://127.0.0.1:3000/chunk-GJJPXCX3.js:5) + open [http://127.0.0.1:3000/chunk-524KQQJQ.js:264](http://127.0.0.1:3000/chunk-524KQQJQ.js:264) + load [http://127.0.0.1:3000/chunk-JCQ5N7PA.js:422](http://127.0.0.1:3000/chunk-JCQ5N7PA.js:422) + ngOnInit [http://127.0.0.1:3000/chunk-JCQ5N7PA.js:422](http://127.0.0.1:3000/chunk-JCQ5N7PA.js:422) + downloadable font: no supported format found (font-family: "FontMfizz") +- Pre-populated local storage / cookies: Local Storage is completely empty upon initial unauthenticated navigation (`No data present for selected host`). However, Session Storage actively tracks the unauthenticated guest state, populating keys such as `guestBasket` (holding raw JSON object arrays of product IDs and quantities, e.g., ProductId 24, 52, 6) and `itemTotal` (tracking the current cart value, e.g., 5.87). Cookies contain framework-specific tokens for socket communication. + +### Security Headers (Quick Look) +Run: `curl -I http://127.0.0.1:3000 2>&1 | head -20`. Paste output: +```text +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: Fri, 12 Jun 2026 14:43:28 GMT +ETag: W/"26af-19ebc49ba4f" +Content-Type: text/html; charset=UTF-8 +Content-Length: 9903 +Vary: Accept-Encoding +Date: Fri, 12 Jun 2026 17:22:15 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. **Absence of Content-Security-Policy (CSP)** — The application's HTTP headers completely lack a `Content-Security-Policy`. Testing the search bar with a basic iframe payload triggers an alert box, proving that the application executes arbitrary client-side scripts. This aligns directly with **A03:2025-Injection** (specifically Cross-Site Scripting). +2. **Exposed Internal Directory Listing (/ftp)** — Navigating directly to the `/ftp` path reveals an open directory containing sensitive application files, backup databases, and internal logs. This exposure allows unauthenticated users to download files that should be strictly internal, mapping directly to **A06:2025-Security Misconfiguration**. +3. **Information Disclosure via Application Headers and Endpoints** — The server leaks technology stack details through the `X-Powered-By: Express` header, and explicitly exposes the exact software version via the `/rest/admin/application-version` endpoint. This precise blueprint helps attackers research and map target-specific CVEs, falling under **A06: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/large temp files committed + - Submission file at `submissions/labN.md` exists +- Auto-fill verified: [x] Yes — PR description showed my template (Link to my PR will be active upon opening the PR) + +## GitHub Community + +Starring open-source repositories is essential because it acts as a baseline metric for community trust and discovery, helping maintainers gain project visibility while signaling potential utility to other security practitioners. Following professors, teaching assistants, and classmates establishes an immediate professional network that aids in peer review tracking, technical collaboration, and long-term career growth within the cybersecurity and DevOps community. + +## Bonus: CI Smoke Test + +- Workflow file: `.github/workflows/lab1-smoke.yml` +- Trigger: `pull_request` on main +- Run URL (must be green): https://github.com/SamiKO228/DevSecOps-Intro/actions/runs/27437810782 +- Workflow run duration: 18S +- Curl response excerpt: + ``` + Homepage returned HTTP 200 + ```