DAST scanner · reads response headers

Security Headers Scanner

Browsers only enforce protections the server asks for. The scanner fetches your pages, reads the response headers and reports each protection that is absent plus the headers that reveal software versions.

DASTLow–HighMissing headers · Info disclosure8 checks

One response, eight checks

The scanner sends a plain GET and looks only at the response headers. Five checks are about a header being absent, one about a header that must hold a specific value, one pair about a header that gives too much away. The same checks run on every URL it tests.

GET / returns header names are lower-cased first HTTP/1.1 200 OK content-type: text/html content-security-policy: default-src 'self'; frame-ancestors 'none' x-content-type-options: nosniff server: nginx/1.19.0 x-powered-by: Express not sent at all: strict-transport-security permissions-policy · referrer-policy Checks header · what was seen · result · severity if flagged Strict-Transport-Security absent flag HIGH 0.95 Content-Security-Policy present ok MEDIUM 0.85 Clickjacking guard CSP frame-ancestors ok MEDIUM 0.90 X-Content-Type-Options nosniff ok MEDIUM 0.95 Permissions-Policy absent flag LOW 0.80 Referrer-Policy absent flag LOW 0.80 Server nginx/1.19.0 flag LOW 0.90 X-Powered-By Express flag LOW 0.90

1The scanner requests a URL and lower-cases the header names. Everything below is decided from this one response. Three headers were never sent, and two are sent with details a visitor should not need.

2Presence checks. HSTS, Content-Security-Policy, Permissions-Policy and Referrer-Policy are flagged only when the header is absent. A missing Strict-Transport-Security is HIGH at 0.95, the others MEDIUM or LOW.

3Two checks with logic. Clickjacking is reported only when both X-Frame-Options and a CSP frame-ancestors directive are missing. X-Content-Type-Options must equal nosniff; a present header with another value is flagged too.

4Disclosure checks. Server is flagged only when it contains a version such as /1.19; a bare nginx passes. X-Powered-By is flagged whenever it is present. Both are LOW, 0.90.

One finding per server, not per URL

Security headers are usually set once for the whole server. If the scanner tests several URLs it would report the same gap on each, so a deduplication pass collapses the repeats.

URL tested HSTSCSPPerm.-PolicyServer ver. / /login /api/health filled circle = a finding raised on that URL Reported 10 findings same gap repeated per URL 4 findings HSTSonce · all 3 URLs CSPonce · all 3 URLs Perm.-Policyonce · all 3 URLs Server ver.kept · /api/health only Collapsed findings gain a note: "missing on all 3 tested endpoints"

1Three URLs were tested and raised ten findings between them. HSTS, CSP and Permissions-Policy are missing on every URL; the Server version leaks on one.

2Findings are grouped by title. A group with as many members as there are URLs that produced findings is reported once, with a note that the header is missing server-wide. Ten findings drop to four.

3The Server version is present on one URL out of three, so it stays as its own finding with that URL. A header that differs by route is not merged away.

What the fix block clears

Because the headers are server-wide, one configuration block removes most findings at once. A few things it does not touch.

next.config.js headers() no headers configured yet Strict-Transport-Security: max-age=63072000 Content-Security-Policy: default-src 'self' X-Frame-Options: DENY X-Content-Type-Options: nosniff Referrer-Policy: strict-origin-when-cross-origin Permissions-Policy: camera=(), microphone=() The block sets six headers. It does not remove Server or X-Powered-By. Findings from the scan HIGHMissing Strict-Transport-Security MEDIUMMissing Content-Security-Policy MEDIUMMissing clickjacking protection MEDIUMMissing X-Content-Type-Options LOWMissing Referrer-Policy and Permissions-Policy LOWServer: nginx/1.19.0 · X-Powered-By: Express

1A scan of an unconfigured server lists a finding for each of the six missing headers plus the two disclosure headers.

2Adding Strict-Transport-Security and Content-Security-Policy clears the High finding and one Medium.

3The other four headers clear the clickjacking, nosniff, Referrer-Policy and Permissions-Policy findings.

4The block shown in the markdown sets only the six security headers. Server and X-Powered-By are produced by the web server or framework, so they need their own change.

Why it matters

Why it matters

Missing headers make other attacks easier. No CSP lets an XSS load external scripts and exfiltrate data. No HSTS lets a man in the middle strip HTTPS. No X-Frame-Options lets an attacker embed your site in an iframe and trick users into clicking hidden buttons. An exposed Server version tells an attacker which CVEs to try.

British Airways (2018)

The Magecart XSS attack was worsened by the absence of a Content Security Policy. A CSP with script-src 'self' would have blocked the injected third-party script from executing.

Vulnerable vs fixed code

// BAD: nothing sets security headers, and the framework advertises itself
const app = express()   // replies with X-Powered-By: Express
app.get("/", (req, res) => res.send(page))

Limits and what it needs

CheckReports whenSeverity · confidence
Strict-Transport-Securityheader absentHigh · 0.95
Content-Security-Policyheader absentMedium · 0.85
Clickjacking protectionX-Frame-Options absent and no frame-ancestors in the CSPMedium · 0.90
X-Content-Type-Optionsabsent, or present with a value other than nosniffMedium · 0.95
Permissions-Policyheader absentLow · 0.80
Referrer-Policyheader absentLow · 0.80
Servervalue contains a version like /1.19Low · 0.90
X-Powered-Byheader presentLow · 0.90
What it deliberately stays quiet about

Only presence and, for nosniff, one exact value are checked. A header that is present but weak, such as a CSP containing unsafe-inline or an HSTS with a tiny max-age, is not reported. Every distinct URL is requested, shortest URL first, with a plain GET (credentials optional: the scan's auth headers are sent if there are any). The documented dedup only merges findings that appear on every URL that produced one.