Penetration Test Runbook
How Gevell commissions, runs, and closes out a third-party penetration test.
Status: no penetration test has been performed. Tracked as issue #3096. This runbook exists so the test can be started on short notice β institutional customers ask for one during security review, and it is the cheapest piece of evidence that satisfies the question. The customer packet states plainly that a test is planned and can be prioritized at contract time; this is how we keep that promise.
Budget roughly 4β6 weeks end to end: 1β2 weeks to select a vendor and agree scope, 1β2 weeks of testing, 1 week for the report, then remediation and retest.
1. Decide the scope
Scope narrowly and deliberately. A broad scope costs more, takes longer, and produces findings on things we do not control.
In scope β the customer-facing surface:
| Target | Why |
|---|---|
pdf.gevell.com Β· audit.gevell.com | Primary applications; authenticated and unauthenticated |
acr.gevell.com Β· orgchart.gevell.com | Distinct auth and tenancy surfaces |
api.gevell.com Β· api-pdf.gevell.com | The API behind all of it; test both compositions β they are built from one source tree but deployed differently |
| Authentication and session handling | Email/OTP, SAML SSO, LTI 1.3 launch, API keys |
| Tenant isolation | The highest-value target: cross-tenant read/write, IDOR on job and file identifiers, 404-not-403 behavior |
| File upload path | Presigned URL abuse, type and size bypass, malware-gate bypass, path traversal in object keys |
| SSRF surfaces | POST /api/v2/fetch-url and the parse service fetch both take customer-supplied URLs; the allow-list is the control under test |
| Published artifacts | Share tokens, published org charts, expiry and revocation |
Explicitly out of scope:
- Cloud provider infrastructure (AWS, Cloudflare, Supabase) β inherited controls under their own attestations; testing them is prohibited by their terms except under their published policies.
- Denial-of-service and volumetric load testing.
- Physical and social engineering, unless the customer specifically requires it.
- Third-party AI endpoints (Bedrock, Mathpix).
Decide before soliciting quotes: grey-box (credentialed, our preference β tenant isolation cannot be meaningfully tested without accounts) versus black-box; and whether a retest of fixed findings is included in the price.
2. Select a vendor
Ask each candidate for: a redacted sample report, tester certifications (OSCP/OSWE/CREST or equivalent), whether findings are manually verified or scanner output, whether a free retest is included, and turnaround time.
Prefer a firm that issues a letter of attestation alongside the report β a one-page summary we can hand to a customer without disclosing findings. That letter, not the report, is what usually closes the procurement question.
Confirm the firm will sign an NDA and will not retain our data after the engagement.
3. Before testing starts
- Signed scope document, NDA, and rules of engagement, naming the exact hosts, the test window, and the tester source IP addresses.
- Notify AWS and Cloudflare per their penetration-testing policies. AWS permits testing of customer-owned resources for approved service types without prior approval; anything outside that list needs a request. Cloudflare requires notice for testing through their edge.
- Stand up an isolated test tenant with seeded synthetic data. Never point a test at production customer documents.
- Create at least three test accounts across two tenants, so cross-tenant isolation can actually be exercised, plus one API key.
- Allow-list tester IPs in the WAF, or agree explicitly that WAF blocking is part of the test.
- Silence or tag alerting for the window so tester traffic does not page us β but keep it recorded, because whether we detected the test is itself a finding worth having.
- Snapshot the environment: commit SHA, build number, deployed versions of each composition. The report must name what was tested.
- Nominate a single point of contact (CTO) reachable during the window.
4. During the test
- Keep a shared channel with the testers for real-time questions.
- Critical findings are reported immediately, not held for the report. Agree this in the rules of engagement.
- Do not fix anything mid-test without telling the testers β a silent fix invalidates their retest baseline.
- Log any production impact. If the test degrades service, that is an incident and follows the incident process.
5. Triage the report
For every finding:
- Reproduce it ourselves before accepting it. Scanner-derived findings are often environmental or false.
- File a GitHub issue labeled
security, one per finding, with the severity the report assigned and a link to the relevant section. - Set the remediation target by severity: critical β 7 days, high β 30 days, medium β 90 days, low β next planned work.
- Where we accept a risk rather than fix it, write the justification down. A documented accepted risk is a defensible answer; an unexplained open finding is not.
- Add a regression test for anything exploitable. A finding that can recur silently has not been fixed.
6. Close out
- Retest critical and high findings and get written confirmation.
- Obtain the letter of attestation.
- Update the customer packet: replace the βnot yetβ answer in Direct Answers and Β§9.9 of each technical specification with the test date, scope, and firm.
- Update the security white paperβs certifications section and remove the corresponding gap from its internal appendix.
- Record the next test date. Annual is the expectation reviewers hold, plus a retest after any architectural change to auth, tenancy, or the upload path.
- Store the full report where it can be shared under NDA β not in the repo.
7. What to hand a customer
Give them the letter of attestation and a summary: date, scope, firm, methodology, count of findings by severity, and confirmation that critical and high findings were remediated and retested.
Do not send the full report. It is a map of the application for anyone who obtains it. If a customer insists, send it under NDA, directly to a named security contact, never as a public link.
Related
Security White Paper Β· HECVAT answer set Β· AI Data Protection