> ## Documentation Index
> Fetch the complete documentation index at: https://docs.endorlabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.endorlabs.com/feedback

```json
{
  "path": "/discover/vulnerability-db/index",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Endor Labs Vulnerability Database

> Understand how to search, analyze, and navigate vulnerabilities.

export const YamlTable = ({children, data: propData, content}) => {
  const KV_RE = /^([A-Za-z][A-Za-z0-9_()/#\s-]+?):\s*(.+)$/;
  const INLINE_MD_RE = /(\[([^\]]+)\]\(([^)]+)\))|(`([^`]+)`)|(\*\*([^*]+)\*\*)|(\*([^*]+)\*)/g;
  const YES_RE = /^-yes-$/i;
  const NO_RE = /^-no-$/i;
  const LIMITED_RE = /^-(limited|partial)-$/i;
  const SIMPLE_TAG_RE = /(<br\s*\/?>)|(<p\s*\/?>)|(-note-)|(-warning-)/gi;
  const tryParseKV = trimmed => {
    const m = KV_RE.exec(trimmed);
    return m ? {
      key: m[1],
      value: m[2].trim()
    } : null;
  };
  const registerKey = (key, seenKeys, orderedKeys) => {
    if (!seenKeys.has(key)) {
      orderedKeys.push(key);
      seenKeys.add(key);
    }
  };
  const flushEntry = (currentEntry, entries) => {
    if (Object.keys(currentEntry).length > 0) entries.push(currentEntry);
  };
  const parseDashPrefixed = (lines, entries, orderedKeys, seenKeys) => {
    let currentEntry = {};
    let inEntry = false;
    for (const line of lines) {
      const trimmed = line.trim();
      if (trimmed.startsWith('- ')) {
        if (inEntry) entries.push(currentEntry);
        currentEntry = {};
        inEntry = true;
        const kv = tryParseKV(trimmed.substring(2).trim());
        if (kv) {
          registerKey(kv.key, seenKeys, orderedKeys);
          currentEntry[kv.key] = kv.value;
        }
      } else if (inEntry && trimmed !== '') {
        const kv = tryParseKV(trimmed);
        if (kv) {
          registerKey(kv.key, seenKeys, orderedKeys);
          currentEntry[kv.key] = kv.value;
        }
      }
    }
    flushEntry(currentEntry, entries);
  };
  const parseBlankSeparated = (lines, entries, orderedKeys, seenKeys) => {
    let currentEntry = {};
    let inEntry = false;
    for (const line of lines) {
      const trimmed = line.trim();
      if (trimmed === '') {
        if (inEntry) {
          flushEntry(currentEntry, entries);
          currentEntry = {};
          inEntry = false;
        }
        continue;
      }
      const kv = tryParseKV(trimmed);
      if (!kv) continue;
      const isNewEntry = !line.startsWith(' ') && !line.startsWith('\t');
      if (isNewEntry && inEntry && Object.keys(currentEntry).length > 0) {
        entries.push(currentEntry);
        currentEntry = {};
      }
      registerKey(kv.key, seenKeys, orderedKeys);
      currentEntry[kv.key] = kv.value;
      inEntry = true;
    }
    flushEntry(currentEntry, entries);
  };
  const normalizeEntries = (entries, orderedKeys) => entries.map(entry => {
    const filled = {};
    for (const key of orderedKeys) filled[key] = entry[key] || '';
    return filled;
  });
  const parseYamlTableContent = contentStr => {
    if (!contentStr) return [];
    const entries = [];
    const orderedKeys = [];
    const seenKeys = new Set();
    const lines = contentStr.split('\n');
    if (lines.some(line => line.trim().startsWith('- '))) {
      parseDashPrefixed(lines, entries, orderedKeys, seenKeys);
    } else {
      parseBlankSeparated(lines, entries, orderedKeys, seenKeys);
    }
    return normalizeEntries(entries, orderedKeys);
  };
  const processText = text => {
    if (!text) return text;
    const parts = [];
    let keyIndex = 0;
    let lastIndex = 0;
    let match;
    while ((match = INLINE_MD_RE.exec(text)) !== null) {
      if (match.index > lastIndex) parts.push(text.slice(lastIndex, match.index));
      if (match[1]) {
        parts.push(<a key={keyIndex++} href={match[3]}>{match[2]}</a>);
      } else if (match[4]) {
        parts.push(<code key={keyIndex++}>{match[5]}</code>);
      } else if (match[6]) {
        parts.push(<strong key={keyIndex++}>{match[7]}</strong>);
      } else if (match[8]) {
        parts.push(<em key={keyIndex++}>{match[9]}</em>);
      }
      lastIndex = match.index + match[0].length;
    }
    if (lastIndex < text.length) parts.push(text.slice(lastIndex));
    if (parts.length === 0) return text;
    const keyRef = {
      current: keyIndex
    };
    return expandHtmlTags(parts, keyRef);
  };
  const processBadges = text => {
    if (!text || typeof text !== 'string') return text;
    if (YES_RE.test(text)) return <span className="yt-badge-yes" role="img" aria-label="Supported" title="Supported">✓</span>;
    if (NO_RE.test(text)) return <span className="yt-badge-no" role="img" aria-label="Not supported" title="Not supported">✗</span>;
    if (LIMITED_RE.test(text)) return <span className="yt-badge-limited" role="img" aria-label="Partially supported" title="Partially supported">◐</span>;
    return processText(text);
  };
  const expandSimpleTags = (str, keyRef) => {
    const result = [];
    let last = 0;
    SIMPLE_TAG_RE.lastIndex = 0;
    let m;
    while ((m = SIMPLE_TAG_RE.exec(str)) !== null) {
      if (m.index > last) result.push(str.slice(last, m.index));
      if (m[1]) {
        result.push(<br key={keyRef.current++} />);
      } else if (m[2]) {
        result.push(<br key={keyRef.current++} />, <br key={keyRef.current++} />);
      } else if (m[3]) {
        result.push(<span key={keyRef.current++} className="yt-badge-note" style={{
          fontWeight: 600
        }}>Note: </span>);
      } else if (m[4]) {
        result.push(<span key={keyRef.current++} className="yt-badge-warning" style={{
          fontWeight: 600
        }}>Warning: </span>);
      }
      last = m.index + m[0].length;
    }
    if (last < str.length) result.push(str.slice(last));
    return result;
  };
  const expandHtmlTags = (chunks, keyRef) => {
    const out = [];
    for (const chunk of chunks) {
      if (typeof chunk === 'string') {
        out.push(...expandSimpleTags(chunk, keyRef));
      } else {
        out.push(chunk);
      }
    }
    return out;
  };
  const extractText = node => {
    if (node === null || node === undefined) return '';
    if (typeof node === 'string') return node;
    if (typeof node === 'number') return String(node);
    if (typeof node === 'boolean') return '';
    if (Array.isArray(node)) return node.map(extractText).join('');
    if (node && typeof node === 'object' && node.type) {
      const props = node.props || ({});
      if (typeof props.children === 'string') return props.children;
      if (props.children) return extractText(props.children);
      return '';
    }
    return String(node || '');
  };
  const [mounted, setMounted] = useState(false);
  useEffect(() => {
    setMounted(true);
  }, []);
  const data = useMemo(() => {
    if (propData) return propData;
    if (content && typeof content === 'string') return parseYamlTableContent(content);
    if (!children) return [];
    if (typeof children === 'string') return parseYamlTableContent(children);
    const childrenArray = Array.isArray(children) ? children : [children];
    return parseYamlTableContent(childrenArray.map(extractText).join('').trim());
  }, [children, propData, content]);
  const columns = useMemo(() => {
    if (!data || data.length === 0) return [];
    const firstRow = data[0];
    if (!firstRow || typeof firstRow !== 'object') return [];
    return Object.keys(firstRow);
  }, [data]);
  if (!mounted) return null;
  if (!data || data.length === 0) return null;
  const rowKey = row => columns.map(c => row[c] || '').join('|');
  return <table>
      <thead>
        <tr>
          {columns.map(col => <th key={col}>{col.replaceAll('_', ' ')}</th>)}
        </tr>
      </thead>
      <tbody>
        {data.map(row => <tr key={rowKey(row)}>
            {columns.map(col => <td key={col}>{processBadges(row[col])}</td>)}
          </tr>)}
      </tbody>
    </table>;
};

A vulnerability is a security weakness in a software package that attackers can exploit to compromise systems, steal data, or disrupt operations. Open-source software often contains vulnerabilities that can introduce risks to your organization, if not managed properly.

Endor Labs vulnerability database is a comprehensive compilation of known software vulnerabilities. You can search the vulnerability database to identify and discover vulnerabilities within your software dependencies.

You can use the following vulnerability IDs to search within the Endor Labs platform:

<YamlTable>
  {`


    - Identifier_type: CVE ID
    Example: CVE-2023-45678
    Description: The most common global identifier for vulnerabilities. MITRE manages it and it is widely used.
    - Identifier_type: GHSA ID
    Example: GHSA-xxxx-xxxx-xxxx
    Description: GitHub Security Advisory ID for vulnerabilities reported by GitHub.
    - Identifier_type: PySEC ID
    Example: PYSEC-2023-123
    Description: Identifier for vulnerabilities in Python packages, sourced from the Python Packaging Advisory Database.
    - Identifier_type: MAL ID
    Example: MAL-xxxx-xxxx
    Description: Identifier for malware advisories. OSV supplies the data and flags packages linked to malicious activity.


    `}
</YamlTable>

<Note>
  Endor Labs supports vulnerability searches only for identifiers included in the `meta.name` or `spec.aliases` fields.
</Note>

## Search for a vulnerability

Search for vulnerabilities using supported security identifiers across your software dependencies.

1. Sign in to Endor Labs and select **Discover > Vulnerabilities** from the left sidebar.

2. Type a search query using a vulnerability ID (for example, CVE, GHSA) and click **Search Vulnerabilities**.

   <img src="https://mintcdn.com/endorlabs-b4795f4f/dHzwUrp_QbpzV9uv/images/discover/vulnerability-db/vulnerability-db.webp?fit=max&auto=format&n=dHzwUrp_QbpzV9uv&q=85&s=5944f63e9269790f7cde4cccea858bb7" alt="Vulnerability Search" style={{width: '70%'}} width="2151" height="3513" data-path="images/discover/vulnerability-db/vulnerability-db.webp" />

   You can view detailed information including the name of the vulnerability, CVE ID, vulnerability's severity, description, and metadata to help users quickly identify important details about a vulnerability.

3. Select **Affected Packages** to view a list of all software packages impacted by the identified vulnerability, including their names, introduced and fixed versions, and the source of the vulnerability data.

4. Select a package to view its details.
   * **Overview**: Shows affected and fixed versions, severity, available patches, impacted classes, and a link to the fix commit. It helps users understand the issue and take necessary remediation steps.

     <img src="https://mintcdn.com/endorlabs-b4795f4f/dHzwUrp_QbpzV9uv/images/discover/vulnerability-db/affected-packages-overview.webp?fit=max&auto=format&n=dHzwUrp_QbpzV9uv&q=85&s=2ab5aa38b6856b6ceacdc09dcb9b7af7" alt="Affected packages overview" width="520" height="810" data-path="images/discover/vulnerability-db/affected-packages-overview.webp" />
   * **Endor Details**: Shows affected call paths and file paths to help identify where the vulnerable code runs and what can trigger it in the project

     <img src="https://mintcdn.com/endorlabs-b4795f4f/dHzwUrp_QbpzV9uv/images/discover/vulnerability-db/affected-packages-details.webp?fit=max&auto=format&n=dHzwUrp_QbpzV9uv&q=85&s=45154c3faada0a2998b5f8c5391afee4" alt="Affected Packages details" width="536" height="566" data-path="images/discover/vulnerability-db/affected-packages-details.webp" />
   * **Impact**:  Shows each package version, along with the number of findings, how many projects use it, and how many other packages depend on it

     <img src="https://mintcdn.com/endorlabs-b4795f4f/dHzwUrp_QbpzV9uv/images/discover/vulnerability-db/affected-packages-impact.webp?fit=max&auto=format&n=dHzwUrp_QbpzV9uv&q=85&s=19ee6e8d379a564e04336aad49d27e3b" alt="Affected Packages Impact" width="515" height="501" data-path="images/discover/vulnerability-db/affected-packages-impact.webp" />

5. Select **Containers** to see all container images in your organization with known vulnerabilities. It lists the affected packages, where each issue entered, whether fixes are available, and the severity of the issues.

   <img src="https://mintcdn.com/endorlabs-b4795f4f/dHzwUrp_QbpzV9uv/images/discover/vulnerability-db/affected-package-container.webp?fit=max&auto=format&n=dHzwUrp_QbpzV9uv&q=85&s=5a13ce244e865271f341a4b0847facb9" alt="affected packages container" width="2912" height="1882" data-path="images/discover/vulnerability-db/affected-package-container.webp" />
