## 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>
14 KiB
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) 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) andservices/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.phplimitedBackofficeLoginGrantService.phpand 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.phptrait) — 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,coolifydeploy 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,Gemfileif 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.dkstyle). - 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):
- 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.
- 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).
- 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.
- 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.
- 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.
- SCA / dependency check (0.5 day)
composer.jsonandpackage.jsonSCA scan.- High-severity known-CVE report only; no deep audit.
- Exploitation & PoC (1 day)
- Build proofs-of-concept for any Critical / High findings.
- 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-2026Q4channel. - 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
- Kick-off doc (this plan, signed off by both parties).
- Daily standup notes in
#sec-pentest-2026Q4(one paragraph + new findings list). - Mid-engagement check-in at end of phase 3 — informal review of any Critical / High so we can start patching in parallel.
- 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.
- Re-test letter (separate SOW, see §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):
- Securix (DK) — boutique, OWASP ASVS-aligned, good fit for our size.
- Pentest People (UK / EU) — mid-tier, mobile capability.
- NCC Group / nCC / NowSecure (international) — heavier, good brand for enterprise due-diligence.
- Curity (SE) — strong API / OAuth expertise, fits our auth model.
- 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, nounsafe-inline; report-only first - All cookies
Secure; HttpOnly; SameSite=Lax(orStrictfor 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 auditandnpm audit --omit=devblocking high+ vulns - Mobile:
allowFileAccess=false, mixed content disabled, JS interfaces removed - Secrets: no production keys in repo (
git log -Saudit)
This list is also the basis for re-test acceptance criteria.
8. Open questions for management
- Confirm total budget cap (recommend ≤ 220 000 DKK + 25 000 retainer).
- Confirm legal/procurement owner and contract template.
- Confirm whether to require a Danish-language final report (recommended).
- Confirm re-test budget is approved up-front, or per-finding.
- 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.