company-a.example.com — External Black-Box Assessment
An external black-box penetration test was conducted against company-a.example.com on March 11, 2026. The site is a pre-launch React single-page application hosted on Amazon S3 + CloudFront with DNS on AWS Route 53 and email via Google Workspace.
The overall attack surface is minimal — no backend APIs, no user input fields, and no session management were found. The primary findings relate to missing HTTP security headers and absent email authentication records (SPF, DMARC, DKIM), both of which are configuration-level fixes requiring no code changes.
No critical vulnerabilities were identified. No sensitive data exposure was found.
| Component | Technology | Detail |
|---|---|---|
| Frontend | React 18.3.1 | Vite build, Tailwind CSS, lucide-react icons |
| CDN | Amazon CloudFront | Edge: CCU50-P5 (Kolkata), HTTP/2 |
| Origin | Amazon S3 | Server-side encryption AES256, static site |
| DNS | AWS Route 53 | 4 NS records, apex → www redirect |
| SSL/TLS | AWS ACM | RSA 2048, SHA-256, wildcard *.company-a.example.com, expires Jan 2027 |
| Google Workspace | MX: smtp.google.com (priority 1) | |
| Integrations | OpenAI | Domain verified (TXT record) |
| # | Test Category | Checks Performed | Result |
|---|---|---|---|
| 1 | HTTP Security Headers | CSP, HSTS, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Referrer-Policy, Permissions-Policy, cookie flags | Issues Found |
| 2 | HTTPS / TLS Configuration | HTTP → HTTPS redirect, TLS version, certificate validity, cipher suite | Pass |
| 3 | Information Disclosure | Server header, X-Powered-By, AWS internal headers, HTML comments, error pages | Low Risk |
| 4 | Sensitive File Exposure | .env, .git/config, .git/HEAD, package.json, .DS_Store, wp-admin, server-status (15 paths tested) | Pass |
| 5 | DNS Reconnaissance | A, AAAA, MX, TXT, NS, CNAME, SOA records; DMARC, SPF, DKIM checks | Issues Found |
| 6 | Subdomain Enumeration | www, api, app, admin, staging, dev, test, mail, blog, dashboard (10 subdomains) | Pass |
| 7 | SSL Certificate Audit | Issuer, validity, SANs, key size, signature algorithm | Pass |
| 8 | Frontend Source Analysis | Hardcoded keys/secrets, API endpoints, inline scripts, exposed credentials | Pass |
| 9 | XSS Vector Analysis | Forms, input fields, URL parameter handling, dynamic rendering | Pass |
| 10 | Clickjacking | iframe embeddability, X-Frame-Options, CSP frame-ancestors | Vulnerable |
| 11 | API Endpoint Discovery | /api/, /graphql, /swagger, /debug — checked for exposed backends | Pass |
| 12 | Third-Party Dependencies | JS libraries, external iframes (YouTube), third-party scripts | Info |
| 13 | Email Security (SPF/DMARC/DKIM) | SPF TXT record, _dmarc TXT record, DKIM selectors | Missing |
| 14 | Cookie Security | Secure, HttpOnly, SameSite flags | N/A (no cookies) |
No CSP header is returned by the server. Without CSP, the browser places no restrictions on where scripts, styles, or other resources can be loaded from. If any XSS vector is introduced in the future (e.g., via user-generated content, URL parameter processing, or third-party script compromise), it would be fully exploitable.
Affected URL: https://www.company-a.example.com
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-src https://www.youtube.com; font-src 'self';
Although HTTP redirects to HTTPS (301), the absence of an HSTS header means first-time visitors or victims of SSL-stripping attacks (e.g., on public Wi-Fi) can be intercepted on the initial plaintext request before the redirect occurs.
Affected URL: All responses from www.company-a.example.com
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
No SPF (Sender Policy Framework) TXT record exists for company-a.example.com. This means any mail server in the world can send email pretending to be from @company-a.example.com without failing SPF checks. This enables phishing and email spoofing attacks impersonating Company A.
company-a.example.com. IN TXT "v=spf1 include:_spf.google.com ~all"
_dmarc.company-a.example.com returns NXDOMAIN. Without DMARC, receiving mail servers have no policy to verify that emails from @company-a.example.com are legitimate. Combined with the missing SPF, this makes email spoofing trivial.
_dmarc.company-a.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@company-a.example.com"
The site can be embedded in an <iframe> on any domain. An attacker could overlay invisible UI elements on top of the framed page, tricking users into clicking unintended actions (clickjacking).
X-Frame-Options: DENY
Without nosniff, browsers may MIME-sniff response content and interpret files differently than intended, potentially treating non-executable content as scripts.
X-Content-Type-Options: nosniff
The response header Server: AmazonS3 reveals the backend storage technology. While not directly exploitable, it helps attackers narrow down the technology stack for targeted attacks.
Override or suppress the Server header via CloudFront Response Headers Policy.
Headers x-amz-server-side-encryption: AES256, x-amz-cf-pop, and x-amz-cf-id expose internal infrastructure details including encryption type and CDN edge node.
Strip x-amz-* headers via CloudFront Response Headers Policy → "Remove headers" section.
No Referrer-Policy or Permissions-Policy headers are set. Referrer leakage can expose URL paths to third parties. Missing Permissions-Policy allows access to browser APIs (camera, mic, geolocation) by default.
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
| ID | Finding | Detail |
|---|---|---|
| I1 | No robots.txt / sitemap.xml | SPA catch-all returns index.html for all paths. Upload these as separate S3 objects. |
| I2 | No security.txt | No /.well-known/security.txt for vulnerability disclosure. Recommended for responsible reporting. |
| I3 | No IPv6 (AAAA) records | Site is IPv4-only. Consider adding AAAA records for broader accessibility. |
| I4 | OpenAI domain verification | TXT record openai-domain-verification=dv-REDACTED is present and publicly visible. |
| I5 | Contact email exposed | ceo@company-a.example.com is visible in the page footer. Consider using a generic alias like contact@company-a.example.com. |
| Path | Status | Exposed? |
|---|---|---|
/.env | 200 (SPA shell) | Not Exposed |
/.git/config | 200 (SPA shell) | Not Exposed |
/.git/HEAD | 200 (SPA shell) | Not Exposed |
/package.json | 200 (SPA shell) | Not Exposed |
/.DS_Store | 200 (SPA shell) | Not Exposed |
/wp-admin/ | 200 (SPA shell) | Not Exposed |
/admin/ | 200 (SPA shell) | Not Exposed |
/api/ | 200 (SPA shell) | Not Exposed |
/swagger | 200 (SPA shell) | Not Exposed |
/graphql | 200 (SPA shell) | Not Exposed |
/server-status | 200 (SPA shell) | Not Exposed |
/debug | 200 (SPA shell) | Not Exposed |
/robots.txt | 200 (SPA shell) | Missing |
/sitemap.xml | 200 (SPA shell) | Missing |
/.well-known/security.txt | 200 (SPA shell) | Missing |
Note: All paths return HTTP 200 with the SPA index.html shell due to the S3/CloudFront catch-all routing. No actual file content is exposed — every path renders the same React application.
| Type | Record | Value |
|---|---|---|
A | company-a.example.com | 10.0.1.1, .80, .85, .75 (CloudFront) |
AAAA | company-a.example.com | None |
MX | company-a.example.com | 1 smtp.google.com |
TXT | company-a.example.com | openai-domain-verification=dv-REDACTED |
NS | company-a.example.com | ns-1282, ns-494, ns-795, ns-2018 (.awsdns-*) |
SPF | company-a.example.com | Missing |
DMARC | _dmarc.company-a.example.com | NXDOMAIN (Missing) |
DKIM | _domainkey.company-a.example.com | Not found |
| Subdomain | Status | IP / Target |
|---|---|---|
www.company-a.example.com | Resolves | CloudFront (same as apex) |
api.company-a.example.com | NXDOMAIN | — |
app.company-a.example.com | NXDOMAIN | — |
admin.company-a.example.com | NXDOMAIN | — |
staging.company-a.example.com | NXDOMAIN | — |
dev.company-a.example.com | NXDOMAIN | — |
test.company-a.example.com | NXDOMAIN | — |
mail.company-a.example.com | NXDOMAIN | — |
blog.company-a.example.com | NXDOMAIN | — |
dashboard.company-a.example.com | NXDOMAIN | — |
Create a single CloudFront Response Headers Policy in the AWS Console or via IaC. Attach it to the distribution. This fixes 7 of 9 findings with zero code changes.
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-src https://www.youtube.com; font-src 'self';
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Server
x-amz-server-side-encryption
x-amz-cf-pop
x-amz-cf-id
company-a.example.com. TXT "v=spf1 include:_spf.google.com ~all"
_dmarc.company-a.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@company-a.example.com"
Generate DKIM key in Google Admin Console → Apps → Google Workspace → Gmail → Authenticate email. Add the provided TXT record to Route 53.
Upload these as separate S3 objects so the SPA catch-all doesn't override them:
User-agent: *
Allow: /
Sitemap: https://www.company-a.example.com/sitemap.xml
Contact: mailto:security@company-a.example.com
Preferred-Languages: en
Canonical: https://www.company-a.example.com/.well-known/security.txt
| Parameter | Detail |
|---|---|
| Type | External black-box penetration test |
| Scope | company-a.example.com, www.company-a.example.com, and common subdomains |
| Standards | OWASP Testing Guide v4.2, PTES, CWE/CVE references |
| Tools | DNS enumeration (dig), TLS analysis (openssl), HTTP header inspection, source code review, path fuzzing |
| Tests Run | 14 test categories, 50+ individual checks |
| Limitations | No authenticated testing (no credentials provided). No active exploitation attempted. JavaScript-rendered content analyzed via source bundle inspection only. |