User guide¶
Every mode of cwex in detail. By default all of them work on MITRE's View 1000,
Complete Weakness Hierarchy (formerly Research Concepts); --view chooses another
(see Other views). For an overview, see the
overview; for what the results can and cannot tell you, see
Limitations.
Commands at a glance¶
cwex 79 # tree in the terminal (lineage + 2 levels of descendants)
cwex CWE-79 --tui # interactive explorer in the terminal
cwex 79 --web # interactive graph in the browser
cwex 664 --depth all # every descendant (also --depth 0, 1, 2...)
cwex --search "race" # search weaknesses by name (see Search by name)
cwex 79 --ancestors # mode 1: direct ancestors (parents)
cwex 79 --descendants # mode 2: direct descendants (children)
cwex 79 --tui --detailed # every section of each CWE (also with the tree and --web)
cwex CVE-2021-44228 --web # a CVE linked to its CWEs (every mode accepts a CVE)
cwex --check 20 79 CVE-2021-44228 # should these CWEs be used to map vulnerabilities?
cwex 79 --cves # how many CVEs in the NVD have CWE-79, and the most recent
cwex --views # the views of the catalog: Top 25, OWASP Top Ten, the NVD's...
cwex --view 1003 # another view instead of View 1000 (here, the one the NVD uses)
cwex 79 --view 699 --web # CWE-79 in the Software Development view, in the browser (see Views)
cwex 79 --json # everything about CWE-79 as JSON (also for a CVE)
cwex --docs # this documentation, as a website served on your computer
cwex --install-skill # teach Claude Code (or another agent) to use cwex (see AI agents)
cwex 79 --web -o xss.html --no-open # save the HTML without opening it
cwex --update # download the latest catalog again
A CWE is accepted as 79, CWE-79 or cwe79, and a CVE as CVE-2021-44228 or
cve-2021-44228; every mode works with both. If a CWE ID belongs to a
grouping (formerly Categories), a view or a deprecated entry, the tool explains
why it is not part of View 1000.
Search by name¶
--search lists the weaknesses whose name contains the text, ignoring case. Names
where it is a whole word come first, so --search AI starts with Generative AI
rather than with Certain or Chain; within each group, names that start with the
text go first, then by CWE number.
cwex --search "race" # the first 25 results
cwex --search AI --limit 100 # up to 100 (and up to 2,000)
cwex --search AI --limit 0 # only how many there are
cwex --search sql --json # as JSON, with the total
When there are more results than --limit (25 by default), the last line says how
many were left out.
The terminal tree¶
Ba CWE-79 Improper Neutralization of Input During Web Page Generation
Type Base: still mostly abstract, but with enough detail to infer specific
methods for detection and prevention.
Structure Simple
Status Stable: all important elements have been verified, and the entry is
unlikely to change significantly.
Published 2006-07-19 (CWE Draft 3)
Mapping Allowed: can be used to map real-world vulnerabilities.
Member of #1 in the 2025 CWE Top 25
OWASP Top Ten 2025: A05:2025 - Injection
View 1003, used by the NVD to map vulnerabilities
Description The product does not neutralize or incorrectly neutralizes user-
controllable input before it is placed in output that is used as a web page
that is served to other users.
Lineage CWE-707 › CWE-74 › CWE-79
...
Hierarchy in View 1000 (CWE 5.0, depth 2)
Pi CWE-707 Improper Neutralization ! Incomplete 2008
└─ Cl CWE-74 Improper Neutralization of Special Elements in Output Used b… ! Incomplete 2006
└─ Ba CWE-79 Improper Neutralization of Input During Web Page Gener… ◀ Stable 2006
├─ Va CWE-80 Improper Neutralization of Script-Related HTML Tags in… Incomplete 2006
├─ Va CWE-81 Improper Neutralization of Script in an Error Message … Incomplete 2006
├─ Va CWE-83 Improper Neutralization of Script in Attributes in a W… Draft 2006
│ └─ Va CWE-82 Improper Neutralization of Script in Attributes of … Incomplete 2006
...
When a weakness has several lineages, all of them are drawn in the tree and the subtree of descendants is shown only once.
Member of lists the featured views that contain the weakness: its rank in the latest CWE Top 25, its category in the latest OWASP Top Ten, and whether it is in View 1003, the one the NVD maps vulnerabilities to (see Other views).
The columns on the right are a mapping mark, each entry's status (MITRE's
measure of how mature it is) and the year it was published. The mark says whether
MITRE recommends using the entry to map vulnerabilities: ! Discouraged, ✗
Prohibited, ? Allowed-with-Review, and nothing when it is Allowed (see
Mapping guidance). Status is styled by maturity:
Stable in bold, Usable and Draft in normal text, Incomplete dimmed, and
Deprecated or Obsolete as a warning. The interactive explorer shows the same
columns. When the tree is narrower than 60 characters, the columns are left out, and
deprecated entries are marked with (deprecated) instead.
The interactive explorer¶
--tui opens the hierarchy in an interactive explorer inside the terminal.

cwex 693 --tui. The hierarchy on the left, the card of the
selected entry (CWE-347) on the right, and the keys at the bottom.| Action | Mouse | Keyboard |
|---|---|---|
| Show a node's details | click | ↑ ↓ / j k |
| Re-center the hierarchy on that node | double click | Enter / → |
| Go back to the previous node | ⌫ / b / ← |
|
| More or fewer levels of descendants | + / - |
|
| Go to another CWE or CVE, or search by name | / |
|
| Scroll the details | wheel over the details | J / K |
| Open the details on cwe.mitre.org | o |
|
| Open the node in the web graph | w |
|
| Quit | q |
With a CVE, the first row is the CVE itself and its details pane shows the CVE card.
/ also accepts CVE identifiers and looks them up, and b goes back to the
previously loaded CVE.
The browser¶
--web writes the hierarchy as a single HTML page with an interactive graph and opens
it in the browser.

cwex 79 --web. The graph of CWE-79 with CWE-83 selected:
its details in the side panel and its lineage highlighted in the graph.- Each node shows its status and the year it was published. The status tag
is more solid the more mature the entry is:
Stablefilled,UsableandDraftoutlined,Incompletedashed, andDeprecatedorObsoleteas a warning. The side panel explains what each status means. - Click a node: shows its details in the side panel and highlights its lineage up to the pillar (thick line: primary lineage).
- Double click, or the Center the hierarchy on CWE-… button: rebuilds the graph around that node.
+N/−on a node: expands or collapses its children. On ancestors it reveals sibling weaknesses.- Search by ID or name, a selector for levels of descendants, wheel zoom and drag to pan.
- Full screen (button or
Fkey): the graph fills the whole screen and the details open as a floating panel when you click a node (from the bottom on phones). Close it with×orEsc;Escalso leaves full screen. - Solid edges for the primary parent and dashed edges for secondary parents.
- Filter: dims or hides the weaknesses that do not match a type, status, mapping usage or publication year (see Filters).
- CVEs in the NVD, in the side panel of each CWE: counts the CVEs linked to it and lists the most recent (see CVEs of a CWE).
- The page embeds all of View 1000, so you can navigate to any other CWE without
generating it again. The link
#cwe-89opens that weakness directly. It follows the system dark mode and adapts to phones.
By default the HTML is saved in ~/.cache/cwe-explorer/html/. Use -o to choose
another path.
Filters¶
Large graphs are hard to read: CWE-664 with every descendant has 381 nodes. The Filter button, next to Fit, keeps only the weaknesses that matter for the task at hand:
| Filter | Values |
|---|---|
| Type | Pillar, Class, Base, Variant, Compound |
| Status | The statuses present in the catalog: Stable, Draft, Incomplete and Deprecated in CWE 5.0 |
| Mapping | Allowed, Allowed-with-Review, Discouraged, Prohibited (see Mapping guidance) |
| Member of | The latest CWE Top 25, the latest OWASP Top Ten and the NVD's View 1003. Unlike the others, these start unchecked: checking some keeps only the weaknesses in any of them |
| Published | A range of years, from 2006 |
A weakness is shown when it matches every filter. What happens to the rest:
- Dim them (default): they fade, and the graph keeps its shape, so lineages stay readable. Hovering over or selecting a faded node brings it back.
- Hide them: they disappear. Their children that match move up in their place, joined to their nearest visible ancestor by a dotted edge (through hidden weaknesses in the legend). The centered node is never hidden, nor is a CVE or the CWEs linked to it.
The button shows how many filters are active, and the legend how many of the
weaknesses shown match (149 of 381 match the filters). Search still finds every
weakness and marks the ones the filters leave out (filtered out).
The filters travel in the address, after the weakness:
#cwe-664?type=Base,Variant&status=Stable,Draft&mode=hide. Copy it to share a
filtered view. The browser also remembers the last filters and applies them the next
time a page opens without filters of its own; Reset clears them.
Full details¶
By default each node shows its type, structure, status, description, lineage and
relationships. With --detailed it also shows every section of the CWE catalog
entry, in the same order as cwe.mitre.org: alternate terms, background details,
common consequences, potential mitigations, modes of introduction, applicable
platforms, likelihood of exploit, demonstrative examples (with their code), observed
examples (CVEs), weakness ordinalities, detection methods, functional areas, affected
resources, dimensions, vulnerability mapping notes, notes, taxonomy mappings, related
CAPEC attack patterns, references and content history.
cwex 79 --detailed # tree, with the full entry of CWE-79
cwex 79 --tui --detailed # the details pane of every node (scroll with J/K or the wheel)
cwex 79 --web --detailed # collapsible sections in the side panel
Common Consequences (3)
• Access Control, Confidentiality
Impact: Bypass Protection Mechanism; Read Application Data
The most common attack performed with cross-site scripting involves the disclosure
of private information stored in user cookies, such as session information.
...
Demonstrative Examples (6)
• Example 1
The following code displays a welcome message on a web page based on the HTTP GET
username parameter (covers a Reflected XSS (Type 1) scenario).
Bad · PHP
│ $username = $_GET['username'];
│ echo '<div class="header"> Welcome, ' . $username . '</div>';
Code examples keep their line breaks and indentation. In the browser, vulnerable
(Bad), fixed (Good) and attack snippets are marked with different colors, and the
side panel is wider.
The full entries are extracted once from the same catalog and cached separately
(details.json, about 9 MB), so the default mode stays light. For the same reason a
--web --detailed page weighs about 10 MB instead of 0.5 MB: it embeds every
weakness's entry so you can navigate to any CWE.
CVEs¶
Every mode also accepts a CVE identifier (CVE-2021-44228, cve-2021-44228...).
The tool finds the CWEs linked to the vulnerability and shows them in View 1000 just
as it does with a CWE:
cwex CVE-2021-44228 # the CVE, its CWEs and the hierarchy that joins them
cwex CVE-2021-44228 --web # the CVE as a node linked to its CWEs in the graph
cwex CVE-2021-44228 --tui # interactive explorer; `/` also looks up other CVEs
cwex CVE-2021-44228 --ancestors # ancestors of each linked CWE (also --descendants, --json)
cwex CVE-2014-0160 --detailed # plus the full catalog entry of each CWE
How the CVE and CWE data are crossed, where each piece comes from and how they relate is explained, with diagrams, in How CWE Explorer links CVEs to CWEs. In short, each link between the CVE and a CWE says where it comes from:
| Source | Who assigns it |
|---|---|
<name> (CNA) |
The organization that published the CVE, in its CVE.org record (for example apache (CNA)) |
ADP, such as CISA-ADP |
Authorized data publishers that enrich the CVE.org record |
NVD |
NIST's National Vulnerability Database analysts |
CWE catalog (observed example) |
The CWE entry cites the CVE as an observed example |
Who these organizations are and how they relate (CNA, ADP, NVD and the CWE catalog) is explained in The CVE ecosystem.
CVE CVE-2021-44228 Apache Log4j2 JNDI features do not protect against attacker controlled LDAP and
other JNDI related endpoints
State Published on 2021-12-10
CNA apache
...
CVSS 10.0 Critical · CVSS 3.1 · CISA-ADP
10.0 Critical · CVSS 3.1 · NVD
9.3 High · CVSS 2.0 · NVD
KEV Yes: in CISA's Known Exploited Vulnerabilities catalog since 2021-12-10, action due
2021-12-24.
SSVC Exploitation active · Automatable yes · Technical Impact total (CISA-ADP, 2025-02-04)
EPSS 99.999% chance of exploitation in the next 30 days · percentile 100 (FIRST, 2026-11-03)
Weaknesses CWE-502 Deserialization of Untrusted Data (Base) · from apache (CNA)
CWE-400 Uncontrolled Resource Consumption (Class) · from apache (CNA)
! Discouraged for mapping (Frequent Misuse, Abstraction). MITRE suggests CWE-770,
CWE-771, CWE-772, CWE-410, CWE-834, CWE-405.
CWE-20 Improper Input Validation (Class) · from apache (CNA)
! Discouraged for mapping (Frequent Misuse, Frequent Misinterpretation,
Abstraction). MITRE suggests CWE-1173, CWE-116, CWE-790, CWE-1284, CWE-1285,
CWE-1286 and 3 more.
CWE-917 Improper Neutralization of Special Elements used in an Expression Language
Statement (Base) · from NVD, CWE catalog (observed example)
CWE-74 Improper Neutralization of Special Elements in Output Used by a Downstream
Component (Class) · from CWE catalog (observed example)
! Discouraged for mapping (Frequent Misuse, Abstraction). More specific: CWE-75,
CWE-77, CWE-79, CWE-91, CWE-93, CWE-94 and 3 more.
Warning The sources disagree: apache (CNA) (CWE-502, CWE-400, CWE-20) and NVD (CWE-917)
point to different branches: none of these CWEs is an ancestor or descendant of the
other source's.
...
CWEs linked to CVE-2021-44228 in View 1000 (CWE 5.0, depth 0)
Pi CWE-664 Improper Control of a Resource Through its Lifetime ! Draft 2008
├─ Cl CWE-913 Improper Control of Dynamically-Managed Code Resources ? Incomplete 2013
│ └─ Ba CWE-502 Deserialization of Untrusted Data ◀ Draft 2006
└─ Cl CWE-400 Uncontrolled Resource Consumption (+7 children) ◀ ! Draft 2006
Pi CWE-707 Improper Neutralization ! Incomplete 2008
├─ Cl CWE-20 Improper Input Validation (+9 children) ◀ ! Stable 2006
└─ Cl CWE-74 Improper Neutralization of Special Elements in Output Use… ◀ ! Incomplete 2006
└─ Cl CWE-77 Improper Neutralization of Special Elements used in a Com… ? Draft 2006
└─ Ba CWE-917 Improper Neutralization of Special Elements used in… ◀ Incomplete 2013
By default a CVE shows only the lineages of its CWEs (--depth 0), so the whole
picture fits; --depth N, or the +N buttons in the browser, reveal the more
specific children of each CWE.

cwex CVE-2021-44228 --web. Log4Shell linked to its five
CWEs, with the CVE's panel open: its CVSS scores and the exploitation signals (KEV,
SSVC and EPSS).In the browser the CVE is a dark node joined to its CWEs by dotted lines, and its
panel lists the CVSS scores, the exploitation signals and every link with its source.
A KEV tag next to the score marks a CVE that is known to be exploited. The search
box and the address (#CVE-2014-0160) look up any other CVE straight from the page,
against CVE.org, the NVD and FIRST.
Exploitation signals: KEV, SSVC and EPSS¶
CVSS measures how severe a vulnerability is, not how likely it is to be exploited. To help prioritize, the CVE card adds three signals:
| Line | What it says | Source |
|---|---|---|
KEV |
Whether the CVE is in CISA's Known Exploited Vulnerabilities catalog, since when and the deadline CISA set for US federal agencies to fix it (action due) | The CISA-ADP container of the CVE.org record and, as a fallback, the NVD (cisaExploitAdd, cisaActionDue) |
SSVC |
CISA's Stakeholder-Specific Vulnerability Categorization decision points: whether it is being exploited (none, poc, active), whether an attack can be automated, and the technical impact (partial, total), with the date of the assessment |
The CISA-ADP container |
EPSS |
FIRST's Exploit Prediction Scoring System: the probability that the CVE is exploited in the next 30 days, and its percentile among all scored CVEs, with the date of the score | The FIRST API (https://api.first.org/data/v1/epss) |
Keep in mind:
- KEV is CISA's view. It lists vulnerabilities with reliable evidence of exploitation in the wild, not every exploited one. No means "not in the KEV catalog", not "not exploited".
- Not every CVE has an SSVC assessment. CISA adds one to many records, but when the record has none, the line is left out.
- EPSS is a model that FIRST recalculates every day: always read it with its date. New CVEs may not have a score yet, and then the line is left out.
- SSVC options are shown as CISA publishes them, so their names may change between versions of the decision tree.
EPSS scores are cached for one day (epss/ in the cache folder), apart from the CVE
record. --check does not ask for EPSS, since it does not use it.
cwex CVE-… --json returns the whole record, with the exploitation signals, the
mapping check and every linked CWE; --ancestors and --descendants with --json
return the record and the listing of each linked CWE. Both are described in the
JSON reference.
Lookups are cached for 7 days in ~/.cache/cwe-explorer/cve/; --update refreshes
them. Without a connection the tool uses the cached copy or, failing that, the
2,202 CVEs cited by the CWE catalog.
NVD API key¶
Without a key, the NVD allows 5 requests every 30 seconds; with one, 50. A key is
free: request it at https://nvd.nist.gov/developers/request-an-api-key. cwex
reads it from the NVD_API_KEY environment variable and sends it only to the NVD
(the apiKey header of each request). It is never written to the cache or to the
web pages, and lookups made from a web page do not use it.
On macOS and Linux, add it to your shell's startup file (~/.zshrc for zsh, the
default on macOS; ~/.bashrc for bash) with an editor, so it does not end up in
the shell history:
export NVD_API_KEY="your-key"
Or, on macOS, keep it in the Keychain instead of a plain-text file. This command prompts for the key:
security add-generic-password -U -a "$USER" -s nvd-api-key -w
and this line in ~/.zshrc reads it when the shell starts:
export NVD_API_KEY="$(security find-generic-password -a "$USER" -s nvd-api-key -w 2>/dev/null)"
On Windows (PowerShell), setx NVD_API_KEY "your-key" saves it for new terminals.
Open a new terminal and check that the NVD accepts the key. 200 means it does;
404 means it rejected it:
curl -s -o /dev/null -w "%{http_code}\n" -H "apiKey: $NVD_API_KEY" \
"https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2021-44228"
If the NVD rejects the key, it answers Invalid apiKey. The CVE card then shows the note "The NVD could not be consulted (HTTP 404: it rejected the API key in NVD_API_KEY)", the NVD's links are missing, and nothing is cached, so the next lookup tries again.
What these links can and cannot tell you is listed in Limitations.
CVEs of a CWE¶
The links above go from a CVE to its CWEs. --cves goes the other way: it asks the
NVD how many CVEs have a CWE among their weaknesses, and which are the most recent.
cwex 79 --cves # the count and the 20 most recent CVEs with CWE-79
cwex 79 --cves --limit 100 # the 100 most recent (up to 2,000; --limit 0 only counts)
cwex 89 --cves --since 2025-01-01 # only CVEs published since that date
cwex 119 --cves --include-descendants # also the count of every weakness below CWE-119
cwex 502 --cves --json # as JSON
Ba CWE-79 Improper Neutralization of Input During Web Page Generation
CVEs in the NVD linked to CWE-79: 25,193
Counted on 2026-11-04 12:41 UTC, from the weaknesses that the NVD lists for each CVE.
Most recent 8
CVE-2026-97397 2026-11-04 7.2 High The Remove Google Fonts – Disable, Block, or Replace with …
CVE-2026-93900 2026-11-04 6.4 Medium The Simple CAPTCHA with Cloudflare Turnstile plugin for Wo…
CVE-2026-115498 2026-11-04 7.2 High The Slim Jetpack plugin for WordPress is vulnerable to Sto…
...
A KEV tag before the description marks CVEs that are in CISA's Known Exploited
Vulnerabilities catalog. The CVSS score is the newest version available, the NVD's
own when there is one.
With --include-descendants, a table gives the count of the CWE and of each of its
descendants, largest first. A CVE linked to several of them is counted once for each,
so the sum is an upper bound, not the number of different CVEs. The list of recent
CVEs is still that of the CWE itself.
Cl CWE-119 Improper Restriction of Operations within the Bounds of a Memory Buffer
CVEs in the NVD linked to CWE-119: 11,345
Counted on 2026-11-04 12:51 UTC, from the weaknesses that the NVD lists for each CVE.
By CWE: CWE-119 and its 21 descendants
Cl CWE-119 11,345 Improper Restriction of Operations within the Bounds of a Memory Buffer
Ba CWE-787 13,272 Out-of-bounds Write
Ba CWE-125 6,981 Out-of-bounds Read
Va CWE-416 5,914 Use After Free
Ba CWE-120 2,277 Buffer Copy without Checking Size of Input
Va CWE-415 738 Double Free
...
Va CWE-122 33 Heap-based Buffer Overflow
...
Sum: 40,762. A CVE linked to several of these CWEs is counted once for each.
How it works. The NVD API filters CVEs by weakness (cweId=CWE-79) and returns
them from the oldest to the newest. cwex asks for the total first and then for the
last page, which holds the most recent ones. The NVD accepts date ranges of up to 120
days, so --since splits the period into ranges and adds up their counts. Each count
or page is one request, and the NVD allows 5 every 30 seconds without an
API key (50 with one): cwex waits when it has to and says so.
--include-descendants makes one request per descendant (CWE-119 has 21), so it is
much faster with a key.
Results are cached for one day in cve-by-cwe/, because the NVD adds CVEs every day;
--update asks again. Without a connection, an older cached count is shown with a
note.
In the browser, the side panel of each CWE has a CVEs in the NVD section. Its button asks the NVD, from the page itself, for the count and the 10 most recent CVEs; click one to open it in the graph.
The count says how CVEs are mapped, not how dangerous a weakness is: generic CWEs such as CWE-20 collect many mappings that a careful analyst would make more specific. The other limits are listed in Limitations.
Mapping guidance¶
Every CWE entry says whether it should be used to map (classify) real-world vulnerabilities. These Vulnerability Mapping Notes give a usage level, the reasons for it, a rationale and, for some entries, suggestions of CWEs to use instead. In View 1000 (957 weaknesses):
| Usage | Weaknesses | Meaning |
|---|---|---|
| Allowed | 755 | Can be used to map real-world vulnerabilities. Almost every Variant and most Bases |
| Allowed-with-Review | 100 | Only in limited situations, after careful review. Mostly Classes (86), which may have a more specific child |
| Discouraged | 44 | Should not be used. All 10 Pillars and 25 Classes, among others |
| Prohibited | 58 | Must not be used. Mostly Bases (51), often quality issues with no direct security impact |
Only 17 entries suggest alternatives, among them CWE-20, CWE-119 and CWE-400. For the rest, the tool proposes the entry's children, which are its more specific forms.
Where it shows. The guidance is always visible, without --detailed:
- Details of a CWE (tree, explorer and browser): a Mapping field with the level, the reasons and MITRE's rationale, followed by MITRE's suggestions or the more specific children.
- Tree and interactive explorer: a mark before the status,
!Discouraged,✗Prohibited or?Allowed-with-Review. - Browser: the same mark in the corner of each node, and a Mapping guidance section in the side panel.
- CVEs: each linked CWE that MITRE discourages, prohibits or asks to review gets a line under it with the reasons and the alternatives. When two sources point to different branches (no CWE of one is an ancestor or descendant of a CWE of the other), the card warns that the sources disagree. For Log4Shell, two of the three CWEs Apache assigned (CWE-400 and CWE-20) are Discouraged, and Apache and the NVD disagree. Observed examples from the catalog are left out of this comparison, because they are citations, not assignments.
Checking IDs from scripts. --check takes one or more CWEs or CVEs, mixed:
cwex --check 943 79 1041
cwex --check CVE-2021-44228
cwex --check CWE-20 CWE-79 --strict # Discouraged entries fail too
cwex --check 79 CVE-2014-0160 --json
? CWE-943 Improper Neutralization of Special Elements in Data Query … Allowed-with-Review
Allowed-with-Review: can be used to map real-world vulnerabilities only in
limited situations, after careful review. Reasons: Abstraction.
This CWE entry is a Class and might have Base-level children that would be more
appropriate
Not in View 1003, the set of weaknesses the NVD maps vulnerabilities to.
More specific:
CWE-89 Improper Neutralization of Special Elements used in an SQL Command
CWE-90 Improper Neutralization of Special Elements used in an LDAP Query
CWE-643 Improper Neutralization of Data within XPath Expressions
CWE-652 Improper Neutralization of Data within XQuery Expressions
CWE-79 Improper Neutralization of Input During Web Page Generation Allowed
✗ CWE-1041 Use of Redundant Code Prohibited
Prohibited: must not be used to map real-world vulnerabilities. Reasons: Other.
This entry is primarily a quality issue with no direct security implications.
Not in View 1003, the set of weaknesses the NVD maps vulnerabilities to.
Summary: 1 allowed, 1 allowed with review, 1 prohibited. Check failed.
The exit status is 1 when any ID is invalid (it does not exist, is a grouping or
a view, or is deprecated) or Prohibited, and 0 otherwise. Discouraged entries
only warn, unless --strict is given. For a CVE, CWEs that only come from the
catalog's observed examples never make the check fail. With --json, the output says whether the check passed and
gives every verdict with MITRE's reasons and alternatives: see
Mapping check in the JSON reference.
The guidance is MITRE's advice, not a rule. Allowed-with-Review means that a person should confirm the fit, not that the mapping is wrong.
The check also says when a weakness is not in View 1003, the reduced set the NVD uses to classify vulnerabilities (about 130 weaknesses). Mapping to it is still valid, but the NVD's analysis will probably use a more general CWE. The note never makes the check fail.
Ancestors and descendants (modes 1 and 2)¶
Given a CWE, lists its ancestors (mode 1) or its descendants (mode 2) in View 1000. By default only the direct ones, that is, its parents or its children:
cwex 79 --ancestors # parents of CWE-79
cwex 79 --descendants # children of CWE-79
cwex 425 --ancestors --depth all # every ancestor, up to the pillars
cwex 664 --descendants --depth 2 # children and grandchildren
cwex 664 --descendants -d all --json > cwe-664.json
--depth N walks N levels and --depth all walks all of them. With more than one
level, the result is grouped by distance:
Ba CWE-425 Direct Request
All ancestors in View 1000 (CWE 5.0): 11 (3 Pillar, 6 Class, 2 Base)
Level 1 (parents)
Cl CWE-862 Missing Authorization (primary parent)
Ba CWE-288 Authentication Bypass Using an Alternate Path or Channel (secondary parent)
Cl CWE-424 Improper Protection of Alternate Path (secondary parent)
Level 2
Cl CWE-285 Improper Authorization (via CWE-862 · primary lineage)
Ba CWE-306 Missing Authentication for Critical Functionality (via CWE-288)
Cl CWE-638 Not Using Complete Mediation (via CWE-424)
Pi CWE-693 Protection Mechanism Failure (via CWE-424)
...
The notes in parentheses explain the relationship:
- Parents:
primary parentorsecondary parent, according to the catalog'sOrdinal="Primary"attribute. - Children:
secondary linkwhen the queried CWE is not the child's primary parent, together with which one is. - Further levels:
via CWE-…, the nodes of the previous level through which the node is reached. Ancestors on the path of primary parents are markedprimary lineage, and descendants that only reach the queried CWE through some secondary parent are markedoutside its primary lineage.
With --json each node comes with its distance, the nodes it is reached through and
whether it is on the primary lineage; the fields are described in
Ancestors and descendants in the JSON reference.
From Python, the same data comes from
Hierarchy.relatives(cwe_id, "ancestors" | "descendants", depth=1); depth=None
walks every level:
from cwe_explorer.data import load_catalog
from cwe_explorer.hierarchy import Hierarchy
h = Hierarchy(load_catalog())
[r.id for r in h.relatives(79, "ancestors")] # [74]
[(r.id, r.distance) for r in h.relatives(83, "ancestors", depth=None)]
# [(79, 1), (74, 2), (707, 3)]
Other views¶
View 1000 holds every weakness, linked by ChildOf. MITRE publishes 61 other views
that select and organize entries for a purpose: the CWE Top 25 of each year, the
OWASP Top Ten, View 1003 (the reduced set the NVD maps vulnerabilities to),
Software Development (699) and Hardware Design (1194) by topic, coding
standards… How to list them and open them in the terminal and in the browser is
explained in Views. In short:
cwex --views # list them
cwex --view 1435 # the whole view in the terminal (also --tui and --web)
cwex 79 --view 1450 --web # CWE-79 in the OWASP Top Ten 2025, in the browser
Membership in the featured views¶
Three views are featured everywhere, without changing the view you browse: the latest CWE Top 25, the latest OWASP Top Ten and the NVD's View 1003. They are found by name, so a new edition replaces the old one by itself.
- The card of a weakness lists them under Member of:
#1 in the 2025 CWE Top 25,OWASP Top Ten 2025: A05:2025 - Injection,View 1003, used by the NVD to map vulnerabilities. - The browser shows the Top 25 rank as a tag on the node (
#1), the same list in the side panel, and a Member of filter that keeps, for example, only the Top 25 weaknesses below a pillar. --checknotes the weaknesses that are not in View 1003 (see Mapping guidance).- The JSON record of a CWE lists every view that contains it, with the rank and the OWASP category (see View membership).
The rank is the position of the weakness in the view's list of members. MITRE lists the Top 25 in rank order: for 2023, 2024 and 2025 the positions match the published rankings.
How another view is built¶
- The view is the root (
Vw), and the entries it lists at its top hang from it, in the order MITRE gives them. - Its own links. Some views have
ChildOflinks of their own, like 1003, 1305 and 1340. Others list their members through groupings (formerly categories,Gr), like 699, 1400 and the OWASP Top Ten, sometimes nested. Groupings are nodes with their own card; MITRE marks them Prohibited for mapping, because they are not weaknesses. - Lineages change meaning. In a view by topic, a weakness may sit in several
groupings, so its "lineages" are the groupings that contain it, not a chain of
ChildOf. - Not every view can be opened. 17 views are defined by a filter on the whole
catalog, and some deprecated views have no members.
cwex --viewsmarks them.
JSON output¶
--json turns any lookup into JSON for scripts. With an identifier and no other mode,
it returns everything the tool knows about the entry:
cwex 79 --json # a CWE: the full record
cwex 79 --json --depth 1 # the same, with only the direct descendants
cwex CVE-2021-44228 --json # a CVE: its record, the exploitation signals, the mapping check and every linked CWE
cwex 79 --json | jq '.mapping.level, .lineages'
cwex CVE-2021-44228 --json | jq '.cve.kev, .cve.epss'
The other modes have their own output: --ancestors and --descendants, --check,
--cves and --search. Every output carries schema (the version of the format)
and type (which output it is), and the JSON reference describes each one
field by field, with examples.
AI agents¶
cwex --install-skill installs a skill: a SKILL.md file that tells an AI agent
when and how to use cwex. With it, an agent such as Claude Code answers questions
about CWEs and CVEs ("which CWE fits this bug?", "is CWE-20 a good mapping?", "what
are the CWEs of CVE-2021-44228?") by running cwex … --json instead of relying on
memory.
cwex --install-skill # Claude Code, for every project: ~/.claude/skills/cwe-explorer
cwex --install-skill .claude/skills # only for the project in the current directory
cwex --install-skill ~/.agents/skills # any other agent that reads skills from that directory
- What it teaches. Which command answers each kind of question, to always ask for
--jsonand how to read it, the exit statuses, and that--tuiand--docsare not for agents. - Where. By default, the personal skills of Claude Code, under
CLAUDE_CONFIG_DIRwhen it is set.DIRis any directory of skills: the skill goes intoDIR/cwe-explorer. - When cwex is not on the agent's PATH, as with a virtual environment the agent does not activate, the skill also gives the full command with the Python that installed it.
- Updates. Running it again replaces the skill; do it after upgrading
cwex, so the skill describes the options of the new version. Agents load it in new sessions. - Removing it is deleting the
cwe-explorerdirectory.
Data and cache¶
- CVEs: the CVE.org API (
https://cveawg.mitre.org/api/cve/{id}) and the NVD API (https://services.nvd.nist.gov/rest/json/cves/2.0), cached for 7 days incve/inside the cache folder. - EPSS scores: the FIRST API (https://api.first.org/data/v1/epss), cached for one
day in
epss/. The CVEs of a CWE (--cves) are cached for one day incve-by-cwe/. - Source: https://cwe.mitre.org/data/xml/cwec_latest.xml.zip. Only
ChildOfrelationships withView_ID="1000"are used, and the parent markedOrdinal="Primary"defines the primary lineage. - Cache:
~/.cache/cwe-explorer/, or$XDG_CACHE_HOME/cwe-explorer, or the path inCWEX_CACHE. It holds the downloaded catalog, a compactcatalog.jsonfor the hierarchy and, once--detailedhas been used,details.jsonwith the full entries. Both JSON files are rebuilt when the catalog changes. - To work offline with a specific XML:
cwex 79 --xml cwec_v5.0.xml(the.zipis accepted too). - The publication date is the release date of the CWE version in which the entry
first appeared (
Submission_ReleaseDate), not the date it was submitted: for 120 weaknesses they fall in different years. - The parser does not depend on the schema namespace (
cwe-7,cwe-8...), so it works with old and new catalogs.
In CWE 5.0, CWE-378 and CWE-379 still hang from CWE-377, which is marked as deprecated. The tool keeps that link as MITRE publishes it, marks the node as deprecated and warns that the lineage does not reach a pillar.