What a CWE identifier on a finding does and does not tell you
A CWE identifier is a name for a kind of mistake. It is not a severity, not a vulnerability, and not something a product can be certified against, and every one of those misreadings is common enough to be worth correcting before the table. What a CWE reference is genuinely good for is shared vocabulary: it lets a finding here, an advisory somewhere else and a reviewer who has seen neither talk about the same weakness without arguing about words first.
Which layer establishes which weakness
A CWE reference on a control says the control bears on that class of weakness. It does not say the class has been eliminated, and the difference is the layer that settled it. A weakness nothing reached is uncovered, which is a different result from absent.
Repository validation
E2The layer that reaches most of this vocabulary, because most weakness classes are properties of code. How queries and commands are assembled answers CWE-89 and CWE-78. Where credential material sits, across the tree and the history, answers CWE-798 and CWE-540. A record fetched from a request identifier with no ownership check is the source half of CWE-639 and CWE-862. The resolved dependency graph answers CWE-1395 and, for packages nobody has published in years, CWE-1104. Findings cite the file, which is what lets a reader disagree with one.
Runtime validation
E4Builds and runs the application and asks it. Type-violating and oversized payloads answer CWE-20 in a way no static read can, because a validation library in the manifest says nothing about whether the handlers use it. Asking for one account's record with another account's session demonstrates CWE-639 rather than inferring it. Forced failures answer CWE-209, since a handler that redacts and a handler that was never reached look identical in source.
Public URL scan
E4Needs only the address, and reaches the weaknesses that live in the deployment rather than the code. What the service enforces about transport answers CWE-319 and CWE-295, and what it returns in its headers answers CWE-693 and CWE-1021. It can see nothing about how the software was written, so every class outside that set is reported uncovered rather than assumed.
Every CWE the pack carries
Eleven of the thirteen controls carry CWE identifiers, eighteen of them between them. Each row gives the weaknesses, how a result is established, and what passing requires. The two controls with none are verified backups and a deployment rollback path, which are reliability and operations properties rather than weakness classes, so their absence here is correct rather than a hole.
Five things people get wrong about CWE
These are not fine points of interpretation. Each one changes what a report means, and most of them are introduced by tooling rather than by the reader.
A CWE is not a CVE
CWE names a kind of weakness. CVE names one instance of one weakness in one piece of software at one version. CWE-89 is the idea of SQL injection; a CVE is the SQL injection somebody found in a named product last March. So a finding carries a CWE because it belongs to a class, and it carries a CVE only when it is a known published instance. A report that uses the two words interchangeably has not understood either, and the practical consequence is real: you can look up a CVE and patch it, and you cannot patch a CWE.
Nobody is CWE compliant, and nobody can certify you against it
There is no conformance programme, no assessment scheme and no certificate, because a dictionary is not something you comply with. MITRE publishes CWE as a shared vocabulary and has no relationship with any product that references it. If a vendor offers CWE certification, the thing being sold does not exist.
The Top 25 is a measurement, not a checklist
The Top 25 ranks weakness classes by how often they appeared in real reported vulnerabilities, weighted by severity. It describes the world rather than prescribing a scope. Working through it as a to-do list is not wrong, and it is worth knowing you are prioritising by other people's incident data rather than by anything about your own application.
A CWE identifier carries no severity
The same class covers findings that range from trivial to critical. CWE-209 on a stack trace in a public error page and CWE-209 on a message that returns a database row are the same identifier and not remotely the same problem. Severity comes from what the specific instance exposes, which is why every row above says what passing requires rather than leaving the identifier to imply it.
Mapping to a class and mapping to a base weakness are different precisions
CWE is a hierarchy. Pillars and classes sit above base weaknesses, and a mapping to a class is a broader statement than a mapping to a base. CWE-20 is a class, and a finding labelled only CWE-20 has been sorted rather than explained. CWE-89 is a base weakness and says something specific. Both appear in the table above and it is worth knowing which you are reading.
What the result looks like
An illustrative extract, not a real customer result. Every row carries the evidence grade behind it, and a control nobody could establish says so.
| Control | Status | Evidence | Note |
|---|---|---|---|
| Secrets are managed outside source code | Verified | E3 | CWE-798 and CWE-540, no credential material in the tree or the history |
| Injection-safe data access | Verified | E2 | CWE-89 and CWE-78, from reading how queries and commands are assembled |
| Object ownership is enforced server-side | Failed | E4 | CWE-639, a record returned to a session that did not own it |
| Dependencies are free of known-critical vulnerabilities | Partial | E3 | CWE-1104, two packages with no advisory and no release in over two years |
| Verified backups and restore procedure | Uncovered | Not graded | The pack maps no CWE to it, because a missing backup is not a weakness class |
Mapped to published standards
Each control is tested against a named clause, so a result means something outside our own vocabulary. Mapping is not certification, and none of these bodies endorse StackAttest.
What this does not tell you
- It is not a penetration test. A deterministic check and a runtime probe are not an adversarial human engagement, and there are classes of weakness only a person hunting for them will find.
- It is not SOC 2 and does not replace it. SOC 2 attests to organisational controls over time; this validates technical controls in the software. They answer different questions for different buyers.
- It does not replace human due diligence. It gives a reviewer repeatable evidence to start from, which is a different thing from being the reviewer.
- Controls the run could not reach are reported as uncovered rather than passed. A result you did not earn is worse than no result.
- It is not a certification and there is no such thing to award: CWE is a dictionary and a dictionary has no conformance scheme. Neither MITRE nor any CWE programme endorses, accredits, reviews or has any relationship with StackAttest. Referencing an openly published vocabulary is what anybody may do with one.
- It does not cover CWE. The catalogue runs to many hundreds of entries and the pack carries eighteen of them. Everything outside that set is untouched rather than absent, and a weakness class nobody looked for is not a class you do not have.
- A control passing does not eliminate its weakness class. It means the specific property the control tests held when it was tested, in the places the layer could reach. CWE-89 not appearing in a repository scan is evidence about the code that was read.
- It does not rank your risk. A CWE identifier is a label, severity comes from the instance, and deciding what matters in your application is a judgement about your data and your users rather than a lookup.
Questions
What is the difference between CWE and CVE?
CWE names a type of weakness, CVE names a specific instance of one in a specific product and version. CWE-89 is SQL injection as a concept. A CVE is a particular SQL injection somebody found and published. You patch a CVE; you design against a CWE. A finding in a code review normally carries a CWE and no CVE, because it is your own code rather than a published vulnerability in somebody else's.
Can software be CWE compliant or CWE certified?
No, and no vendor can offer it. CWE is a taxonomy published by MITRE with no conformance scheme attached, so there is nothing to comply with and nobody to award anything. What is meaningful is a report saying which weakness classes were examined, how, and what was found, which is a claim you can check.
Why do some findings carry a broad CWE like CWE-20?
Because CWE is a hierarchy and CWE-20 is a class rather than a base weakness. A finding labelled only CWE-20 has been sorted into a large bucket, not described. That is sometimes the honest label, when what is wrong genuinely is that input is not validated. It is more often a sign that whoever classified it did not look closely.
Does a passing control mean that weakness is not present?
It means the property the control tests held in the places the layer reached, on the date it ran. Source evidence tells you about the code that was read. Runtime evidence tells you about the deployment that was probed. Neither is a statement about code nobody looked at, which is why coverage is reported as its own number.
How does this relate to the OWASP Top 10?
The OWASP Top 10 is an awareness document grouping risks for web applications; CWE is the underlying vocabulary those groupings are built from, and the Top 10 categories map to sets of CWEs. They are not competitors. If you are trying to explain a finding to somebody, the Top 10 category is usually the friendlier name and the CWE is the precise one.
Related
Find out what is actually true of your application
Start with the layer you can run today. The report says which layers ran and what they could not reach, so the result is honest about its own limits.