This is what you'll receive.
An example report based on a real analysis (all data is fictitious).
Executive summary
This report documents the security analysis performed on example.com between April 8 and April 10, 2026. We identified 17 findings in total, distributed across 4 severity levels. The critical finding requires immediate attention: an access control vulnerability that allows an authenticated user to access invoices belonging to other customers. We recommend following the priority order laid out in the "Next steps" section — starting with the critical finding, which requires attention within the next 48 hours, through to the lower-severity ones, which can be addressed over the following 30 days.
Scope and methodology
The analysis covered the public surface of example.com, the authenticated functionality accessible through a standard test user, and the REST API documented in the Swagger provided by the client. We specifically analyzed the invoice management area, customer dashboard, contact forms, and public endpoints.
We combined multiple AI agents specialized in cybersecurity with the supervision and validation of a human expert. The agents executed automated tests to detect common vulnerabilities, configuration errors, and data exposure. The expert validated each finding manually, discarded false positives, and analyzed cases specific to the client's context.
Detailed findings
IDOR on /api/invoices/:id
The /api/invoices/:id endpoint does not validate that the authenticated user has permission to access the requested resource. Any logged-in user can access another customer's invoices simply by changing the ID in the URL.
An authenticated attacker could download every historical invoice in the system, including personal data (name, address, tax ID), payment information, and purchase history. This represents a serious risk of personal data exposure under GDPR and could result in regulatory penalties in addition to reputational damage.
1. Log in as user A (legitimate customer) 2. Access an own invoice: GET /api/invoices/12345 3. Modify the ID in the URL: GET /api/invoices/12346 4. The response returns customer B's invoice with no authorization error
Implement an ownership check on the endpoint: validate that the authenticated user's user_id matches the user_id associated with the requested invoice before returning the data. Apply the same pattern to every endpoint that receives resource IDs in the URL.
Stored XSS in support message
The "message" field on the support form does not properly escape HTML submitted by the user. An attacker can inject JavaScript that runs when a support agent opens the ticket in the admin panel.
An attacker can hijack a support agent's session, stealing authentication cookies and gaining access to the admin panel. In the worst case, this could escalate to full control of the system and all customer data.
1. Create a support ticket with the message: '<script>alert(document.cookie)</script>' 2. The support agent opens the ticket in the admin panel 3. The JavaScript runs in the agent's context, exposing their session cookies
Escape all user output in the admin panel HTML. Use a sanitization library like DOMPurify or apply standard HTML encoding when rendering user text. Set a strict Content-Security-Policy as additional defense.
JWT without expiration
The JWT tokens generated by the /api/auth/login endpoint do not include the "exp" (expiration) claim. Tokens are valid indefinitely once issued, with no way to invalidate them individually.
If a token is compromised (via phishing, malware on the user's device, etc.), the attacker maintains access to the system permanently. There is no way to invalidate the token without rotating the JWT signing key, which would log out every user simultaneously.
1. Log in via POST /api/auth/login 2. Capture the JWT token from the response 3. Decode the token (jwt.io) 4. Confirm the "exp" field is missing 5. Use the token 30 days later: still valid
Add an "exp" claim with a reasonable lifetime (15-60 minutes for access tokens). Implement a refresh token system for long-lived sessions. Establish a periodic rotation of the JWT signing key.
Missing security headers
The web server does not return important security headers in HTTP responses: Content-Security-Policy, Strict-Transport-Security, X-Frame-Options, and Referrer-Policy. These headers are the first line of defense against several types of client-side attacks.
Increases the risk of clickjacking attacks, XSS, downgrade to HTTP, and information leakage via the referrer. They are not direct attacks but reduce defense-in-depth and leave the user exposed to attack vectors that could easily be mitigated.
1. Access https://example.com with curl 2. Inspect the response headers: curl -I https://example.com 3. Verify the absence of the listed headers
Configure the web server (nginx/apache) or the proxy/CDN (Cloudflare, Vercel) to send the recommended security headers. Validate the configuration using securityheaders.com.
+ 13 more findings in the full report, each explained with the same level of detail.
Next steps
We recommend addressing the findings in this order of priority:
- URGENT — next 48 hours
Apply the fix for the critical finding (IDOR on /api/invoices/:id). While the fix is being deployed, consider temporarily limiting access to the invoice API through the WAF.
- HIGH PRIORITY — next week
Sanitize the support message field to prevent stored XSS. As a preventive measure, rotate every active session cookie in the admin panel.
- MEDIUM PRIORITY — next 30 days
Implement expiration on JWTs ("exp" claim) and consider refresh tokens for long-lived sessions. Establish a token rotation policy.
- GENERAL IMPROVEMENTS — next 60 days
Configure the recommended security headers (CSP, HSTS, X-Frame-Options, Referrer-Policy). Validate the configuration with securityheaders.com.
If you have questions about any of the recommendations or need help prioritizing the fixes, reply to the report email and we'll help.
Want a report like this for your website?
Request your audit now and get a report like this for your website.