Confidential — External Pentest

Penetration Test Report

company-a.example.com — External Black-Box Assessment

Target
company-a.example.com / www.company-a.example.com
Date
March 11, 2026
Operator
Parent Corp A Pvt Ltd
Methodology
OWASP + PTES
Overall Risk
Low–Medium
01 Executive Summary

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.

02 Security Score
80
/ 100

Finding Breakdown

Critical
0
High
2
Medium
4
Low
3
Info
5
03 Discovered Architecture
🌐
User / Browser
☁️
CloudFront CDN
TLS 1.3 termination
📦
Amazon S3
Static hosting, AES256
ComponentTechnologyDetail
FrontendReact 18.3.1Vite build, Tailwind CSS, lucide-react icons
CDNAmazon CloudFrontEdge: CCU50-P5 (Kolkata), HTTP/2
OriginAmazon S3Server-side encryption AES256, static site
DNSAWS Route 534 NS records, apex → www redirect
SSL/TLSAWS ACMRSA 2048, SHA-256, wildcard *.company-a.example.com, expires Jan 2027
EmailGoogle WorkspaceMX: smtp.google.com (priority 1)
IntegrationsOpenAIDomain verified (TXT record)
04 Tests Conducted
#Test CategoryChecks PerformedResult
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)
05 Detailed Findings
High

H1 — Missing Content-Security-Policy

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

Recommended Fix
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';
High

H2 — Missing Strict-Transport-Security (HSTS)

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

Recommended Fix
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Medium

M1 — Missing SPF Record

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.

Recommended Fix — Add DNS TXT Record
company-a.example.com. IN TXT "v=spf1 include:_spf.google.com ~all"
Medium

M2 — Missing DMARC Record

_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.

Recommended Fix — Add DNS TXT Record
_dmarc.company-a.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@company-a.example.com"
Medium

M3 — Missing X-Frame-Options (Clickjacking)

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

Recommended Fix
X-Frame-Options: DENY
Medium

M4 — Missing X-Content-Type-Options

Without nosniff, browsers may MIME-sniff response content and interpret files differently than intended, potentially treating non-executable content as scripts.

Recommended Fix
X-Content-Type-Options: nosniff
Low

L1 — Server Header Information Disclosure

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.

Recommended Fix
Override or suppress the Server header via CloudFront Response Headers Policy.
Low

L2 — AWS Internal Headers Exposed

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.

Recommended Fix
Strip x-amz-* headers via CloudFront Response Headers Policy → "Remove headers" section.
Low

L3 — Missing Referrer-Policy & Permissions-Policy

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.

Recommended Fix
Referrer-Policy: strict-origin-when-cross-origin Permissions-Policy: camera=(), microphone=(), geolocation=()
Info

Informational Findings (5)

IDFindingDetail
I1No robots.txt / sitemap.xmlSPA catch-all returns index.html for all paths. Upload these as separate S3 objects.
I2No security.txtNo /.well-known/security.txt for vulnerability disclosure. Recommended for responsible reporting.
I3No IPv6 (AAAA) recordsSite is IPv4-only. Consider adding AAAA records for broader accessibility.
I4OpenAI domain verificationTXT record openai-domain-verification=dv-REDACTED is present and publicly visible.
I5Contact email exposedceo@company-a.example.com is visible in the page footer. Consider using a generic alias like contact@company-a.example.com.
06 Sensitive File & Path Scan Results
PathStatusExposed?
/.env200 (SPA shell)Not Exposed
/.git/config200 (SPA shell)Not Exposed
/.git/HEAD200 (SPA shell)Not Exposed
/package.json200 (SPA shell)Not Exposed
/.DS_Store200 (SPA shell)Not Exposed
/wp-admin/200 (SPA shell)Not Exposed
/admin/200 (SPA shell)Not Exposed
/api/200 (SPA shell)Not Exposed
/swagger200 (SPA shell)Not Exposed
/graphql200 (SPA shell)Not Exposed
/server-status200 (SPA shell)Not Exposed
/debug200 (SPA shell)Not Exposed
/robots.txt200 (SPA shell)Missing
/sitemap.xml200 (SPA shell)Missing
/.well-known/security.txt200 (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.

07 DNS Records Discovered
TypeRecordValue
Acompany-a.example.com10.0.1.1, .80, .85, .75 (CloudFront)
AAAAcompany-a.example.comNone
MXcompany-a.example.com1 smtp.google.com
TXTcompany-a.example.comopenai-domain-verification=dv-REDACTED
NScompany-a.example.comns-1282, ns-494, ns-795, ns-2018 (.awsdns-*)
SPFcompany-a.example.comMissing
DMARC_dmarc.company-a.example.comNXDOMAIN (Missing)
DKIM_domainkey.company-a.example.comNot found
08 Subdomain Enumeration
SubdomainStatusIP / Target
www.company-a.example.comResolvesCloudFront (same as apex)
api.company-a.example.comNXDOMAIN
app.company-a.example.comNXDOMAIN
admin.company-a.example.comNXDOMAIN
staging.company-a.example.comNXDOMAIN
dev.company-a.example.comNXDOMAIN
test.company-a.example.comNXDOMAIN
mail.company-a.example.comNXDOMAIN
blog.company-a.example.comNXDOMAIN
dashboard.company-a.example.comNXDOMAIN
09 Positive Security Findings
  • No sensitive files exposed — .env, .git, package.json, .DS_Store all return SPA shell, not actual content
  • No hardcoded secrets — JS bundle contains no API keys, tokens, or credentials
  • Zero XSS attack surface — No forms, input fields, or URL parameter processing
  • HTTPS properly enforced — HTTP 301 redirects to HTTPS via CloudFront
  • TLS 1.3 — Strong transport encryption with valid AWS ACM certificate
  • S3 encryption at rest — AES256 server-side encryption enabled
  • No backend API exposed — Pure static site with no server-side attack surface
  • No cookies set — No session hijacking risk
  • Minimal subdomain footprint — Only www resolves, reduces attack surface
  • No X-Powered-By header — Framework not disclosed
10 Remediation Plan

Step 1: CloudFront Response Headers Policy (fixes H1, H2, M3, M4, L1, L2, L3)

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.

Headers to Add
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=()
Headers to Remove
Server x-amz-server-side-encryption x-amz-cf-pop x-amz-cf-id

Step 2: DNS Records in Route 53 (fixes M1, M2)

SPF Record
company-a.example.com. TXT "v=spf1 include:_spf.google.com ~all"
DMARC Record
_dmarc.company-a.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@company-a.example.com"
DKIM (via Google Workspace Admin)
Generate DKIM key in Google Admin Console → Apps → Google Workspace → Gmail → Authenticate email. Add the provided TXT record to Route 53.

Step 3: Upload Static Files to S3 (fixes I1, I2)

Upload these as separate S3 objects so the SPA catch-all doesn't override them:

robots.txt
User-agent: * Allow: / Sitemap: https://www.company-a.example.com/sitemap.xml
.well-known/security.txt
Contact: mailto:security@company-a.example.com Preferred-Languages: en Canonical: https://www.company-a.example.com/.well-known/security.txt
11 Methodology & Scope
ParameterDetail
TypeExternal black-box penetration test
Scopecompany-a.example.com, www.company-a.example.com, and common subdomains
StandardsOWASP Testing Guide v4.2, PTES, CWE/CVE references
ToolsDNS enumeration (dig), TLS analysis (openssl), HTTP header inspection, source code review, path fuzzing
Tests Run14 test categories, 50+ individual checks
LimitationsNo authenticated testing (no credentials provided). No active exploitation attempted. JavaScript-rendered content analyzed via source bundle inspection only.