Security

Last updated: March 21, 2026

PenReport is built for penetration testers, bug bounty hunters, and security consultants. We know our users evaluate security for a living, so we hold ourselves to the same standard. This page describes the technical security measures we have implemented across every layer of the application. Nothing here is aspirational — every item listed below is deployed in production today.

1. Infrastructure Security

PenReport is deployed on Vercel, which provides automatic TLS termination, DDoS mitigation, and a globally distributed edge network. All traffic between clients and our servers is encrypted with TLS 1.2 or higher. There is no option to access PenReport over plain HTTP — all connections are upgraded to HTTPS via HSTS headers.

  • Hosting: Vercel serverless functions (Node.js runtime). No long-lived servers, no SSH access surface, no manual OS patching.
  • Edge network: Static assets and pages served from Vercel's global CDN with automatic cache invalidation on deploy.
  • TLS: All connections encrypted with TLS 1.2+ using modern cipher suites. HSTS is enabled with a long max-age.
  • DDoS protection: Vercel's infrastructure-level DDoS mitigation applies to all inbound traffic automatically.
  • No tracking: We do not use advertising trackers, analytics cookies, analytics services, or third-party tracking scripts. PenReport does not run any analytics software and does not set any tracking cookies.

2. Data Encryption

In Transit

Every connection between your browser and PenReport is encrypted with TLS 1.2 or higher. This includes all API calls, authentication flows, file uploads, and webhook callbacks. Internal service-to-service communication (application to database, application to blob storage, application to third-party APIs) also uses TLS-encrypted connections exclusively.

At Rest

  • Database: Neon Postgres encrypts all data at rest using AES-256 encryption. This covers all user accounts, reports, findings, sessions, and billing records.
  • File storage: Generated PDFs, branding assets, and finding attachments are stored in ImageKit, which serves all files over HTTPS with TLS encryption in transit.
  • Backups: Database backups managed by Neon are also encrypted at rest.

Field-Level Encryption (Application Layer)

In addition to Neon's disk-level encryption, PenReport applies a second layer of encryption at the application level using AES-256-GCM. All sensitive report and finding fields are encrypted by the application before being written to the database, and decrypted only after being read back. This means that even an attacker with direct read access to the Postgres database — via a compromised database credential or a SQL injection vulnerability — would see only opaque ciphertext, not your client data.

Fields encrypted at the application layer include:

  • Reports: title, client name, client contact, target, executive summary, scope, methodology, recommendations, disclaimer
  • Findings: title, description, impact, remediation, affected asset, CVSS vector, references, remediation note

The encryption key is a 256-bit secret stored only in the server environment — it is never written to the database or logged. Each field is encrypted with a unique randomly-generated 96-bit IV, and the 128-bit GCM auth tag is verified on every decrypt to detect any tampering.

3. Authentication Security

PenReport supports two authentication methods: Google OAuth 2.0 and email/password. Both methods result in the same server-side session model — there is no difference in security posture between the two.

  • Google OAuth: Delegates authentication entirely to Google. PenReport never sees or stores Google passwords. We receive only the user's email address and profile name.
  • Email/password: Passwords are hashed using Argon2id, the algorithm recommended by OWASP for password storage. We never use bcrypt, SHA-256, MD5, or any other algorithm for password hashing. Passwords are never stored in plain text under any circumstance.
  • No account linking: If an email address is registered with one authentication method (e.g., Google OAuth), it cannot be used with another method (e.g., password). This prevents account takeover via provider confusion. We never auto-link or merge accounts.
  • Email verification: All password-registered users must verify their email address before accessing any application feature. Unverified accounts are automatically hard-deleted after 24 hours.
  • Disposable email blocking: Registration rejects known disposable and temporary email domains to prevent abuse.
  • Password requirements: Minimum 8 characters, maximum 128 characters, must include at least one uppercase letter, one number, and one special character. Validated both client-side (for UX) and server-side (for security) using Zod schemas.

4. Session Management

PenReport uses database-backed sessions exclusively. We do not use JWT-based sessions. This gives us full server-side control over session lifecycle, including the ability to immediately revoke any session.

  • Session storage: Each session is a row in our Postgres database with a cryptographically random UUID token. The session token is stored in an httpOnly, Secure, SameSite cookie.
  • Cookie security: Session cookies are set with httpOnly (not accessible to JavaScript), Secure (transmitted only over HTTPS in production), and SameSite (CSRF protection). In production, the cookie name is prefixed with __Secure- as an additional browser-enforced security measure.
  • Server-side validation: On every request, the session token is looked up in the database. User plan status, account status, and permissions are read directly from the database — never from the cookie, a JWT claim, or any client-supplied value.
  • Immediate revocation: When a user signs out, changes their password, or is suspended, their session rows are deleted from the database. The next request with the old cookie finds no matching session and is rejected. There is no “wait for token expiry” window.
  • Session expiry: Sessions have a server-enforced expiration time. Expired sessions are rejected regardless of cookie validity.

5. Password Security

  • Hashing algorithm: Argon2id with OWASP-recommended parameters. Argon2id is a memory-hard function that resists both GPU-based and side-channel attacks, making offline brute force infeasible at scale.
  • No weak algorithms: We will never use bcrypt, PBKDF2, SHA-family, or MD5 for password hashing.
  • Password reset tokens: Generated with crypto.randomBytes(32) (256 bits of entropy). The raw token is sent to the user's email. Only the SHA-256 hash of the token is stored in the database. Even if the database is compromised, the raw tokens cannot be recovered.
  • Activation tokens: Same pattern as password reset tokens — 256-bit random value, SHA-256 hash stored, raw value in email only.
  • Email change tokens: Same pattern. The old email address receives a notification. The new email address receives a confirmation link with a hashed token.
  • Google OAuth users: Have no password hash stored. There is no mechanism to set or guess a password for an OAuth-only account.

6. Brute Force and Rate Limiting

All sensitive endpoints are protected by rate limiting powered by Upstash Redis. Rate limits are applied per-IP and, where applicable, per-account.

  • Login: Progressive delay on failed attempts. Each consecutive failure increases the wait time before the next attempt is accepted. This makes automated credential stuffing impractical without locking out legitimate users.
  • No account lockout: We deliberately do not lock accounts after failed attempts. Account lockout creates a denial-of-service vector where an attacker can lock any user out of their account by intentionally failing login attempts. Instead, we use progressive delays that slow down attackers without blocking legitimate users.
  • No email enumeration: Login always returns “Invalid email or password” regardless of whether the email exists in our system. The forgot-password endpoint always returns a success message, even if the email is not registered. Timing differences are minimized.
  • Registration: Rate limited per IP to prevent mass account creation.
  • Password reset: Rate limited per IP and per email to prevent token flooding.
  • AI calls: Rate limited per user to prevent API cost abuse.
  • PDF generation: Rate limited per user. Free tier is additionally limited to 2 PDFs per month.

7. Input Validation and Injection Prevention

  • Server-side validation: Every API request body is validated against a Zod schema before any processing occurs. Requests that fail validation are rejected with a 400 response. Client-side validation exists for UX but is never trusted for security.
  • SQL injection: All database queries use parameterized statements via Drizzle ORM. There are zero raw SQL strings in the codebase. User input is never interpolated into query strings.
  • XSS prevention: React's default output encoding prevents stored and reflected XSS in the web application. For PDF generation, all user input is additionally sanitized: HTML tags are stripped and special characters are escaped before rendering into the PDF template.
  • CSRF protection: SameSite cookie attribute provides primary CSRF protection. Server actions in Next.js include built-in CSRF tokens.
  • Path traversal: All file operations use ImageKit's key-based storage. There is no local filesystem access and no user-controlled file paths.

8. API Security

  • Authentication enforcement: A centralized proxy (proxy.ts) is the single enforcement point for all protected routes. Individual route handlers do not implement their own authentication checks — this eliminates the risk of a developer forgetting to add an auth check to a new route.
  • Resource ownership: Every API route that accesses user data verifies that the requested resource belongs to the authenticated user. A valid session is not sufficient — the user must own the specific report, finding, or template they are trying to access.
  • Plan enforcement: Pro-only features are gated at the API level, not just the UI level. Even if a user crafts a direct API request, the server verifies their plan status from the database before executing the operation.
  • Cron route security: Scheduled cron endpoints require a Bearer token matching the CRON_SECRET environment variable. Unauthenticated requests receive a 401 response.

9. AI Data Security

PenReport uses Anthropic's Claude (Haiku model) to assist users in enhancing their finding descriptions. We take the following precautions with AI-processed data:

  • Server-side only: The Anthropic API key is stored as a server-side environment variable and is never sent to the browser. All AI calls are made from our server-side functions, never from client-side code.
  • Single entry point: All Anthropic SDK calls are routed through a single server-side module. There is no way for other parts of the codebase to make uncontrolled AI requests.
  • Output validation: Every AI response is validated against a strict Zod schema before use. If the AI returns unexpected or malformed data, the response is rejected and a user-visible error is shown. Invalid AI output is never silently used.
  • Token limits: AI calls are capped at 1,500 output tokens per request to prevent cost abuse and limit data exposure.
  • Anthropic data policy: Per Anthropic's privacy policy, data sent via the API is not used to train their models. Your finding data is processed to generate the response and is subject to Anthropic's data retention policies.
  • Minimized data: Only the specific finding fields needed for enhancement are sent to the AI. Full report data, user credentials, billing information, and other unrelated data are never included in AI requests.

10. Payment Security

PenReport uses Polar as our Merchant of Record for all payment processing. We never see, store, or process credit card numbers or bank account details.

  • No card data: All payment information is entered directly on Polar's PCI-compliant checkout page. Card numbers never touch our servers.
  • Webhook verification: All incoming Polar webhooks are verified using the Standard Webhooks specification with webhook-signature header. Requests with invalid or missing signatures are rejected with a 403 response before any processing occurs.
  • Idempotent processing: Every webhook event ID is recorded in a deduplification table before processing. If a duplicate event arrives (due to retry or replay), it is silently acknowledged without re-processing. This prevents double charges, double downgrades, and replay attacks.
  • Server-side plan status: A user's subscription plan is always read from the database. It is never derived from cookies, local storage, JWT claims, or any client-supplied value. UI-level plan indicators are for display only.

11. File Storage Security

  • Storage provider: All uploaded and generated files (PDFs, logos, finding attachments) are stored in ImageKit, which serves all files over HTTPS with TLS encryption in transit.
  • Access control: File URLs are not guessable. Access to blob objects requires the signed URL associated with the object.
  • Orphan cleanup: When a file is replaced (e.g., regenerating a PDF or uploading a new logo), the previous blob is deleted before the new one is stored. A scheduled cron job periodically scans for and removes any orphaned blob objects that may result from partial failures.
  • Account deletion: When a user deletes their account, all associated blob objects (PDFs, logos, attachments) are permanently deleted.

12. Error Handling and Logging

  • No information leakage: Internal error messages, stack traces, and system details are never exposed to the client. API responses return generic error messages. Full error details are logged server-side only.
  • Error tracking: Server-side errors are captured by Sentry with contextual metadata (user ID, report ID) for debugging. Sentry is configured server-side only and does not inject client-side tracking scripts.
  • No console logging: Production code does not use console.log. All error reporting goes through Sentry's structured error capture.
  • Graceful degradation: Failures in non-critical services (AI, PDF generation, blob upload) are handled gracefully. If AI assistance fails, the user can fill in findings manually. If blob upload fails after PDF generation, the PDF is served as a direct download rather than failing silently.

13. Content Security

PenReport allows users to generate shareable links for their reports. These links are designed to be secure by default:

  • Unguessable tokens: Share tokens are generated using nanoid(21), which produces 21-character URL-safe strings with approximately 126 bits of entropy. These are not sequential IDs and cannot be enumerated.
  • No indexing: Shared report pages include noindex meta tags, instructing search engines not to index them. Report content will not appear in search results.
  • Revocable: Users can disable or regenerate share tokens at any time, immediately invalidating any previously shared links.
  • Read-only: Shared report pages provide a read-only view. There is no mechanism to edit, delete, or otherwise modify a report via a share link.

14. Account Lifecycle Security

Registration

  • Disposable email domains are rejected at registration time.
  • Rate limits prevent mass account creation from a single IP.
  • Password users must verify their email before accessing any features.
  • Unverified accounts are automatically hard-deleted after 24 hours.

Password Changes

  • Changing a password requires the current password to be provided and verified.
  • After a password change, all other sessions for that user are invalidated, forcing re-authentication on all other devices.

Email Changes

  • Email changes require confirmation via a token sent to the new email address.
  • A notification is sent to the old email address so the account holder is aware of the change.
  • The change is not applied until the new email is confirmed via the token link.

Account Deletion

  • Users can permanently delete their account from the settings page. This action requires explicit confirmation.
  • The deletion process cancels any active subscription, checks for organization ownership constraints, deletes all associated blob storage objects (PDFs, logos, attachments), and permanently removes the user record and all associated data from the database.
  • Deletion is irreversible. We do not retain user data after account deletion.

15. Third-Party Security

PenReport uses the following third-party services. Each was selected for its security posture and data handling practices:

ServicePurposeData Shared
NeonPostgreSQL databaseAll application data (encrypted at rest)
VercelHosting, CDNApplication code, HTTP requests
ImageKitFile storage and CDNGenerated PDFs, branding logos, finding attachments
Anthropic (Claude)AI finding enhancementIndividual finding fields only (not full reports)
PolarPayment processingEmail, name (card data handled by Polar directly)
ResendTransactional emailEmail addresses, email content
UpstashRate limiting (Redis)IP addresses, rate limit counters
SentryError trackingError metadata, user IDs (no PII in error payloads)
GoogleOAuth authenticationOAuth token exchange (email, profile name)
CloudflareDNS managementDNS query metadata (domain lookups only)

No third-party service has access to more data than is strictly necessary for its function. We select providers based on their security posture and data handling practices.

16. Compliance and Standards

PenReport's security controls are designed with reference to industry standards and best practices:

  • OWASP Top 10: Our application security controls address all categories of the OWASP Top 10, including injection, broken authentication, sensitive data exposure, broken access control, security misconfiguration, and more.
  • OWASP ASVS: Our authentication and session management implementations follow the OWASP Application Security Verification Standard guidelines, including password storage (Argon2id), session management (server-side sessions, httpOnly cookies), and token handling (high-entropy tokens, hashed storage).
  • GDPR considerations: Users can export and delete their data. We minimize data collection. Third-party data sharing is limited to what is necessary for service operation. See our Privacy Policy for full details.
  • SOC 2: PenReport does not hold a SOC 2 certification. Our infrastructure providers (Vercel, Neon, Upstash) maintain their own SOC 2 compliance.

17. Incident Response

In the event of a security incident, we follow a structured response process:

  • Detection: Sentry error tracking, webhook event monitoring, and rate limit alerts provide real-time visibility into anomalous activity.
  • Containment: Database-backed sessions allow us to immediately revoke all sessions for affected accounts. Vercel's deployment model allows instant rollback to a previous known-good deployment.
  • Notification: If a breach affects user data, we will notify affected users via email within 72 hours of confirming the incident, in accordance with GDPR requirements.
  • Post-incident: Every incident is followed by a root cause analysis and implementation of preventive measures. Material findings are documented and, where appropriate, shared publicly.

18. Security Updates

  • Dependencies: We use tools like bun audit and GitHub Dependabot alerts to identify known vulnerabilities in our dependency tree and update affected packages.
  • Deployment: Vercel's serverless deployment model means every deploy runs on a fresh, up-to-date runtime. There are no long-lived servers that accumulate unpatched vulnerabilities.
  • This page: We update this security page whenever our security controls change materially. The “Last updated” date at the top of this page reflects the most recent revision.

19. Responsible Disclosure and Vulnerability Reporting

We appreciate the work of security researchers and welcome responsible disclosure of vulnerabilities. If you discover a security issue in PenReport, please report it following the process below.

Reporting Process

Send your report to [email protected]. Please include:

  • A clear description of the vulnerability and its potential impact.
  • Step-by-step instructions or a proof of concept to reproduce the issue.
  • The affected URL, endpoint, or component (if known).
  • Your preferred contact method for follow-up.

Response Timeline

  • Acknowledgment: We will acknowledge receipt of your report within 48 hours.
  • Triage: We will assess the severity and validity of the reported vulnerability within 5 business days.
  • Resolution: Critical and high-severity vulnerabilities will be prioritized for immediate remediation. We will keep you informed of our progress.
  • Disclosure: We will coordinate with the reporter on public disclosure timing. We ask for a reasonable window to remediate before public disclosure.

Scope

The following are in scope for vulnerability reports:

  • The PenReport web application at penreport.app
  • PenReport API endpoints under penreport.app/api/*
  • Authentication and session management flows
  • Authorization and access control bypasses
  • Data exposure or leakage vulnerabilities
  • Injection vulnerabilities (SQL, XSS, SSRF, etc.)

Out of Scope

  • Vulnerabilities in third-party services (Vercel, Neon, Polar, etc.) — please report these directly to the respective service.
  • Social engineering or phishing attacks against PenReport staff.
  • Denial of service (DoS/DDoS) attacks.
  • Automated scanning output without a demonstrated, exploitable vulnerability.
  • Issues that require physical access to a user's device.
  • Reports of missing security headers without a demonstrated attack scenario.
  • SPF/DKIM/DMARC configuration issues on non-PenReport domains.

Safe Harbor

We consider security research conducted in accordance with this policy to be authorized and will not pursue legal action against researchers who:

  • Make a good faith effort to avoid privacy violations, data destruction, and disruption to our service.
  • Do not access or modify data belonging to other users.
  • Do not perform actions that could impact the availability of PenReport for other users.
  • Report vulnerabilities to us before disclosing them publicly.
  • Do not use the vulnerability for personal gain beyond demonstrating the issue.

Recognition

We are happy to publicly acknowledge security researchers who report valid vulnerabilities, with their permission. We do not currently offer a paid bug bounty program, but we may introduce one in the future.

20. Contact

For security concerns or vulnerability reports, contact us at [email protected].

For general support or questions about this security page, contact us at [email protected].