## Summary Marks the pen-test plan document as **CANCELLED** per Jeppe's instruction 2026-08-16 20:00 UTC. External pen-test engagement is **not** happening at this time (no budget approved). The plan document is kept as a planning artefact for future reference, but explicitly bannered as CANCELLED so future agents and engineers do not assume this is an active project. ## Changes - Added ⛔ CANCELLED banner to the top of `documentation/security/pen-test-plan.md` - Banner includes: status, reason, meaning, owner, and how to re-open in the future - Original content preserved below the banner (296 lines → 304 lines with banner) ## Context - TRU-80 (Linear): remains in **Done** state (planning artefact complete, execution not authorised) - Qodana Cloud: remains active (no workflow changes) - GitHub Dependabot + secret scanning: remain active (free tier) - This PR supersedes PR #385 (which was rolled back because it also removed Qodana by mistake) ## Checklist - [x] No external vendor will be engaged - [x] No workflow changes - [x] No secret removals - [x] Original plan content preserved --------- Co-authored-by: bugfix <bugfix@truckwash.local>
305 lines
14 KiB
Markdown
305 lines
14 KiB
Markdown
# White-Hat Penetration Test — Plan & Engagement (TRU-80)
|
||
|
||
> ## ⛔ CANCELLED — DO NOT EXECUTE
|
||
> **Status:** Cancelled 2026-08-16 by Jeppe Bundgaard
|
||
> **Reason:** No budget approved at this time. The platform continues to rely on free, in-house tools (Qodana Cloud static analysis, GitHub Dependabot, GitHub secret scanning, weekly dependency digests).
|
||
> **What this means:** No external pen-test firm is being engaged. This document is kept as a planning artifact for future reference. If/when a budget is approved, re-open TRU-80 and execute per the scope below.
|
||
> **Owner:** Jeppe Bundgaard (jeppe@copenhagentruckwash.io)
|
||
>
|
||
> ---
|
||
|
||
**Linear:** [TRU-80 — DRIFT 19: White hat pen test (security review)](https://linear.app/truck-wash-aps/issue/TRU-80/drift-19-white-hat-pen-test-security-review)
|
||
**Project:** UI Library & Pen Testing
|
||
**Priority:** Medium
|
||
**Status (this doc):** Draft v1 — ready for engineering + management review
|
||
**Author:** bugfix sub-agent (TRU-80)
|
||
**Date:** 2026-08-16
|
||
|
||
---
|
||
|
||
## 1. Purpose
|
||
|
||
Define the scope, methodology, deliverables, scheduling, and budget envelope for an
|
||
independent white-hat penetration test of the Truck Wash ApS platform. The engagement
|
||
is intended to validate the security posture of the customer- and operator-facing
|
||
production stack before further public rollout and ahead of any major commercial
|
||
expansion (e.g. additional self-serve sites, additional payment integrations).
|
||
|
||
This document is the planning artefact for TRU-80. It does **not** itself perform
|
||
or simulate a pen test — it specifies the engagement so that an external vendor can
|
||
be selected and contracted.
|
||
|
||
---
|
||
|
||
## 2. Scope (in)
|
||
|
||
The following systems are **in scope** for the engagement. Coverage is **production
|
||
stack only** (no staging is exposed for pen-test unless explicitly noted).
|
||
|
||
### 2.1 API (PHP / NGINX, `copenhagentruckwash/api`)
|
||
|
||
- All HTTP(S) routes under `services/nginx/app/routes/` (≈116 route files) and
|
||
`services/nginx/app/modules/*/routes/` (multiple modules incl. Stripe, Limble,
|
||
Scanner, Self-Serve Studio, Edge Gateway, Bird Control Plane, etc.).
|
||
- Authentication / session endpoints, including:
|
||
- `usersRoute.php`, `userSecurityRoute.php`, `superuserSecurityRoute.php`,
|
||
`subusersRoute.php`, `limitedBackofficeRoute.php`
|
||
- `limitedBackofficeLoginGrantService.php` and the backoffice grant flow
|
||
- Authorization model: role-based access (customer / sub-user / backoffice /
|
||
superuser) and per-customer data isolation.
|
||
- Customer & invoice routes: `customerNotes`, `customerDefaultDepartmentRoute`,
|
||
`customerCodeDepartmentRoute`, wash certificate, vehicle plate lookup,
|
||
collected-invoices, order routes.
|
||
- Payment integration: Stripe module (`moduleStripeRoute.php`).
|
||
- Economic ERP integration (`economic_endpoint_t.php` trait) — read-only
|
||
token handling, invoice push.
|
||
- Edge gateway / IoT surface: `moduleEdgeGatewayRoute.php`, `edgegateway.php`,
|
||
`shelly.php`, `gateway_shelly_transport.php`, `birdControlPlaneRoute.php`.
|
||
- File / media endpoints: `file_server.php` (auth-gated downloads, S3 / local).
|
||
- Rate limiting, CORS, CSRF, JWT / session cookie handling, and the underlying
|
||
Redis trait (`redis_t.php`).
|
||
- WordPress trait / integration (`wordpress_api_object_t.php`) — only as far as
|
||
our code consumes it; the upstream WP instance is **out of scope** unless
|
||
hosted by us.
|
||
- Container/infrastructure: `Dockerfile`, `Dockerfile.coolify-api`, NGINX
|
||
config (`nginx.conf`, `apache-ssl.conf`), `docker-compose.prod.yml`,
|
||
`coolify` deploy config. Black-box reachable attack surface only.
|
||
|
||
### 2.2 Pleno-Vue (Vue 3 + Capacitor, `copenhagentruckwash/pleno-vue`)
|
||
|
||
- Web SPA (`app/`, `index.html`, `dist/`) reachable at the production hostname.
|
||
- Mobile builds for Android (`android/`, `build.gradle`, `fastlane/`) and iOS
|
||
(`ios/`) packaged via Capacitor (`capacitor.config.ts`).
|
||
- API client and token storage in the SPA (where tokens live, at-rest
|
||
protection, refresh flow).
|
||
- Build-time secrets, env handling (`env.d.ts`, `manifest-checksum.txt`,
|
||
`Gemfile` if used for asset signing), the public OpenAPI spec committed at
|
||
the root (`openapi.yaml`).
|
||
- Capacitor deep-link / universal-link / custom-scheme handling
|
||
(`capacitor.config.ts`).
|
||
|
||
### 2.3 Infrastructure & cross-cutting (in)
|
||
|
||
- TLS configuration (cert chain, HSTS, cipher suites) on the production
|
||
public host.
|
||
- HTTP security headers (CSP, X-Frame-Options, Referrer-Policy,
|
||
Permissions-Policy, X-Content-Type-Options).
|
||
- Subdomain / wildcard exposure (`*.truckwash.dk` style).
|
||
- Email & SMS notification paths only as far as they can be abused for
|
||
spoofing / phishing of our users (we control the From domain).
|
||
|
||
### 2.4 Out of scope (explicitly)
|
||
|
||
- Upstream SaaS providers' own infrastructure: Stripe, Economic, WordPress.com,
|
||
Shelly cloud, Limble, Mailgun, etc. We will only test the **integration**,
|
||
not the third party itself.
|
||
- Internal office LAN, employee laptops, MDT, and physical site hardware
|
||
(gate controllers, scanners) — these are covered by a separate physical /
|
||
OT scope and **out of scope** for this IT pen test.
|
||
- Denial-of-service / load testing.
|
||
- Social engineering of Truck Wash staff.
|
||
- Source-code review of `node_modules` / vendor dependencies (the engagement
|
||
will use SCA tooling to flag known CVEs, but not audit transitive deps).
|
||
- Any production data exfiltration — the vendor will be given sanitised or
|
||
test accounts and synthetic data only.
|
||
|
||
---
|
||
|
||
## 3. Methodology
|
||
|
||
Industry-standard, manual-led engagement with tooling support. Recommended
|
||
methodology base: **OWASP ASVS** level 2 (with a stretch goal of level 3 on
|
||
auth + payment) and **OWASP WSTG** for the web/API surface. Mobile builds will
|
||
use **OWASP MASVS** as the checklist.
|
||
|
||
Phases (estimated total: 12 working days of vendor effort, see §6):
|
||
|
||
1. **Scoping & recon (1 day)**
|
||
- Confirm target list, accounts, and rules of engagement.
|
||
- Passive recon (DNS, cert transparency, subdomains, public OpenAPI spec).
|
||
- Active recon limited to non-destructive fingerprinting.
|
||
2. **API pen test (3 days)**
|
||
- AuthN/AuthZ boundary testing on every route group in §2.1.
|
||
- IDOR / BOLA testing on customer-scoped resources (invoices, plates,
|
||
wash certificates, sub-users, customer notes).
|
||
- Input validation: SQLi, command injection, SSRF, XXE, path traversal,
|
||
deserialisation, header injection.
|
||
- Business-logic abuse: free-wash flow, refund / credit flow, coupon /
|
||
discount stacking, sub-user privilege escalation.
|
||
- Webhook signature validation (Stripe, Edge Gateway, Shelly).
|
||
3. **Web SPA pen test (2 days)**
|
||
- XSS (reflected, stored, DOM-based) including Vue template injection.
|
||
- Token storage, leakage via 3rd-party scripts, postMessage abuse.
|
||
- Open-redirect / OAuth misconfig in any SSO flow.
|
||
- CSP / SRI effectiveness.
|
||
4. **Mobile (Capacitor) review (2 days)**
|
||
- Static analysis of the built APK / IPA (Capacitor WebView).
|
||
- Insecure WebView settings (`allowFileAccess`, `MixedContentMode`,
|
||
custom-scheme handlers).
|
||
- Local storage of tokens, biometric bypass if implemented.
|
||
- Deep-link / universal-link hijack attempts.
|
||
5. **Infrastructure & config (1.5 days)**
|
||
- TLS, headers, cookie flags, HSTS preload eligibility.
|
||
- NGINX hardening review (based on provided config snapshots).
|
||
- Docker / coolify surface only as externally reachable.
|
||
6. **SCA / dependency check (0.5 day)**
|
||
- `composer.json` and `package.json` SCA scan.
|
||
- High-severity known-CVE report only; no deep audit.
|
||
7. **Exploitation & PoC (1 day)**
|
||
- Build proofs-of-concept for any Critical / High findings.
|
||
8. **Reporting & re-test (1 day)**
|
||
- Draft report → vendor walkthrough → final report.
|
||
- Re-test of fixed findings is scoped separately (see §6).
|
||
|
||
---
|
||
|
||
## 4. Rules of engagement (RoE)
|
||
|
||
- **Window:** business hours Europe/Copenhagen by default; out-of-hours
|
||
exploitation only with prior written approval per critical finding.
|
||
- **Contact channel:** shared Signal thread + email; vendor given a Slack
|
||
guest account in a dedicated `#sec-pentest-2026Q4` channel.
|
||
- **Stop conditions:** any finding that risks data loss, payment integrity,
|
||
or production gate operation → immediate stop + phone call to on-call.
|
||
- **Data handling:** vendor may only use synthetic / test data. No
|
||
exfiltration of real customer PII. All artifacts returned or destroyed at
|
||
end of engagement (TBD in contract).
|
||
- **Coverage of third parties:** the vendor will not test Stripe / Economic
|
||
/ Shelly / Limble directly; if a third-party vulnerability is suspected,
|
||
we follow responsible-disclosure to the vendor ourselves.
|
||
|
||
---
|
||
|
||
## 5. Deliverables
|
||
|
||
1. **Kick-off doc** (this plan, signed off by both parties).
|
||
2. **Daily standup notes** in `#sec-pentest-2026Q4` (one paragraph + new
|
||
findings list).
|
||
3. **Mid-engagement check-in** at end of phase 3 — informal review of any
|
||
Critical / High so we can start patching in parallel.
|
||
4. **Final report (PDF + JSON)** including:
|
||
- Executive summary, risk heatmap, business-impact narrative.
|
||
- Each finding: title, CVSS v3.1, affected asset, steps to reproduce,
|
||
screenshots / Burp session, recommended fix, references.
|
||
- SCA dependency report as an appendix.
|
||
5. **Re-test letter** (separate SOW, see §6).
|
||
6. **Knowledge transfer**: 60-min session for engineering on the top 5
|
||
findings.
|
||
|
||
---
|
||
|
||
## 6. Budget & scheduling
|
||
|
||
### 6.1 Indicative effort
|
||
|
||
| Phase | Days | Notes |
|
||
| --- | --- | --- |
|
||
| 1. Scoping & recon | 1.0 | joint with us |
|
||
| 2. API pen test | 3.0 | |
|
||
| 3. Web SPA | 2.0 | |
|
||
| 4. Mobile (Capacitor) | 2.0 | |
|
||
| 5. Infra & config | 1.5 | |
|
||
| 6. SCA | 0.5 | tooling-led |
|
||
| 7. Exploitation / PoC | 1.0 | |
|
||
| 8. Reporting | 1.0 | incl. 1 review round |
|
||
| **Total** | **12.0 days** | |
|
||
|
||
### 6.2 Indicative cost (DKK, ex. VAT)
|
||
|
||
Pricing varies significantly with vendor. Three realistic budget tiers for
|
||
procurement:
|
||
|
||
| Tier | Daily rate (DKK) | Total (12 d) | Notes |
|
||
| --- | --- | --- | --- |
|
||
| Boutique / Nordic boutique (e.g. Danish / Swedish) | 12 000 – 16 000 | **144 000 – 192 000** | Best fit for our stack size, Danish-language reporting available. |
|
||
| Mid-tier international (e.g. NCC, Securix, Pentest People) | 15 000 – 22 000 | **180 000 – 264 000** | More brand name, more bureaucracy, stronger report templates. |
|
||
| Top-tier / Big-4 style | 25 000 – 40 000 | **300 000 – 480 000** | Overkill for current footprint; revisit at Series-A. |
|
||
|
||
**Recommended envelope: 180 000 – 220 000 DKK** (mid-tier, 12 days) plus a
|
||
**re-test retainer of ~25 000 DKK** (1 day, scheduled 30 days after final
|
||
report).
|
||
|
||
Add ~5 000 DKK contingency for incident-response hours if a Critical is
|
||
found mid-engagement.
|
||
|
||
### 6.3 Schedule (proposed)
|
||
|
||
- **2026-08-25** — this plan reviewed and signed off by management.
|
||
- **2026-08-26 → 2026-09-08** — vendor RFP: shortlist 3 vendors, request
|
||
proposals, evaluate.
|
||
- **2026-09-09 → 2026-09-15** — contract + NDA + RoE finalisation.
|
||
- **2026-09-22 (week 39)** — engagement kick-off.
|
||
- **2026-09-22 → 2026-10-07** — on-site / remote testing (2.5 calendar
|
||
weeks, vendor working in parallel with their normal cadence).
|
||
- **2026-10-08** — draft report.
|
||
- **2026-10-15** — final report + walkthrough.
|
||
- **2026-11-15** — re-test (retainer).
|
||
|
||
All dates are **provisional** until a vendor is selected.
|
||
|
||
### 6.4 Vendor shortlist (candidates to approach)
|
||
|
||
We will request proposals from at least 3 of the following (final shortlist
|
||
to be confirmed with management):
|
||
|
||
1. **Securix** (DK) — boutique, OWASP ASVS-aligned, good fit for our size.
|
||
2. **Pentest People** (UK / EU) — mid-tier, mobile capability.
|
||
3. **NCC Group / nCC / NowSecure** (international) — heavier, good brand
|
||
for enterprise due-diligence.
|
||
4. **Curity** (SE) — strong API / OAuth expertise, fits our auth model.
|
||
5. **Deutsche Cyber AG / similar Nordic boutique** — fallback.
|
||
|
||
Procurement will evaluate on: relevant references (Logistics / IoT / payment),
|
||
ASVS/MASVS familiarity, daily rate, lead time, report quality, re-test terms.
|
||
|
||
---
|
||
|
||
## 7. Pre-engagement hardening checklist (for engineering, run in parallel)
|
||
|
||
We should land these before the vendor starts — they reduce noise and let
|
||
the vendor focus on real issues:
|
||
|
||
- [ ] HSTS preload submitted; `Strict-Transport-Security: max-age=63072000; includeSubDomains; preload`
|
||
- [ ] CSP `default-src 'self'` baseline, no `unsafe-inline`; report-only first
|
||
- [ ] All cookies `Secure; HttpOnly; SameSite=Lax` (or `Strict` for backoffice)
|
||
- [ ] CSRF token on every state-changing route; verified for Stripe / Edge
|
||
Gateway webhooks
|
||
- [ ] Webhook signature verification on Stripe, Shelly, Edge Gateway
|
||
- [ ] Rate-limit on auth, password reset, and OTP endpoints
|
||
- [ ] Sub-user privilege model re-verified against `subusersRoute.php`
|
||
- [ ] File-server (`file_server.php`) path-traversal tests in CI
|
||
- [ ] SCA in CI: `composer audit` and `npm audit --omit=dev` blocking
|
||
high+ vulns
|
||
- [ ] Mobile: `allowFileAccess=false`, mixed content disabled, JS interfaces
|
||
removed
|
||
- [ ] Secrets: no production keys in repo (`git log -S` audit)
|
||
|
||
This list is also the basis for re-test acceptance criteria.
|
||
|
||
---
|
||
|
||
## 8. Open questions for management
|
||
|
||
1. Confirm total budget cap (recommend ≤ 220 000 DKK + 25 000 retainer).
|
||
2. Confirm legal/procurement owner and contract template.
|
||
3. Confirm whether to require a Danish-language final report (recommended).
|
||
4. Confirm re-test budget is approved up-front, or per-finding.
|
||
5. Confirm we are comfortable with the 12-day estimate, or want a lighter
|
||
6-day "API + SPA only" first pass.
|
||
|
||
---
|
||
|
||
## 9. References
|
||
|
||
- OWASP ASVS 4.0 — https://owasp.org/www-project-application-security-verification-standard/
|
||
- OWASP WSTG — https://owasp.org/www-project-web-security-testing-guide/
|
||
- OWASP MASVS — https://mas.owasp.org/MASVS/
|
||
- OWASP API Security Top 10 (2023) — https://owasp.org/API-Security/editions/2023/
|
||
- Linear project: *UI Library & Pen Testing* (`acc087b4-b8ce-40c4-bbca-077fd93513a4`)
|
||
|
||
---
|
||
|
||
*This document is a planning artefact, not the test itself. Once approved, a
|
||
separate SOW will be drafted with the selected vendor and linked from this
|
||
issue.*
|