From 89ca86a696c7ddc9e694d5c0acc1489e63048f9e Mon Sep 17 00:00:00 2001 From: err0r522 <47586934+err0r522@users.noreply.github.com> Date: Fri, 19 Jun 2026 22:07:19 +0300 Subject: [PATCH 1/3] feat(lab1): juice shop deploy + PR template + triage report --- .github/PULL_REQUEST_TEMPLATE.md | 31 +++++++++++++ submissions/lab1.md | 75 ++++++++++++++++++++++++++++++++ 2 files changed, 106 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..c9811d54f --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,31 @@ +## Goal + + + +## Changes + + + +- Change 1 +- Change 2 +- Change 3 + +## Testing + + + +``` + commands +``` + +## Artifacts & Screenshots + + + +--- + +### Checklist + +- [ ] Title is clear (`feat(labN): ` style) +- [ ] No secrets/large temp files committed +- [ ] Submission file at `submissions/labN.md` exists \ No newline at end of file diff --git a/submissions/lab1.md b/submissions/lab1.md new file mode 100644 index 000000000..5b44411dd --- /dev/null +++ b/submissions/lab1.md @@ -0,0 +1,75 @@ +# 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 25H2` +- Docker version: `28.3.0` + +### 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 +- Container restart policy: `no` + +### Health Check +- HTTP code on `/`: `200` +- API check (first 200 chars of `/api/Products`): + ``` + {"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-12T19:30:57.156Z" + ``` +- Container uptime: `Up 31 minutes` + +### Initial Surface Snapshot (from browser exploration) +- Login/Registration visible: [x] Yes [ ] No — notes: Accessible from the topbar. +- Product listing/search present: [x] Yes [ ] No — notes: On the main page. +- Admin or account area discoverable: [x] Yes [ ] No — notes: Although there doesn't seem to be a visible indication of an admin page a user can find, it can be discovered by analyzing code or bruteforcing. Access to the page is restricted without superuser privileges. +- Client-side errors in DevTools console: [ ] Yes [x] No — notes: No errors present. +- Pre-populated local storage / cookies: Adds a cookie to store language preference on first load. Local storage was empty. + +### Security Headers (Quick Look) +Run: `curl -I http://127.0.0.1:3000 2>&1 | head -20`. Paste output: +``` +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 19:31:00 GMT +ETag: W/"26af-19ebd50f802" +Content-Type: text/html; charset=UTF-8 +Content-Length: 9903 +Vary: Accept-Encoding +Date: Fri, 12 Jun 2026 20:22:37 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. Broken Access Control — Admin page is discoverable by any unauthorized user. Bruteforcing an admin's account credentials is enough to get full control over the shop. OWASP Top 10:2025 A01. +2. Security Misconfiguration — Missing security headers, vulnerable to client-side attacks such as Cross-Site Scripting. OWASP Top 10:2025 A05. +3. Injection — The responses seems to be taken directly from the database. If there are no server-side checks of user-input, the DB is vulnerable to SQL-injection. OWASP Top 10:2025 A04. + +## 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: [ ] Yes — PR description showed my template (screenshot or link to draft PR) + +## GitHub Community + +Starring repositories helps increasing their popularity and shows what you're interested in to other people. Following other developers helps stay up to date with their activity and projects. \ No newline at end of file From 3981230e2cb6f39734f156b910ab6f0b775a147d Mon Sep 17 00:00:00 2001 From: err0r522 <47586934+err0r522@users.noreply.github.com> Date: Fri, 26 Jun 2026 21:54:59 +0300 Subject: [PATCH 2/3] test: first signed commit --- submissions/lab3.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 submissions/lab3.md diff --git a/submissions/lab3.md b/submissions/lab3.md new file mode 100644 index 000000000..61fa24bee --- /dev/null +++ b/submissions/lab3.md @@ -0,0 +1 @@ +lab3 signing test From 4bcfbc8ca1338cd743266dc373b04e7e847f4885 Mon Sep 17 00:00:00 2001 From: err0r522 <47586934+err0r522@users.noreply.github.com> Date: Fri, 26 Jun 2026 23:06:53 +0300 Subject: [PATCH 3/3] feat(lab3): SSH signing + gitleaks pre-commit + history rewrite practice --- .pre-commit-config.yaml | 10 +++++ submissions/lab3.md | 82 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..03d6c4d2e --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,10 @@ +repos: + - repo: https://github.com/gitleaks/gitleaks + rev: v8.24.2 + hooks: + - id: gitleaks + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: detect-private-key + - id: check-added-large-files \ No newline at end of file diff --git a/submissions/lab3.md b/submissions/lab3.md index 61fa24bee..6dd265804 100644 --- a/submissions/lab3.md +++ b/submissions/lab3.md @@ -1 +1,81 @@ -lab3 signing test +# Lab 3 — Submission + +## Task 1: SSH Commit Signing + +### Local configuration +- `git config --global gpg.format` → +- `git config --global user.signingkey` → +- `git config --global commit.gpgsign` → + +### Local verification +Output of `git log --show-signature -1`: +``` +commit 3981230e2cb6f39734f156b910ab6f0b775a147d (HEAD -> feature/lab3) +Good "git" signature for 47586934+err0r522@users.noreply.github.com with ED25519 key +``` +Although the key is public, I had to remove the fingerprint (gitleaks). +``` +Author: err0r522 <47586934+err0r522@users.noreply.github.com> +Date: Fri Jun 26 21:54:59 2026 +0300 + + test: first signed commit +``` + +### GitHub verification +- Direct link to your most recent commit on GitHub: [Link](https://github.com/err0r522/DevSecOps-Intro/commit/3981230e2cb6f39734f156b910ab6f0b775a147d) +- Screenshot of the Verified badge: Link to image file in PR + +### One-paragraph reflection (2-3 sentences) +A malicious actor can make a commit using a team member's name and email address to impersonate them and push malicious code on their behalf. However, such commit won't have the Verified badge, so if the team member normally signs their commits, the unverified commit will immediately stand out and allow them to prove they weren't the one who pushed it. + +## Task 2: Pre-commit + gitleaks + +### `.pre-commit-config.yaml` +``` +repos: + - repo: https://github.com/gitleaks/gitleaks + rev: v8.24.2 + hooks: + - id: gitleaks + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: detect-private-key + - id: check-added-large-files +``` + +### `pre-commit install` output +``` +pre-commit installed at .git\hooks\pre-commit +``` + +### The blocked commit +Output of the `git commit` that gitleaks blocked (the failing hook output): +``` +- hook id: gitleaks +- exit code: 1 + +○ + │╲ + │ ○ + ○ ░ + ░ gitleaks + +Finding: GH_PAT=REDACTED +Secret: REDACTED +RuleID: github-pat +Entropy: 4.143943 +File: submissions/leak-attempt.txt +Line: 2 +Fingerprint: submissions/leak-attempt.txt:github-pat:2 + +10:36PM INF 1 commits scanned. +10:36PM INF scanned ~101 bytes (101 bytes) in 68.9ms +10:36PM WRN leaks found: 1 +``` + +### Tune-out exercise +Suppose a teammate insists they need to commit `AKIA*` strings because they're documentation examples in `docs/`. Briefly describe two approaches: +1. **Inline allowlist** — `[allowlist]` block in `.gitleaks.toml`. This is OK when the strings are easily identifiable as fake and only show up in one place. However, it is not okay to make many of such exceptions as they tend to accumulate. +2. **Path exclusion** — `paths: [docs/]` in `.gitleaks.toml`. It is risky if the directory contains any leftover logs or dumps. Though human error is also a risk on it's own, whoever writes the docs can make an intentional or accidental mistake. +``` \ No newline at end of file