Skip to content
Open
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
35 changes: 35 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Goal

This PR delivers Lab N work: <briefly describe what this lab adds>.

## Changes

* Added/updated `submissions/labN.md`.
* Added/updated lab-related configuration files.
* Documented testing steps, observed output, and required artifacts.

## Testing

Commands used:

```bash
<paste commands used to verify the lab>
```

Observed output:

```text
<paste important output here>
```

## Artifacts & Screenshots

* `submissions/labN.md`
* <add links to screenshots, workflow runs, or other artifacts if needed>

## Checklist

* [ ] Title is clear (`feat(labN): <topic>` style)
* [ ] No secrets/large temp files committed
* [ ] Submission file at `submissions/labN.md` exists

51 changes: 51 additions & 0 deletions .github/workflows/lab1-smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Lab 1 Smoke Test

on:
pull_request:
branches:
- main

permissions:
contents: read

jobs:
smoke-test:
runs-on: ubuntu-latest

steps:
- name: Pull Juice Shop image
run: docker pull bkimminich/juice-shop:v20.0.0

- 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 become healthy
run: |
for i in $(seq 1 30); do
if curl --silent --fail http://127.0.0.1:3000/rest/admin/application-version; then
echo
echo "Juice Shop is healthy"
exit 0
fi

echo "Waiting for Juice Shop... attempt $i/30"
sleep 2
done

echo "Juice Shop did not become healthy within 60 seconds"
docker logs juice-shop
exit 1

- name: Verify homepage returns HTTP 200
run: |
STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:3000)
echo "Homepage HTTP status: $STATUS_CODE"

if [ "$STATUS_CODE" != "200" ]; then
echo "Expected HTTP 200, got $STATUS_CODE"
docker logs juice-shop
exit 1
fi
107 changes: 107 additions & 0 deletions submissions/lab1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# 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 / image ID: `sha256:fd58bdc9745416afce8184ee0666278a436574633ea7880365153a63bfd418b0`
- Host OS: Arch Linux
- Docker version: `Docker version 29.5.1, build 2518b52d94`

### 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
- Product count from `/api/Products`: 46
- Version check from `/rest/admin/application-version`: `{"version":"20.0.0"}`
- 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-12T11:00:57.053Z"
```
- Container uptime:
```
NAMES STATUS PORTS
juice-shop Up 10 minutes 127.0.0.1:3000->3000/tcp
```

### Initial Surface Snapshot (from browser exploration)
- Login/Registration visible: [x] Yes [ ] No — notes: visible through the Account menu; login and registration are reachable from the UI.
- Product listing/search present: [x] Yes [ ] No — notes: product cards are listed on the landing page; product data is also available through `/api/Products`.
- Admin or account area discoverable: [x] Yes [ ] No — notes: account functionality is visible from the top navigation; admin-related backend endpoint `/rest/admin/application-version` is reachable and exposes the application version.
- Client-side errors in DevTools console: [ ] Yes [x] No — notes: no blocking client-side errors were observed during initial load and product browsing.
- Pre-populated local storage / cookies: browser state contains normal Juice Shop client/UI state such as language or welcome/cookie-banner preferences; no user authentication token was present before login.
- Product detail network behavior: opening a product detail triggers API calls such as `/api/Products/<id>/reviews`; reading product/review data does not require authentication during initial browsing.

### Security Headers (Quick Look)
Run: `curl -I http://127.0.0.1:3000 2>&1 | head -20`. Output:
```
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 0 0 9903 0 0 0 0 0 0 0 0 9903 0 0 0 0 0 0 0 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: Fri, 12 Jun 2026 11:00:57 GMT
ETag: W/"26af-19ebb7e0182"
Content-Type: text/html; charset=UTF-8
Content-Length: 9903
Vary: Accept-Encoding
Date: Fri, 12 Jun 2026 11:11:54 GMT
Connection: keep-alive
Keep-Alive: timeout=5

```

Which of these are MISSING?
- [x] `Content-Security-Policy`
- [x] `Strict-Transport-Security`
- [ ] `X-Content-Type-Options: nosniff`
- [ ] `X-Frame-Options`

### Top 3 Risks Observed
1. **Missing or incomplete browser hardening headers** — The initial header check shows that at least some defensive headers are absent or not explicitly configured. This matters because headers such as CSP, HSTS, X-Frame-Options, and X-Content-Type-Options reduce the impact of common browser-side attacks; this maps to OWASP Top 10:2025 A06 Security Misconfiguration.
2. **Discoverable unauthenticated API surface** — Product data and review-related endpoints are easy to discover from DevTools and can be queried directly. Even when public reads are intended, this increases the reconnaissance surface and should be reviewed for excessive data exposure or missing authorization boundaries; this maps to OWASP Top 10:2025 A01 Broken Access Control.
3. **Input-heavy application surface around login, registration, search, and product interaction** — The first exploration immediately exposes forms, account flows, and API-backed product functionality. These areas are common entry points for injection, authentication abuse, and validation mistakes, so they should be prioritized in later DAST/manual testing; this maps to OWASP Top 10:2025 A03 Injection and A07 Identification & Authentication Failures.

## PR Template Setup

- File: `.github/PULL_REQUEST_TEMPLATE.md`
- Sections included: Goal / Changes / Testing / Artifacts & Screenshots
- Checklist items:
- Title is clear (`feat(labN): <topic>` style)
- No secrets/large temp files committed
- Submission file at `submissions/labN.md` exists
- Auto-fill verified: [x] Yes — PR description showed my template (PASTE_DRAFT_PR_URL_HERE_AFTER_PUSH)

## GitHub Community

I starred the course repository and `simple-container-com/api` because stars work both as bookmarks and as a public signal that helps useful open-source projects gain visibility. I also followed the professor, TAs, and classmates because following developers makes it easier to track course activity, discover related projects, and build professional connections for future teamwork.

Completed actions:
- [x] Starred the course repository
- [x] Starred `simple-container-com/api`
- [x] Followed @Cre-eD
- [x] Followed @Naghme98
- [x] Followed @pierrepicaud
- [x] Followed at least 3 classmates from the course

## Bonus: CI Smoke Test

- Workflow file: `.github/workflows/lab1-smoke.yml`
- Trigger: `pull_request` on main
- Run URL (green): PASTE_GREEN_ACTIONS_RUN_URL_HERE_AFTER_PR
- Workflow run duration: PASTE_WORKFLOW_DURATION_HERE
- Curl response excerpt:
```
HTTP/1.1 200 OK / Homepage HTTP status: 200
```
Expand Down
10 changes: 10 additions & 0 deletions submissions/lab12-results/bonus-bind-kata-container.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
SKIPPED AS AN INVALID ISOLATION TEST.

A writable host bind mount explicitly grants the container access to the
selected host path. Kata transports such mounts into the guest through its
shared-filesystem mechanism, normally virtio-fs. Therefore, the fact that a
Kata workload can write to an explicitly provided writable bind mount does
not demonstrate a VM escape.

During the attempted experiment, startup of the writable virtio-fs mount
also failed to complete reliably under nested virtualization.
1 change: 1 addition & 0 deletions submissions/lab12-results/bonus-bind-kata-exit-status.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SKIPPED_INVALID_VECTOR
1 change: 1 addition & 0 deletions submissions/lab12-results/bonus-bind-kata-host.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
not-applicable
2 changes: 2 additions & 0 deletions submissions/lab12-results/bonus-bind-runc-container.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
+ nerdctl run --rm --privileged -v /tmp:/host_tmp alpine:3.20 sh -c echo "OVERWRITTEN BY RUNC CONTAINER" > /host_tmp/lab12-target && cat /host_tmp/lab12-target
OVERWRITTEN BY RUNC CONTAINER
1 change: 1 addition & 0 deletions submissions/lab12-results/bonus-bind-runc-exit-status.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
1 change: 1 addition & 0 deletions submissions/lab12-results/bonus-bind-runc-host.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
OVERWRITTEN BY RUNC CONTAINER
5 changes: 5 additions & 0 deletions submissions/lab12-results/bonus-bind-summary.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
runc_container_exit=0
runc_host_value=OVERWRITTEN BY RUNC CONTAINER
kata_container_exit=SKIPPED_INVALID_VECTOR
kata_host_value=not-applicable
reason=writable host bind mounts are explicitly shared resources, not a valid Kata escape boundary test
2 changes: 2 additions & 0 deletions submissions/lab12-results/containerd-kata-config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[plugins.'io.containerd.grpc.v1.cri'.containerd.runtimes.kata]
runtime_type = 'io.containerd.kata.v2'
1 change: 1 addition & 0 deletions submissions/lab12-results/containerd-version.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
containerd github.com/containerd/containerd 1.7.24
7 changes: 7 additions & 0 deletions submissions/lab12-results/dev-diff.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
--- /home/remnux/DevSecOps-Intro/labs/lab12/results/runc-devs.txt 2026-07-17 11:55:25.857191627 -0400
+++ /home/remnux/DevSecOps-Intro/labs/lab12/results/kata-devs.txt 2026-07-17 11:55:32.264393747 -0400
@@ -1,4 +1,3 @@
-core
fd
full
mqueue
5 changes: 5 additions & 0 deletions submissions/lab12-results/kata-caps.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CapInh: 0000000000000000
CapPrm: 00000000a80425fb
CapEff: 00000000a80425fb
CapBnd: 00000000a80425fb
CapAmb: 0000000000000000
3 changes: 3 additions & 0 deletions submissions/lab12-results/kata-io.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
100+0 records in
100+0 records out
104857600 bytes (100.0MB) copied, 0.023807 seconds, 4.1GB/s
6 changes: 6 additions & 0 deletions submissions/lab12-results/kata-kernel.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
+ nerdctl run --rm --runtime=io.containerd.kata.v2 alpine:3.20 sh -c uname -a; echo "--- cpuinfo ---"; head -3 /proc/cpuinfo
Linux 1c60be6cde44 6.18.35 #1 SMP Mon Jun 15 12:55:58 UTC 2026 x86_64 Linux
--- cpuinfo ---
processor : 0
vendor_id : GenuineIntel
cpu family : 6
1 change: 1 addition & 0 deletions submissions/lab12-results/kata-version.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.32.0
6 changes: 6 additions & 0 deletions submissions/lab12-results/kvm.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
=== loaded KVM modules ===
kvm_intel 380928 0
kvm 1019904 1 kvm_intel

=== /dev/kvm ===
crw-rw----+ 1 root kvm 10, 232 Jul 17 11:55 /dev/kvm
5 changes: 5 additions & 0 deletions submissions/lab12-results/runc-caps.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CapInh: 0000000000000000
CapPrm: 00000000a80425fb
CapEff: 00000000a80425fb
CapBnd: 00000000a80425fb
CapAmb: 0000000000000000
3 changes: 3 additions & 0 deletions submissions/lab12-results/runc-io.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
100+0 records in
100+0 records out
104857600 bytes (100.0MB) copied, 0.004719 seconds, 20.7GB/s
6 changes: 6 additions & 0 deletions submissions/lab12-results/runc-kernel.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
+ nerdctl run --rm alpine:3.20 sh -c uname -a; echo "--- cpuinfo ---"; head -3 /proc/cpuinfo
Linux 9730d7860109 5.15.0-139-generic #149~20.04.1-Ubuntu SMP Wed Apr 16 08:29:56 UTC 2025 x86_64 Linux
--- cpuinfo ---
processor : 0
vendor_id : GenuineIntel
cpu family : 6
11 changes: 11 additions & 0 deletions submissions/lab12-results/startup-bench.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
runtime,run,seconds
runc,1,0.526595584
runc,2,0.552260352
runc,3,0.481219072
runc,4,0.423924224
runc,5,0.372067072
kata,1,7.855792128
kata,2,7.574585856
kata,3,7.067718144
kata,4,6.545513984
kata,5,7.210876160
7 changes: 7 additions & 0 deletions submissions/lab12-results/startup-summary.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
runc_samples=0.526595584,0.552260352,0.481219072,0.423924224,0.372067072
runc_average=0.471213261
runc_median=0.481219072
kata_samples=7.855792128,7.574585856,7.067718144,6.545513984,7.210876160
kata_average=7.250897254
kata_median=7.210876160
cold_start_overhead_ratio=15.3877
Loading