# Common Weakness Enumeration (CWE)

> CWE is MITRE's catalog of software and hardware weakness types. A CWE ID names a vulnerability's root-cause mistake; a CVE names one instance.

Also known as: CWE ID, MITRE CWE

Source: https://socket.dev/glossary/common-weakness-enumeration-cwe

Last updated: 2026-11-06

Common Weakness Enumeration (CWE) is a catalog of software and hardware weakness types, run by MITRE and sponsored by CISA. Each entry has a CWE ID, such as CWE-79 for cross-site scripting. A CVE identifies one vulnerability in one product; the CWE ID attached to it names the root-cause mistake, so one flaw can be counted across many products.

A CWE ID describes a mistake, not an attack and not an intent. It travels as metadata: the organization that publishes a [CVE record](https://socket.dev/glossary/common-vulnerabilities-and-exposures-cve) puts it in the record's `problemTypes` field, and the [GitHub Advisory Database](https://socket.dev/glossary/github-advisory-database) copies it into the `cwe_ids` field of its [OSV](https://socket.dev/glossary/osv)-format records. As of November 2026, the list is at [CWE 5.0](https://cwe.mitre.org/news/archives/news2026.html), released October 28, 2026, with 956 weaknesses among 1,477 entries. Our position: CWE is the right vocabulary for root-cause trends and static analysis rules, a weak signal for triage, and close to irrelevant for catching malicious packages. On November 6, 2026, the OpenSSF malicious-packages dataset held 239,975 malware reports. Exactly 7 of them referenced a CVE.

## What is CWE in cybersecurity?

CWE is a shared dictionary of the mistakes that make software exploitable. CISA sponsors it, and the Homeland Security Systems Engineering and Development Institute, which MITRE operates, manages it, according to the [CWE FAQ](https://cwe.mitre.org/about/faq.html). The program started in 2006 and marked its 20th anniversary on September 29, 2026.

Each CWE entry carries an ID, a name, an abstraction level, a description, and relationships to other entries. Most also list detection methods, mitigations, and observed examples drawn from real CVEs. Every weakness entry also carries a vulnerability-mapping usage, which tells you whether you may attach that ID to a real vulnerability at all. We come back to that field below, because much of the CWE data in circulation ignores it.

In practice you rarely visit cwe.mitre.org. You meet CWE IDs inside other records. Here is the CNA container of the CVE record for the [Qix maintainer compromise](https://socket.dev/blog/npm-author-qix-compromised-in-major-supply-chain-attack), published by GitHub's CNA on September 15, 2025:

```json
"cna": {
  "title": "debug@4.4.2 contains malware after npm account takeover",
  "problemTypes": [{
    "descriptions": [{
      "cweId": "CWE-506",
      "lang": "en",
      "description": "CWE-506: Embedded Malicious Code",
      "type": "CWE"
    }]
  }]
}
```

The CWE list changes on a published schedule. CWE 4.20, released April 30, 2026, added view CWE-1448 for weaknesses in AI and machine learning products. CWE 5.0 added 16 weaknesses, deprecated CWE-377, CWE-391, and CWE-613, and shipped Schema 8.0 with breaking changes. The Category element is gone, replaced by Grouping, and the XML namespace moved to `http://cwe.mitre.org/cwe-8`. MITRE also released CWE 4.21 the same day for consumers still parsing Schema 7.x. If your tooling ingests the CWE XML, it needs work before it can read 5.0.

## What is the difference between CVE and CWE?

A CVE identifies one vulnerability in one product; a CWE classifies the kind of mistake behind it. The CWE FAQ puts the relationship in one line: "one CWE entry can often be the root cause of many different CVE Records."

The [form-data vulnerability](https://socket.dev/blog/critical-vulnerability-in-popular-npm-form-data-package) of July 2025 shows both identifiers in one advisory. The npm package picked multipart boundaries with `Math.random()`, so an attacker who could observe other outputs of the generator could predict a boundary and inject form fields. The GitHub-reviewed advisory record looks like this:

```json
{
  "id": "GHSA-fjxv-7rqg-78g4",
  "aliases": ["CVE-2025-7783"],
  "summary": "form-data uses unsafe random function in form-data for choosing boundary",
  "database_specific": {
    "cwe_ids": ["CWE-330"],
    "severity": "CRITICAL",
    "github_reviewed": true
  }
}
```

The advisory itself notes that the same bug had recently been found in undici. That is CWE doing its job: two CVEs in two packages, one weakness type.

The record also shows how loose mapping is in practice. CWE-330, Use of Insufficiently Random Values, is a Class that MITRE marks Discouraged for mapping. Its Base-level child, CWE-338, Use of Cryptographically Weak Pseudo-Random Number Generator, is marked Allowed and describes `Math.random()` exactly. A carefully reviewed advisory still landed on the coarser label, and our own coverage repeated it.

|  | CVE | CWE | CVSS |
| --- | --- | --- | --- |
| Question it answers | Which vulnerability is this? | What kind of mistake caused it? | How severe is it, in the abstract? |
| Unit | One flaw in one product's version range | One weakness type, shared across products | One score per CVE, per scorer |
| form-data example | CVE-2025-7783 | CWE-330 (better fit: CWE-338) | CVSS 4.0 vector rated Critical by GitHub |
| Who assigns it | A CVE Numbering Authority (CNA) | The CNA, with CISA's Vulnrichment and NVD as backstops | The CNA, NVD, and GitHub, often with different results |
| Use it for | Matching your dependencies to advisories | Trend analysis, SAST rules, training | A first sort, never the final word |

Verdict: use CVE to answer "am I affected?" and CWE to answer "what do we keep getting wrong?" Use neither to answer "what do I fix first?" That question needs [reachability analysis](https://socket.dev/glossary/reachability-analysis) and exploitation evidence such as [CISA's Known Exploited Vulnerabilities (KEV) catalog](https://socket.dev/glossary/cisa-kev). A severity score from [CVSS](https://socket.dev/glossary/common-vulnerability-scoring-system) is a starting point, and a CWE ID adds nothing to the ordering.

## The CWE hierarchy: pillars, classes, bases, and variants

The CWE hierarchy sorts weaknesses into four abstraction levels, from Pillar down to Variant. MITRE defines a Pillar as the "highest-level weakness that cannot be made any more abstract." A Class is described abstractly, independent of language or technology. A Base has enough detail to infer detection and prevention methods. A Variant is tied to a specific language or technology.

Views slice the same entries for different readers. CWE-699 organizes weaknesses by software development concepts, CWE-1194 covers hardware design, and CWE-1000 is the full research hierarchy. CWE-1003, Weaknesses for Simplified Mapping of Published Vulnerabilities, is a deliberately short list for databases; the FAQ says the NVD "has historically added CWE mappings to CVE Records using the CWE-1003 view." Groupings, called Categories before CWE 5.0, collect entries that share an attribute. Views and groupings are navigation aids. You never map a vulnerability to one.

The branch that holds malicious code is the clearest way to see how the levels nest:

> CWE-506 lineage in CWE 5.0: Pillar CWE-710 Improper Adherence to Coding Standards, Discouraged; Class CWE-684 Incorrect Provision of Specified Functionality, Allowed-with-Review; Class CWE-912 Hidden Functionality, Allowed-with-Review; its children Class CWE-506 Embedded Malicious Code, Allowed-with-Review, and Base CWE-1242 Inclusion of Undocumented Features or Chicken Bits; CWE-506 has Base children CWE-507 Trojan Horse, CWE-510 Trapdoor, CWE-511 Logic/Time Bomb, CWE-512 Spyware

Figure 1 shows the CWE-506 lineage in CWE 5.0. Pillar CWE-710, Improper Adherence to Coding Standards, is the root, and MITRE marks it Discouraged. Its child CWE-684, Incorrect Provision of Specified Functionality, is a Class marked Allowed-with-Review. CWE-684's child CWE-912, Hidden Functionality, is a Class marked Allowed-with-Review. CWE-912 has two children: CWE-506, Embedded Malicious Code, a Class marked Allowed-with-Review, and CWE-1242, Inclusion of Undocumented Features or Chicken Bits, a Base. CWE-506 has four Base children: CWE-507 Trojan Horse, CWE-510 Trapdoor, CWE-511 Logic/Time Bomb, and CWE-512 Spyware.

The placement is revealing. In CWE's model, a credential stealer injected into a package is a descendant of "Improper Adherence to Coding Standards." The taxonomy treats malware as a property of the product's code, because CWE was built to describe defects that the product's own developers introduce.

## How do CNAs map a vulnerability to a CWE?

CNAs map a vulnerability to a CWE through root cause mapping, which MITRE defines as "the identification of the underlying cause(s) of a vulnerability." The [mapping guidance](https://cwe.mitre.org/documents/cwe_usage/guidance.html) is explicit that "CWEs at the Base and Variant level should be used whenever possible." Every entry declares one of four usage levels:

- **Allowed:** the ID may be used to map real-world vulnerabilities.
- **Allowed-with-Review:** usable in limited cases after checking whether a child fits better. Many Classes, including CWE-506 and CWE-912, sit here.
- **Discouraged:** the ID "should not be used to map to real-world vulnerabilities." Pillars such as CWE-284 and CWE-710 sit here, along with overused Classes such as CWE-20 Improper Input Validation.
- **Prohibited:** the ID "must not be used." Views such as CWE-1003 are Prohibited.

The CNA that publishes the CVE record does the first mapping. For years, the [National Vulnerability Database (NVD)](https://socket.dev/glossary/national-vulnerability-database-nvd) added or corrected mappings during enrichment. In April 2026, NIST [stopped enriching most CVEs](https://socket.dev/blog/nist-officially-stops-enriching-most-cves) and now prioritizes KEV entries, federal software, and software designated critical. That leaves CNAs and CISA's Vulnrichment container as the practical sources of CWE data for most new records.

We measured what that produces. We scanned every CVE record published between January 1 and November 6, 2026 under a CVE-2025 or CVE-2026 ID, from [CVEProject/cvelistV5](https://github.com/CVEProject/cvelistV5) at commit `08ff21a`:

| Measure (2026 records, as of November 6) | Count | Share |
| --- | --- | --- |
| Published CVE records | 89,756 | 100% |
| At least one CWE from any container | 81,822 | 91.2% |
| A CWE supplied by the CNA itself | 66,976 | 74.6% |
| CWE-284, a Discouraged Pillar | 4,532 | 5.0% |
| CWE-20, a Discouraged Class | 2,034 | 2.3% |
| CWE-284 or CWE-20 | 6,552 | 7.3% |
| CWE-506 Embedded Malicious Code | 29 | 0.03% |

CWE-284, Improper Access Control, is the third most common CWE on 2026 records, behind CWE-79 and CWE-862. MITRE's own entry for CWE-284 says the ID "is not useful for trend analysis" and lists seven descendants to use instead. Coverage is high and precision is not. The [CNA Scorecard](https://socket.dev/blog/cna-scorecard) rated CWE completeness at 89.8% across more than 23,000 CVEs from February 7 to August 7, 2025, but it measures whether the field is filled, not whether the ID is right.

You can reproduce our count with a sparse clone and a short Python script:

```bash
git clone --depth 1 --filter=blob:none --sparse https://github.com/CVEProject/cvelistV5
cd cvelistV5 && git sparse-checkout set cves/2025 cves/2026
```

```python
import json, os, collections

def cwes(container):
    return {d["cweId"] for pt in container.get("problemTypes") or []
            for d in pt.get("descriptions") or [] if d.get("cweId")}

total, any_cwe, counts = 0, 0, collections.Counter()
for folder in ("cves/2025", "cves/2026"):
    for root, _, files in os.walk(folder):
        for f in files:
            if not f.endswith(".json"):
                continue
            rec = json.load(open(os.path.join(root, f)))
            meta = rec["cveMetadata"]
            if meta["state"] != "PUBLISHED" or not meta["datePublished"].startswith("2026"):
                continue
            total += 1
            found = cwes(rec["containers"]["cna"])
            for adp in rec["containers"].get("adp") or []:
                found |= cwes(adp)
            any_cwe += bool(found)
            counts.update(found)

print(total, any_cwe, counts.most_common(5))
```

## What the CWE Top 25 measures

The CWE Top 25 ranks weaknesses by how often they appear in recent CVE records and how severe those records score. The [2025 list](https://cwe.mitre.org/top25/archive/2025/2025_cwe_top25.html), published in December 2025, drew on 39,080 CVE records for vulnerabilities published between June 1, 2024 and June 1, 2025. Each weakness's score is its normalized frequency multiplied by its normalized average CVSS v3.x score, times 100.

| Rank | CWE | Weakness | Score | CVEs in KEV |
| --- | --- | --- | --- | --- |
| 1 | CWE-79 | Cross-site scripting | 60.38 | 7 |
| 2 | CWE-89 | SQL injection | 28.72 | 4 |
| 3 | CWE-352 | Cross-site request forgery | 13.64 | 0 |
| 4 | CWE-862 | Missing authorization | 13.28 | 0 |
| 5 | CWE-787 | Out-of-bounds write | 12.68 | 12 |
| 6 | CWE-22 | Path traversal | 8.99 | 10 |
| 7 | CWE-416 | Use after free | 8.47 | 14 |
| 8 | CWE-125 | Out-of-bounds read | 7.88 | 3 |
| 9 | CWE-78 | OS command injection | 7.85 | 20 |
| 10 | CWE-94 | Code injection | 7.57 | 7 |

The ranking measures reporting volume, not attacker preference. CWE-79 scores more than twice as high as anything else, and much of that volume comes from the [WordPress plugin ecosystem](https://socket.dev/blog/cve-volume-surges-past-48k-in-2025). In our count of CVE-2025 records published in 2025, Patchstack and Wordfence, two WordPress-focused CNAs, filed 3,615 of the 6,251 records whose CNA mapped CWE-79. CWE-78, OS command injection, ranks ninth but has 20 CVEs in KEV, the most of any entry on the list. MITRE tracks exploitation separately, in a "2025 CWE Top 10 KEV Weaknesses" list published January 29, 2026.

The list also inherits the data's mapping errors. CWE-20 ranks 18th and CWE-284 ranks 19th, though MITRE discourages mapping vulnerabilities to either. The 2024 edition had the same problem in a different form: MITRE attributed some ranking shifts in the [2024 CWE Top 25](https://socket.dev/blog/input-validation-vulnerabilities-dominate-mitre-s-2024-cwe-top-25-list) to CVE records that never received NVD mappings. The Top 25 is a good map of what developers keep shipping. It is a poor guide to what will hurt you this quarter.

## Which CWE covers malicious packages?

CWE-506, Embedded Malicious Code, is the CWE entry for malicious packages. The [CWE-506 entry](https://cwe.mitre.org/data/definitions/506.html) describes a product that "contains code that appears to be malicious in nature." It is a Class marked Allowed-with-Review, so MITRE expects mappers to check its four Base children first.

GitHub stamps CWE-506 on its malware advisories, and the OpenSSF [malicious-packages](https://github.com/ossf/malicious-packages) repository imports them in OSV format. A typical record, for a malicious npm package named `wc`, carries the CWE and no CVE:

```json
{
  "id": "MAL-2025-6136",
  "aliases": ["GHSA-575w-mx7m-5697"],
  "summary": "Malicious code in wc (npm)",
  "affected": [{
    "package": { "ecosystem": "npm", "name": "wc" },
    "database_specific": {
      "cwes": [{ "cweId": "CWE-506", "name": "Embedded Malicious Code" }]
    }
  }]
}
```

We counted the whole dataset at commit `89eed16`, current on November 6, 2026. It holds 239,975 non-withdrawn reports of [malicious packages](https://socket.dev/glossary/malicious-package), 222,852 of them on npm. 33,126 reports carry a CWE, and every one of those includes CWE-506. Only 7 reports reference a CVE, and all 7 belong to the [Nx compromise](https://socket.dev/blog/nx-packages-compromised) of August 2025, tracked as CVE-2025-10894. On the CVE side, only 29 of the 89,756 CVE records published in 2026 carry CWE-506.

> Two pipelines. Vulnerability path: a CNA publishes a CVE record with a CWE in problemTypes, CISA Vulnrichment and NVD may add data, GitHub Advisory Database and OSV copy it to cwe\_ids, scanners match package versions; 29 of 89,756 CVE records published in 2026 carry CWE-506. Malware path: researchers and registries report a package, GitHub malware advisories and OpenSSF MAL records label it CWE-506, no CVE is assigned; 7 of 239,975 malware reports reference a CVE.

Figure 2 shows why CWE-506 rarely reaches a vulnerability scanner. On the vulnerability path, a CNA publishes a CVE record with a CWE in `problemTypes`, CISA's Vulnrichment and the NVD may add data, the GitHub Advisory Database and OSV copy the CWE into `cwe_ids`, and scanners match package versions against those advisories. On the malware path, researchers and registries report a package, GitHub publishes a malware advisory or OpenSSF publishes a `MAL-` record with CWE-506, and no CVE is assigned. The counts above sit under each path: 29 of the 89,756 CVE records published in 2026 carry CWE-506, while 7 of 239,975 malware reports carry a CVE.

When a malicious release does get a CVE, the labels vary with whoever filed it. The table compares five records for the same kind of event: the [ua-parser-js hijack](https://socket.dev/blog/limitations-of-cve-based-security-scanners) of October 2021, the keep backdoor on PyPI, the malicious debug release from the Qix compromise, the [axios hijack](https://socket.dev/blog/axios-npm-package-compromised) of March 31, 2026, and a downstream CLI that pulled the bad axios release:

| Incident | Record | CWE | CVE | Severity |
| --- | --- | --- | --- | --- |
| ua-parser-js hijack, October 2021 | CVE-2021-4229, filed by VulDB on May 24, 2022 | CWE-912, labeled "Backdoor" | Yes, seven months later | CVSS 3.1 5.0, Medium |
| keep backdoor on PyPI, disclosed 2022 | CVE-2022-30877, filed by MITRE | None ("n/a") | Yes | None |
| debug hijack, September 8, 2025 | CVE-2025-59144, filed by GitHub | CWE-506 | Yes, seven days later | CVSS 4.0 8.8, High |
| axios hijack, March 31, 2026 | MAL-2026-2307, alias GHSA-fw8c-xr5c-95f9 | CWE-506 | No | No CVE record to score |
| @usebruno/cli, which pulled the axios release | CVE-2026-34841, filed by GitHub | CWE-494 and CWE-506, plus CWE-1395 in GHSA | Yes | CVSS 3.1 9.8, Critical |

The keep record is the oddest. MITRE cites CVE-2022-30877 as the observed example on its own CWE-506 page, yet the CVE record itself has no CWE. The axios rows are the most consequential. The axios releases that pulled in a remote access trojan dropper have no CVE, while a downstream CLI that depended on them does. A scanner keyed only on CVEs flags the CLI and misses the compromised axios versions themselves.

That is why we do not wait for an identifier. Socket's [Known malware](https://socket.dev/alerts/malware) alert fires on package versions that our AI scanner flags and our threat research team confirms as malware, whether or not a CVE exists.

## What CWE cannot describe

CWE describes defects in a product's own code, and that framing breaks down for supply chain attacks. From the consumer's side, installing a hijacked release is not a coding mistake. The weakness is a trust decision: which publisher, which version, and when the code was allowed to run. CWE's closest entries are CWE-1357, Reliance on Insufficiently Trustworthy Component, a Class, and its child CWE-1395, Dependency on Vulnerable Third-Party Component. The @usebruno/cli advisory stacked three IDs, and none of them names the actual failure: trusting a release published from a hijacked maintainer account.

The CWE program can move when someone does the work. In 2026 it added a view for AI and machine learning weaknesses, and CWE 5.0 added views mapped to the OpenSSF Secure Coding Guide for Python and the OWASP Go secure coding practices. A supply chain view, with entries that describe consumer-side trust failures rather than producer-side bugs, would let advisories label these incidents consistently. Until then, CWE-506 will remain a label applied after the fact, to a few dozen CVEs a year, for an attack class that already fills 239,975 reports in one open dataset. Catching those packages means reading the code before it runs.
