Custom Software · Security · Production · Observability

Forty weaknesses under one heading: scoping an access control review

Published · Updated

Broken Access Control is ranked #1 in OWASP's 2025 list, yet the contributed data shows 3.73% of tested applications hit it. Rank and frequency are different instructions.

Broken Access Control keeps the top slot in OWASP's 2025 list, and the contributed data behind it indicates that, on average, 3.73% of applications tested had one or more of the 40 Common Weakness Enumerations in that category. Those two figures pull in different directions. One reads as uncommon, the other as the most serious application security risk. For a small server-rendered platform, the useful question is what the ranking actually asks you to check.

A rank is not a frequency

A category can hold position #1 while appearing in a small share of tested applications, so the position is telling you something other than how often you will meet it. Read #1 as an instruction to give the category its own dedicated pass, not as a prediction about your codebase. The list also changes shape between editions: Security Misconfiguration moved from #5 in 2021 to #2 in 2025, and Mishandling of Exceptional Conditions is new for 2025. A review scoped to the older edition is short by a category.

Forty CWEs do not fit in one checkbox

The category covers 40 separate weaknesses. That makes "is access control working?" a heading rather than a test, and a heading cannot pass or fail. The workable version for an SME platform is a list you can walk end to end: every route that returns data, every object identifier accepted from a client, every state-changing request, every administrative action. For each entry, write down who may call it and what the platform does when somebody else tries.

A control is not coverage of a category

Response headers are easy to confuse with a result. A strict CSP uses nonce- or hash-based fetch directives to control script loading as a mitigation against XSS, and the guidance is blunt about the limit: setting a CSP is not an alternative to sanitising input. The same logic applies upward. Hardened security headers, shipped from day one as on the Abbys Consult platform, are one layer in front of one class of problem. They do not close out a category of forty weaknesses.

The error path makes decisions too

Mishandling of Exceptional Conditions is new for 2025, and it sits next to access control for a practical reason: a lot of authorisation gets decided while something is already going wrong. The timeout, the failed upstream call, the malformed identifier. Each one takes a branch that may be less reviewed than the happy path. Walk the same route list again, but this time ask what the failure branch returns, and to whom.

Logging that nobody is reading

Great logging with no alerting is of minimal value in identifying security incidents. That line matters most on exactly the platforms that advertise low operational overhead. Where client time spent on operations is 0 h, as on the Abbys Consult site, or manual intervention required is 0, as on the Tatano Energy platform, nobody is tailing a log file by habit. Either an alert reaches a person, or the logging is a record written for an audience that does not exist.

Every response, including the generated ones

A CSP should be set on all responses to all requests, not just the main document. On a platform that generates its own inventory, that phrase has teeth. The Tatano Energy build runs one codebase across four country domains in seven languages, publishing eight SEO articles every day. Pages the team never hand-wrote still have to carry the same headers and obey the same route rules, which means the check belongs in the template and the response layer, not in a launch checklist.

Treat the ranking as a scoping instruction rather than a risk estimate. Write the route list once, record who may call each entry, then run it twice: once for the normal path, once for the failure branch. Confirm the headers land on every response, including machine-generated pages, and confirm at least one alert reaches a human. That is a smaller piece of work than it sounds, and it is auditable, which a heading never is.

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 — A consulting firm, dressed for trust — https://neurolinks.be/work/abbys-consult

Neurolinks case study — Four markets, one codebase — https://neurolinks.be/work/tatano-energy

Working on a project where these methods apply?