From #5 to #2: misconfiguration scales with deploy targets, not with code
Published · Updated
Security Misconfiguration moved from #5 in 2021 to #2 in 2025. Code volume doesn't grow when you add a market, but configuration does: one codebase, four country domains, four places a setting can be wrong.
OWASP's 2025 list moves Security Misconfiguration up from #5 in 2021 to #2 in 2025. The useful part of that ranking for a small team is not the position but what the category scales with. Adding a market does not add much code. It adds places where a setting can be wrong. Tatano Energy's platform is one codebase deployed across four country domains, serving seven languages, publishing eight SEO articles every day.
One codebase gets reviewed once; each target gets configured separately
A change to shared application code is read, discussed and merged a single time. The environment it lands in is not shared in the same way. A platform that serves four country domains from one codebase has one review surface and several runtime surfaces, and nothing about merging the code guarantees that all of them received the same host rules, the same cache behaviour or the same response headers.
So the audit question for a multi-domain build is not whether the code is correct. It is whether the code is configured identically everywhere it runs, and where it is deliberately different. Locale defaults, canonical hosts, redirect chains and header sets are all legitimate places to differ per domain. Each legitimate difference is also a place where a value can be copied wrong and nobody notices, because the application still responds normally.
A header policy is a per-response setting, not a per-project one
MDN is explicit that a Content Security Policy should be delivered in the Content-Security-Policy response header and set on all responses to all requests, not just the main document. That sentence is a configuration requirement, not a coding one. A policy that is present on rendered pages and absent on an API route or an error response is not a partially applied policy. It is a misconfiguration with a specific, findable location.
Two further constraints from the same guidance keep expectations honest. For script loading, the recommended mitigation against XSS is nonce- or hash-based fetch directives, described as a strict CSP. And setting a CSP is not an alternative to sanitising input. Misconfiguration cannot be bought off by adding more headers, because headers sit alongside input handling rather than replacing it.
Access control sits on the same shelf, at number one
Broken Access Control maintains its position at #1 as the most serious application security risk, and the contributed data indicates that, on average, 3.73% of applications tested had one or more of the 40 Common Weakness Enumerations in that category. That rate is measured per application tested. It describes how often a codebase carries at least one of those weaknesses, which is a different quantity from how many deployed surfaces expose one.
The practical overlap is that a route protected in code can be reachable by configuration. Host rules, rewrite rules and environment flags all decide which requests ever reach the authorisation check. When the same application answers on four separate domains, the check is written once and relied upon four times, and only one of those four is covered by reading the diff.
Logging without alerting is how drift survives
OWASP puts it plainly: great logging with no alerting is of minimal value in identifying security incidents. Configuration drift is exactly the failure class that benefits from this gap. It produces no stack trace and no obviously broken page. It produces a missing header, a redirect that resolves to the wrong canonical host, or a path that answers when it should refuse, recorded in a log nobody reads.
Report-only mode is the lever that makes this measurable rather than theoretical. A policy can be deployed without enforcement while violations are sent to the reporting endpoint named in the policy. That turns an untested restriction into a stream of observations. The value of that stream still depends entirely on whether anything downstream of the endpoint raises its hand when the shape of the reports changes.
Launch numbers are a snapshot of configuration, not a guarantee about it. Abbys Consult shipped with hardened security headers and clean search signals from day one, zero technical SEO issues at launch and time to first byte under 200 ms. Those results describe the state of the configuration on the day it was measured. Keeping them true is a separate, continuing job from achieving them.
If you run one codebase across several domains, treat the deploy target as the unit of security review rather than the repository. Write down, per target, which headers must be present on every response, which hosts are canonical, and which differences between targets are intentional. Deploy new restrictions in report-only first, route the reports somewhere that can alert rather than merely store, and re-check the list when a market is added, because that is when the count changes.
Sources
OWASP — Top 10:2025 Introduction — https://top10.owasp.org/2025/0x00_2025-Introduction/
MDN Web Docs — Content Security Policy (CSP) — https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP
Neurolinks case study — Four markets, one codebase — https://neurolinks.be/work/tatano-energy
Neurolinks case study — A consulting firm, dressed for trust — https://neurolinks.be/work/abbys-consult
Working on a project where these methods apply?