Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## Goal
<!-- One sentence: what does this PR deliver? -->

## Changes
<!-- Bullet list of added/modified files -->
-

## Testing
<!-- Commands you ran and what you observed -->
```bash
# paste commands + output here
```

## Artifacts & Screenshots
<!-- Links to files in this PR, screenshots where useful -->
- `submissions/labN.md`

---

## Checklist
- [ ] Title follows `feat(labN): <topic>` format
- [ ] No secrets or large temp files committed
- [ ] Submission file at `submissions/labN.md` exists
64 changes: 64 additions & 0 deletions .github/workflows/lab1-smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: lab1-smoke

on:
pull_request:
branches:
- main

permissions:
contents: read

jobs:
smoke-test:
name: Juice Shop smoke test
runs-on: ubuntu-latest

steps:
- 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 to be ready (max 60s)
run: |
echo "Waiting for Juice Shop..."
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 up after $((i * 2))s"
exit 0
fi
echo " attempt $i/30 — not ready yet, sleeping 2s..."
sleep 2
done
echo "ERROR: Juice Shop did not become ready within 60s"
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 "Homepage status: $STATUS"
if [ "$STATUS" != "200" ]; then
echo "ERROR: expected 200, got $STATUS"
exit 1
fi

- name: Verify application version endpoint
run: |
RESPONSE=$(curl --silent http://127.0.0.1:3000/rest/admin/application-version)
echo "$RESPONSE"
echo "$RESPONSE" | grep -q '"version"' || {
echo "ERROR: version endpoint did not return expected JSON"
exit 1
}
echo "Juice Shop is healthy — smoke test passed."

- name: Stop Juice Shop
if: always()
run: docker stop juice-shop || true
78 changes: 78 additions & 0 deletions submissions/lab1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Lab 1 - Submission

## PR Template Setup

- File: `.github/PULL_REQUEST_TEMPLATE.md`
- Sections included: Goal / Changes / Testing / Artifacts & Screenshots
- Checklist items: title format / no secrets / submission file exists
- Auto-fill verified: [x] Yes — PR description showed my template

## Triage Report: OWASP Juice Shop

### Scope & Asset
- Asset: OWASP Juice Shop (local lab instance)
- Image: `bkimminich/juice-shop:v20.0.0`
- Image digest: sha256:99779f57113bd47312e8fe7b264ff402ee41da76ddda7f2fc842a92ad51827ce
- Host OS: Kali
- Docker version: 26.1.5

### 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)

### Health Check
- HTTP code on `/`: 200
- API check (`/api/Products` length): 46

### Initial Surface Snapshot
- Login/Registration visible: [x] Yes - в меню Account
- Product listing/search present: [x] Yes - главная страница
- Admin or account area discoverable: [x] Yes - /administration (после логина)
- Client-side errors in DevTools console: [x] Yes - Angular warnings, mixed content notices
- Pre-populated local storage / cookies: language preference, возможно welcomeBanner флаг

### Security Headers (Quick Look)
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 14:54:25 GMT
ETag: W/"26af-19eb72d63d4"
Content-Type: text/html; charset=UTF-8
Content-Length: 9903
Vary: Accept-Encoding
Date: Thu, 11 Jun 2026 14:55:04 GMT
Connection: keep-alive
Keep-Alive: timeout=5

Отсутствующие заголовки:
- [x] `Content-Security-Policy` - ОТСУТСТВУЕТ
- [x] `Strict-Transport-Security` - ОТСУТСТВУЕТ (HTTP, не HTTPS)
- [ ] `X-Content-Type-Options: nosniff` - присутствует
- [x] `X-Frame-Options` - ОТСУТСТВУЕТ

### Top 3 Risks Observed

1. **Broken Access Control (A01:2025)** - endpoint `/rest/admin/application-version`
доступен без авторизации, раскрывает версию приложения. Упрощает таргетированные атаки.

2. **Security Misconfiguration (A03:2025)** - отсутствуют заголовки CSP и X-Frame-Options.
Приложение уязвимо к clickjacking и XSS без дополнительных браузерных защит.

3. **Injection (A05:2025)** - поиск товаров (`/rest/products/search?q=`) не фильтрует ввод,
классический вектор для SQL injection и reflected XSS.


## GitHub Community

Starring repositories serves as a public bookmark and signals community trust -
the star count helps developers gauge project adoption and encourages maintainers.
Following classmates and instructors creates a lightweight activity feed that surfaces
new projects and keeps you aware of ongoing course work, which helps with collaboration
and professional networking beyond the classroom.
Loading