Skip the stagnant list of attacks and weaknesses in favor of an approach the deals with the design and implementation of your site. Many items relate to a site’s use of HTTP and HTML. Neither of these arrived in the 21st century. In fact, they date back to the ’90s. HTML 4.01 was made official in December 1999, when Jessica Simpson and Whitney Houston had hits on the Billboard Top 10, and The Green Mile and Galaxy Quest were in the Top 10 grossing movies. (I realize these references reinforce the mighty U.S. cultural hegemony, but the U.K. album charts for that month included Boyzone and Westlife so you’ll have to forgive me.)
But let’s get back to the OWASP Top 10. There’s an implication here that some compelling reason exists for ignoring it. Simply put, it’s uninteresting over time and unhelpful for more than nomenclature.
If you love the OWASP Top 10, don’t bother reading the rest of this post. Skip to the comments section and start typing. The curious may read on. The impatient may skip to the last paragraph.
The OWASP Top 10 list originated as a clone of the SANS Top 10 for Windows and Unix vulnerabilities (ostensibly the most popular ways those operating systems were compromised). The list made an initial mistake of putting itself forward as a standard, which encouraged adoption without comprehension — taking the list as a compliance buzzword rather than a security starting point. The 2010 update mercifully raises red flags about the danger of falling into the trap of myopic adherence to the list.
The list has a suspicious confirmation bias such that popular, trendy vulnerabilities rise to the top, possibly because that’s what researchers are looking for. And these researchers are coming from a proactive rather than forensics perspective of web security, meaning that they rely on vulnerabilities discovered in a web site vs. vulnerabilities actively exploited to compromise a web site.
Two of the list’s metrics, Prevalence and Detectability, appear curiously correlated. A vulnerability that’s easy to detect (e.g. cross-site scripting) has a widespread prevalence. I question the causality of this relationship: Are they widespread because they’re easy to detect? This arises because an entry like A7: Insecure Cryptographic Storage has a difficult detectability and (therefore?) uncommon prevalence. Yet the last few months marked clear instances of web sites that stored users’ passwords with no salt and poor encryption . This seems to reinforce the idea that the list is also biased towards a blackbox perspective of web applications at the expense of viewpoints from developers and architects.
Six of the list’s entries have easy detectability. This seems strange. If more than half of the risks to a web application are easy to find, why do these problems remain so widespread that site owners can’t squash them? The list of well-funded, well-established applications that have had HTML injection problems has more than a few familiar names: Amazon, eBay, Facebook, GMail, Paypal, and Twitter . Maybe detectability isn’t so easy when dealing with large, complex systems.
If you’ve ever “tested for the OWASP Top 10” or asked a vendor if their scanner “tests for the OWASP Top 10” then you’ve tested the implementation of that web site, but not necessarily its design.
Web application vulnerabilities roughly fall into a design or implementation error. A great example of a design error is cross-site request forgery (CSRF). CSRF exploits the natural, expected way a browser submits requests from the iframe and img tags that appear in HTML. It was manifest from the first form tag in the ’90s, but didn’t reach critical mass (i.e. inclusion on the Top 10) until 2007. SQL injection was another design error: the ever-insecure commingling of code and data. (SQL injection occurs because the grammar of a database query could be modified by the data used by the query.)
These design problems inspired efforts to create viable solutions. Naive solutions blacklisted the common characteristics of an exploit, but such approaches dealt with implementation rather than design. Superior solutions introduced new concepts, the Origin header for CSRF and prepared statements for SQL injection, that enabled developers to address the systemic cause of the vulnerabilities rather than paper over the bugs that allowed them to emerge on the site.
Alas, not every vulnerability gets the secure by design treatment. HTML injection (known as cross-site scripting in the Vulgar Latin) attacks seem destined to be the ever-living cockroaches of the web. Where SQL injection combined code and data in the form of database queries, HTML injection combines user-supplied data with HTML. No one yet has created to reliable “prepared statement/parameterized query” equivalent for updating the DOM.
This doesn’t mean implementation errors can’t be dealt with: Coding guidelines provide secure alternatives to common patterns, frameworks enable consistent usage of recommended techniques, automated scanners provide a degree of verification.
This delineation of design and implementation plays second fiddle to the Siren’s Song of the OWASP Top 10. (Anecdote alert.) All too often the phrase, “Does it scan for the OWASP Top 10?” or “How does this compare to the OWASP Top 10?” arises when discussing a scanner’s capability or the outcome of a penetration test. Not exactly the list’s fault, but the inquirer’s. Never the less, the list has become a beast that drives web security in spite of the fact that applications have narrowly-defined, easy-to-detect problems like HTML injection (XSS) as well as widely-defined, broad, combined concepts like Broken Authentication and Session Management. After all, twenty years into the web sites still ask for an email address and password to authenticate users.
All software has bugs and bugs lead to implementation problems like HTML injection or forgetting to use a prepared statement for a SQL query. Such problems are usually independent of the site’s design. On the other hand, the security of authentication and session management have strong ties to a site’s design. Yet a scanner or penetration test that can’t execute a login bypass via SQL injection or brute force an administrator’s password doesn’t imply the site’s design is strong or correct — it simply means those attacks failed.
Maybe this misinterpretation of the OWASP Top 10 was already obvious: A scanner or penetration test that goes through the list verifies that common attacks can or cannot compromise the site, but strict adherence to the list doesn’t mean that the site is well-designed.
Fine, you say, complain about the rot in Denmark, but where’s the better replacement?
The Common Weakness Enumeration  (CWE) provides an excellent alternative to the stale OWASP list. To quote directly from its site, CWE “provides a unified, measurable set of software weaknesses that is enabling more effective discussion, description, selection, and use of software security tools and services that can find these weaknesses in source code and operational systems as well as better understanding and management of software weaknesses related to architecture and design.”
Several of the weaknesses aren’t even specific to web applications, but they’ve clearly informed attacks against web applications. CSRF evolved from the “Confused Deputy” described in 1988 . SQL injection and HTML injection have ancestors in Unix command injection used against SMTP and finger daemons, to name just two. Pointing developers to these concepts provides a richer background on security.
If you care about your site’s security, engage your developers and security team in the site’s design and architecture. Use tools or manual testing to verify its implementation. Refer to the CWE for coding guidelines. And keep the OWASP Top 10 list around as an artifact of the types of vulnerabilities that interests the security community — a different community, one might guess, from the attackers targeting web sites.
As a final experiment, invert the sense of the attacks and weaknesses to a prescriptive list of Mike’s Top 10 and see how that influences developers:
M1. Validate data from the client.
M2. Sanitize data for the appropriate context when displayed in the client.
M3. Apply strong authentication schemes.
M4. Use strong PRNG and high entropy when access control relies on knowledge of a value.
M5. Enforce strong session management and workflows (and set the Origin header).
M6. Configure the platform securely.
M7. Use established, recommended cryptographic systems and techniques.
M8. Apply authorization checks consistently.
M9. Turn on SSL wherever possible.
M10. Restrict data to expected values.