StackAttestTechnical Trust
CWE

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.

Run a validationAI code auditSee an example Passport

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

E2
Repository

The 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

E4
Runtime

Builds 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

E4
URL scan

Needs 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.

Transport security (TLS) is enforced
CWE-319 cleartext transmission of sensitive information, and CWE-295 improper certificate validation. Probed against the running deployment: whether plain HTTP answers rather than redirecting, and whether the served chain validates. Passing requires TLS 1.2 or better only, a valid certificate, and that redirect.
Security response headers are present
CWE-693 protection mechanism failure, and CWE-1021 improper restriction of rendered UI layers. Read from the responses the deployment returns rather than the configuration meant to produce them, which is why the pack records runtime evidence as the floor for a pass here.
Authentication endpoints are rate limited
CWE-307 improper restriction of excessive authentication attempts, and CWE-799 improper control of interaction frequency. A rate-limiting library in the source is a gap to check; a small bounded burst against the running service is what shows a ceiling is enforced, including at an edge that source cannot see.
Object ownership is enforced server-side
CWE-639 authorisation bypass through a user-controlled key, and CWE-862 missing authorisation. These are the two halves of the same finding: 862 is no check at all, 639 is a check that trusts an identifier the caller supplies. Traced in source, and where runtime validation runs, demonstrated by asking the deployment for another account's record.
Server-side input validation on state-changing endpoints
CWE-20 improper input validation. Worth noting as the clearest example of a class rather than a base weakness: CWE-20 is a category so broad that a finding labelled only with it has been classified rather than described. Passing requires typed schemas with explicit bounds on every state-changing endpoint.
Injection-safe data access
CWE-89 SQL injection, and CWE-78 OS command injection. A repository scan of how queries and commands are assembled, looking for the construction that makes injection possible rather than for a library claiming to prevent it. A reproducible injection is a fail rather than a partial.
Secrets are managed outside source code
CWE-798 use of hard-coded credentials, and CWE-540 inclusion of sensitive information in source code. Scanned across the working tree and the history, because a credential removed in a later commit is still in every clone taken before it. Passing requires credential material outside the repository entirely.
Error responses do not leak internals
CWE-209 generation of an error message containing sensitive information. Established by forcing a failure and reading what came back, which is the only way to tell a handler that redacts from one that was never reached.
Database queries are index-backed at scale
CWE-1049 excessive data query operations in a large data table. The one performance weakness in the pack, and the one most often mistaken for a non-security concern: a table scan on a public endpoint is a denial of service somebody else can trigger cheaply.
Health checks and basic observability
CWE-778 insufficient logging. Read from configuration and probed against the running service. Passing requires enough signal to diagnose a failure after it happened, which is a lower bar than good observability and a higher one than nothing.
Dependencies are free of known-critical vulnerabilities
CWE-1395 dependency on a vulnerable third-party component, and CWE-1104 use of unmaintained third-party components. The second is the one teams skip: a package with no advisory against it and no release in two years is a risk with no identifier attached yet.

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.

ControlStatusEvidenceNote
Secrets are managed outside source codeVerifiedE3CWE-798 and CWE-540, no credential material in the tree or the history
Injection-safe data accessVerifiedE2CWE-89 and CWE-78, from reading how queries and commands are assembled
Object ownership is enforced server-sideFailedE4CWE-639, a record returned to a session that did not own it
Dependencies are free of known-critical vulnerabilitiesPartialE3CWE-1104, two packages with no advisory and no release in over two years
Verified backups and restore procedureUncoveredNot gradedThe 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.

CWEOWASP ASVS 5NIST SSDFOWASP API Security Top 10

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

OWASP ASVS assessmentNIST SSDF assessmentThe control catalogueBroken access controlVulnerable dependenciesAI code auditAI app security audit

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.

Run a validationAI code audit