Files
api/documentation/security/pen-test-plan.md
T
Jeppe Bandbugfix 76ad696691 docs: mark pen-test plan as CANCELLED (TRU-80, no budget approved) (#386)
## 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>
2026-08-16 22:20:03 +02:00

14 KiB
Raw Blame History

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


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.