openapi: 3.1.0

info:
  title: WPVulnerability API
  version: "1.13.0"
  description: |
    Public REST API for WordPress vulnerability data, infrastructure software vulnerabilities,
    and supply-chain audit intelligence.

    ## Authentication

    | Endpoint group | Auth |
    |---|---|
    | `/`, `/core/`, `/plugin/`, `/theme/`, and all infrastructure endpoints | None — public |
    | Bulk update endpoints (`/all/`) | API key appended to path: `/all/{type}/{apikey}/` |

    ## Response envelope

    Every response shares a common JSON wrapper:

    | Field | Type | Description |
    |---|---|---|
    | `error` | integer | `0` = success, `1` = error |
    | `message` | string\|null | Human-readable error details; `null` on success |
    | `data` | object\|array\|null | Payload (varies by endpoint) |
    | `updated` | integer | Unix timestamp of the last data refresh |

    HTTP status is `200 OK` except `403 Forbidden` (invalid API key) and `503 Service Unavailable` (database failure).

    ## Operators

    Version comparison operators follow PHP `version_compare()` semantics and are always lowercase.

    | Operator | Symbol | Meaning |
    |---|---|---|
    | `lt` | < | Component version is strictly less than the vulnerability version |
    | `le` | ≤ | Component version is less than or equal to the vulnerability version |
    | `eq` | = | Component version matches exactly |
    | `ne` | ≠ | Component version differs from the vulnerability version |
    | `gt` | > | Component version exceeds the vulnerability version |
    | `ge` | ≥ | Component version is greater than or equal to the vulnerability version |

  contact:
    name: WPVulnerability
    url: https://wpvulnerability.com

servers:
  - url: https://www.wpvulnerability.net
    description: Production API

tags:
  - name: General
    description: Statistics and project information
  - name: WordPress
    description: WordPress core, plugin, and theme vulnerability data
  - name: Infrastructure
    description: Server-side software vulnerability data
  - name: Last updates
    description: Full slug/version lists for integration use (API key required)

paths:

  /:
    get:
      operationId: getStats
      summary: Statistics
      description: |
        Aggregated vulnerability counts across all data sources, plus sponsor and contributor lists.
        No authentication required. Cached for 6 hours.
      tags: [General]
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Envelope"
                  - type: object
                    properties:
                      stats:
                        $ref: "#/components/schemas/Stats"
                      behindtheproject:
                        $ref: "#/components/schemas/BehindTheProject"
              example:
                error: 0
                message: null
                data: null
                stats:
                  products:
                    core: "123"
                    plugins: "123"
                    themes: "123"
                  vulnerabilities:
                    cve:
                      core: "123"
                      plugins: "123"
                      themes: "123"
                    jvn:
                      core: "123"
                      plugins: "123"
                      themes: "123"
                    patchstack:
                      core: "123"
                      plugins: "123"
                      themes: "123"
                    wpscan:
                      core: "123"
                      plugins: "123"
                      themes: "123"
                    wordfence:
                      core: "123"
                      plugins: "123"
                      themes: "123"
                  core: "123"
                  plugins: "123"
                  themes: "123"
                  php: "123"
                  apache: "123"
                  nginx: "123"
                  mariadb: "123"
                  mysql: "123"
                behindtheproject:
                  sponsors:
                    - name: "Sponsor name"
                      url: "https://www.example.com/"
                      image: "https://www.example.com/image.png"
                  contributors:
                    - name: "Contributor name"
                      url: "https://www.example.com/"
                      image: "https://www.example.com/image.png"
                updated: 123456789
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /core/{version}/:
    get:
      operationId: getCoreVulnerabilities
      summary: WordPress core
      description: |
        All known vulnerabilities for a specific WordPress core version.
        Cached permanently; invalidated by the CDN crawler when new data is available.
      tags: [WordPress]
      parameters:
        - name: version
          in: path
          required: true
          description: WordPress core version
          schema:
            type: string
            example: "5.8.2"
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Envelope"
                  - type: object
                    properties:
                      data:
                        $ref: "#/components/schemas/CoreData"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /plugin/{slug}/:
    get:
      operationId: getPluginVulnerabilities
      summary: WordPress plugin
      description: |
        All known vulnerabilities for a plugin slug. When supply-chain attack data is available for this plugin,
        a `supplychain` array is included in `data`. The field is omitted when no approved audit exists.
        Cached permanently; invalidated by the CDN crawler.
      tags: [WordPress]
      parameters:
        - name: slug
          in: path
          required: true
          description: WordPress.org plugin slug
          schema:
            type: string
            example: "updraftplus"
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Envelope"
                  - type: object
                    properties:
                      data:
                        $ref: "#/components/schemas/PluginData"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /theme/{slug}/:
    get:
      operationId: getThemeVulnerabilities
      summary: WordPress theme
      description: |
        All known vulnerabilities for a theme slug.
        Cached permanently; invalidated by the CDN crawler.
      tags: [WordPress]
      parameters:
        - name: slug
          in: path
          required: true
          description: WordPress.org theme slug
          schema:
            type: string
            example: "ripple"
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Envelope"
                  - type: object
                    properties:
                      data:
                        $ref: "#/components/schemas/ThemeData"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /php/{version}/:
    get:
      operationId: getPhpVulnerabilities
      summary: PHP
      description: |
        PHP vulnerability data since PHP 4.0 — vulnerabilities that may apply to WordPress.
        This is not a PHP vulnerability database.
        Accepts a major or minor version (e.g. `8.2`, `8.2.18`). Cached for 1 hour.
      tags: [Infrastructure]
      parameters:
        - name: version
          in: path
          required: true
          description: Major or minor PHP version
          schema:
            type: string
            example: "8.2"
      responses:
        "200":
          $ref: "#/components/responses/SoftwareResponse"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /apache/{version}/:
    get:
      operationId: getApacheVulnerabilities
      summary: Apache HTTPD
      description: |
        Apache HTTPD vulnerability data since Apache HTTPD 1.3 — vulnerabilities that may apply to WordPress.
        This is not a comprehensive Apache HTTPD vulnerability database.
        Cached for 1 hour.
      tags: [Infrastructure]
      parameters:
        - name: version
          in: path
          required: true
          description: Major or minor Apache HTTPD version
          schema:
            type: string
            example: "2.4"
      responses:
        "200":
          $ref: "#/components/responses/SoftwareResponse"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /nginx/{version}/:
    get:
      operationId: getNginxVulnerabilities
      summary: nginx
      description: |
        nginx vulnerability data since nginx 0.5 — vulnerabilities that may apply to WordPress.
        This is not a nginx vulnerability database.
        Cached for 1 hour.
      tags: [Infrastructure]
      parameters:
        - name: version
          in: path
          required: true
          description: Major or minor nginx version
          schema:
            type: string
            example: "1.22"
      responses:
        "200":
          $ref: "#/components/responses/SoftwareResponse"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /mariadb/{version}/:
    get:
      operationId: getMariadbVulnerabilities
      summary: MariaDB
      description: |
        MariaDB vulnerability data since MariaDB 5.5 — vulnerabilities that may apply to WordPress.
        This is not a MariaDB vulnerability database.
        Cached for 1 hour.
      tags: [Infrastructure]
      parameters:
        - name: version
          in: path
          required: true
          description: MariaDB version
          schema:
            type: string
            example: "10.1.25"
      responses:
        "200":
          $ref: "#/components/responses/SoftwareResponse"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /mysql/{version}/:
    get:
      operationId: getMysqlVulnerabilities
      summary: MySQL
      description: |
        MySQL vulnerability data since MySQL 3.23 — vulnerabilities that may apply to WordPress.
        This is not a MySQL vulnerability database.
        Cached for 1 hour.
      tags: [Infrastructure]
      parameters:
        - name: version
          in: path
          required: true
          description: MySQL version
          schema:
            type: string
            example: "8.0.30"
      responses:
        "200":
          $ref: "#/components/responses/SoftwareResponse"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /imagemagick/{version}/:
    get:
      operationId: getImagemagickVulnerabilities
      summary: ImageMagick
      description: |
        ImageMagick vulnerability data since version 6.8 — vulnerabilities that may apply to WordPress.
        This is not an ImageMagick vulnerability database.
        Cached for 1 hour.
      tags: [Infrastructure]
      parameters:
        - name: version
          in: path
          required: true
          description: Major or minor ImageMagick version
          schema:
            type: string
            example: "6.9"
      responses:
        "200":
          $ref: "#/components/responses/SoftwareResponse"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /curl/{version}/:
    get:
      operationId: getCurlVulnerabilities
      summary: cURL
      description: |
        cURL vulnerability data since curl 7.1 — vulnerabilities that may apply to WordPress.
        This is not a comprehensive curl vulnerability database.
        Cached for 1 hour.
      tags: [Infrastructure]
      parameters:
        - name: version
          in: path
          required: true
          description: Major or minor cURL version
          schema:
            type: string
            example: "7.77"
      responses:
        "200":
          $ref: "#/components/responses/SoftwareResponse"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /memcached/{version}/:
    get:
      operationId: getMemcachedVulnerabilities
      summary: Memcached
      description: |
        Memcached vulnerability data since memcached 1.4 — vulnerabilities that may apply to WordPress.
        This is not a memcached vulnerability database.
        Cached for 1 hour.
      tags: [Infrastructure]
      parameters:
        - name: version
          in: path
          required: true
          description: Major or minor Memcached version
          schema:
            type: string
            example: "1.5"
      responses:
        "200":
          $ref: "#/components/responses/SoftwareResponse"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /redis/{version}/:
    get:
      operationId: getRedisVulnerabilities
      summary: Redis
      description: |
        Redis vulnerability data since Redis 2.0 — vulnerabilities that may apply to WordPress.
        This is not a Redis vulnerability database.
        Cached for 1 hour.
      tags: [Infrastructure]
      parameters:
        - name: version
          in: path
          required: true
          description: Major or minor Redis version
          schema:
            type: string
            example: "7.0"
      responses:
        "200":
          $ref: "#/components/responses/SoftwareResponse"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /sqlite/{version}/:
    get:
      operationId: getSqliteVulnerabilities
      summary: SQLite
      description: |
        SQLite vulnerability data since SQLite 3.0 — vulnerabilities that may apply to WordPress.
        This is not a SQLite vulnerability database.
        Cached for 1 hour.
      tags: [Infrastructure]
      parameters:
        - name: version
          in: path
          required: true
          description: Major or minor SQLite version
          schema:
            type: string
            example: "3.40"
      responses:
        "200":
          $ref: "#/components/responses/SoftwareResponse"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /all/core/{apikey}/:
    get:
      operationId: getAllCore
      summary: Last updates WordPress core
      description: |
        All WordPress core versions that have at least one active vulnerability. API key required.
        Use `since` to retrieve only versions updated after a given Unix timestamp (limited to the last 52 weeks).
      tags: [Last updates]
      parameters:
        - $ref: "#/components/parameters/PathApiKey"
        - $ref: "#/components/parameters/Since"
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Envelope"
                  - type: object
                    properties:
                      data:
                        type: array
                        items:
                          $ref: "#/components/schemas/AllCoreEntry"
        "403":
          $ref: "#/components/responses/Forbidden"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /all/plugin/{apikey}/:
    get:
      operationId: getAllPlugins
      summary: Last updates WordPress plugin
      description: |
        All plugin slugs that have at least one active vulnerability. API key required.
        Use `since` to fetch only slugs updated after a given Unix timestamp (limited to the last 52 weeks;
        values outside that range are ignored).
      tags: [Last updates]
      parameters:
        - $ref: "#/components/parameters/PathApiKey"
        - $ref: "#/components/parameters/Since"
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Envelope"
                  - type: object
                    properties:
                      data:
                        type: array
                        items:
                          $ref: "#/components/schemas/AllSlugEntry"
        "403":
          $ref: "#/components/responses/Forbidden"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

  /all/theme/{apikey}/:
    get:
      operationId: getAllThemes
      summary: Last updates WordPress theme
      description: |
        All theme slugs that have at least one active vulnerability. API key required.
        Use `since` to retrieve only themes updated after a given Unix timestamp (limited to the last 52 weeks).
      tags: [Last updates]
      parameters:
        - $ref: "#/components/parameters/PathApiKey"
        - $ref: "#/components/parameters/Since"
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Envelope"
                  - type: object
                    properties:
                      data:
                        type: array
                        items:
                          $ref: "#/components/schemas/AllSlugEntry"
        "403":
          $ref: "#/components/responses/Forbidden"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"

components:

  parameters:

    PathApiKey:
      name: apikey
      in: path
      required: true
      description: API key
      schema:
        type: string

    Since:
      name: since
      in: query
      required: false
      description: Unix timestamp. When provided, returns only entries updated after this date. Limited to the last 52 weeks.
      schema:
        type: integer
        example: 1714521600

  responses:

    Forbidden:
      description: Invalid or missing API key
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"

    ServiceUnavailable:
      description: Database connection failure
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"

    SoftwareResponse:
      description: Success
      content:
        application/json:
          schema:
            allOf:
              - $ref: "#/components/schemas/Envelope"
              - type: object
                properties:
                  data:
                    $ref: "#/components/schemas/SoftwareData"

  schemas:

    # ---------------------------------------------------------------------------
    # Envelope
    # ---------------------------------------------------------------------------

    Envelope:
      type: object
      required: [error, message, data, updated]
      properties:
        error:
          type: integer
          enum: [0, 1]
          description: "`0` = success, `1` = error"
        message:
          type: [string, "null"]
          description: Error details when applicable; `null` on success
        data:
          description: Response payload; type varies by endpoint
        updated:
          type: [integer, string]
          description: |
            Unix timestamp of the last data refresh.
            Infrastructure and statistics endpoints return an integer; WordPress (core/plugin/theme) endpoints
            return a numeric string (e.g. `"1776963060"`). Treat as a Unix timestamp regardless of type.

    ErrorEnvelope:
      type: object
      description: Returned when `error` is `1` or on HTTP 403 / 503.
      properties:
        error:
          type: integer
          enum: [1]
        message:
          type: string
          description: Descriptive error text
        data:
          type: "null"
        updated:
          type: integer

    # ---------------------------------------------------------------------------
    # Shared sub-objects
    # ---------------------------------------------------------------------------

    Source:
      type: object
      description: |
        A vulnerability record from a single data source.
        Supported sources: CVE (NVD), EUVD, JVN, Patchstack (PAT), WPScan (WPS), Wordfence (WFN).

        **Note:** The `name` field is present on WordPress endpoints (core, plugin, theme) but is
        **absent** on infrastructure endpoints (PHP, Apache, nginx, etc.), where sources only contain
        `id`, `link`, `description`, and `date`.
      properties:
        id:
          type: string
          description: Source identifier, e.g. `CVE-2024-12345`, `JVNDB-…`
          example: "CVE-2024-12345"
        name:
          type: string
          description: Vulnerability name as reported by this source. Present on WordPress endpoints only.
        link:
          type: string
          format: uri
          description: Source URL
        description:
          type: string
          description: Vulnerability description
        date:
          type: string
          format: date
          description: Publication date (YYYY-MM-DD)

    CweEntry:
      type: object
      description: |
        A CWE (Common Weakness Enumeration) classification entry.
        CWE is a community-developed list of software and hardware weakness types used as a
        classification baseline for vulnerability identification and prevention.
      properties:
        cwe:
          type: string
          description: CWE identifier
          example: "CWE-89"
        name:
          type: string
          description: Short weakness name
        description:
          type: string
          description: Weakness description

    # ---------------------------------------------------------------------------
    # CVSS blocks
    # ---------------------------------------------------------------------------

    CvssLegacy:
      type: [object, "null"]
      description: |
        Legacy CVSS block. Populated from CVE/NVD data only. Values use abbreviated single-letter codes.
        This block is frozen — no new fields will be added. See `cvss3` for the human-readable equivalent.
      properties:
        version:
          type: string
          description: CVSS version, e.g. `3.1`
        vector:
          type: string
          description: Full CVSS vector string
        av:
          type: string
          description: "Attack Vector: `n`=network, `a`=adjacent, `l`=local, `p`=physical"
        ac:
          type: string
          description: "Attack Complexity: `l`=low, `h`=high"
        pr:
          type: string
          description: "Privileges Required: `n`=none, `l`=low, `h`=high"
        ui:
          type: string
          description: "User Interaction: `n`=none, `r`=required"
        s:
          type: string
          description: "Scope: `u`=unchanged, `c`=changed"
        c:
          type: string
          description: "Confidentiality: `n`=none, `l`=low, `h`=high"
        i:
          type: string
          description: "Integrity: `n`=none, `l`=low, `h`=high"
        a:
          type: string
          description: "Availability: `n`=none, `l`=low, `h`=high"
        score:
          type: string
          description: Base score (`0.0`–`10.0`)
        severity:
          type: string
          description: "Abbreviated severity: `c`=critical, `h`=high, `m`=medium, `l`=low, `n`=none"
        exploitable:
          type: string
          description: Exploitability sub-score
        impact:
          type: string
          description: Impact sub-score

    Cvss2:
      type: [object, "null"]
      description: |
        CVSS v2.x block. EUVD source only.

        CVSS 2.0 uses **Authentication** (`au`) instead of Privileges Required / User Interaction.
        Confidentiality, Integrity, and Availability use `none`/`partial`/`complete` (not `none`/`low`/`high`).
        There is no `critical` severity level — the maximum is `high`.

        Vector format: `AV:N/AC:L/AU:N/C:P/I:P/A:P`

        **Severity ranges:** low = 0.0–3.9, medium = 4.0–6.9, high = 7.0–10.0
      properties:
        version:
          type: string
          enum: ["2.0"]
        vector:
          type: string
          description: Vector string without version prefix
          example: "AV:N/AC:L/AU:N/C:P/I:P/A:P"
        score:
          type: string
          description: Base score (`0.0`–`10.0`)
        severity:
          type: string
          enum: [low, medium, high]
        av:
          type: [string, "null"]
          enum: [network, adjacent, local, null]
          description: |
            Access Vector.
            `network` = exploitable across the network.
            `adjacent` = exploitable from the adjacent network only.
            `local` = requires local access.
        ac:
          type: [string, "null"]
          enum: [low, medium, high, null]
          description: |
            Access Complexity.
            `low` = no specialized conditions required.
            `medium` = some conditions required.
            `high` = specialized conditions required.
        au:
          type: [string, "null"]
          enum: [none, single, multiple, null]
          description: |
            Authentication (CVSS 2.0 only — number of times an attacker must authenticate).
            `none` = no authentication required.
            `single` = one authentication required.
            `multiple` = multiple authentications required.
        c:
          type: [string, "null"]
          enum: [none, partial, complete, null]
          description: |
            Confidentiality impact.
            `none` = no impact.
            `partial` = considerable disclosure but limited scope.
            `complete` = total information disclosure.
        i:
          type: [string, "null"]
          enum: [none, partial, complete, null]
          description: |
            Integrity impact.
            `none` = no impact.
            `partial` = some file or information modification possible.
            `complete` = total system integrity compromise.
        a:
          type: [string, "null"]
          enum: [none, partial, complete, null]
          description: |
            Availability impact.
            `none` = no impact.
            `partial` = reduced performance or interruptions.
            `complete` = total resource shutdown.

    Cvss3:
      type: [object, "null"]
      description: |
        CVSS v3.0 / v3.1 block. The `version` field distinguishes the two.
        CVE/NVD coverage: ~98%. EUVD coverage: ~71%.
        Exploitability and impact sub-scores are only available from CVE/NVD; they are `null` for EUVD.

        Vector format: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H`

        **Severity ranges:** none = 0.0, low = 0.1–3.9, medium = 4.0–6.9, high = 7.0–8.9, critical = 9.0–10.0
      properties:
        version:
          type: string
          enum: ["3.0", "3.1"]
        vector:
          type: string
          description: Full CVSS vector string
          example: "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
        score:
          type: string
          description: Base score (`0.0`–`10.0`)
        severity:
          type: string
          enum: [none, low, medium, high, critical]
        av:
          type: [string, "null"]
          enum: [network, adjacent, local, physical, null]
          description: |
            Attack Vector.
            `network` = exploitable from across the network, up to and including the entire Internet.
            `adjacent` = exploitable from the same shared physical or logical network.
            `local` = requires local access (keyboard, console, SSH) or user interaction.
            `physical` = requires physical device manipulation.
        ac:
          type: [string, "null"]
          enum: [low, high, null]
          description: |
            Attack Complexity.
            `low` = no specialized conditions; repeatable success expected.
            `high` = success depends on conditions the attacker cannot control.
        pr:
          type: [string, "null"]
          enum: [none, low, high, null]
          description: |
            Privileges Required.
            `none` = no prior privileges needed.
            `low` = basic user-level capabilities required.
            `high` = administrative component control required.
        ui:
          type: [string, "null"]
          enum: [none, required, null]
          description: |
            User Interaction.
            `none` = no user interaction required.
            `required` = a user must take a specific action before exploitation.
        s:
          type: [string, "null"]
          enum: [unchanged, changed, null]
          description: |
            Scope.
            `unchanged` = impact limited to the vulnerable component's security scope.
            `changed` = impact extends beyond to other components managed by a different security authority.
        c:
          type: [string, "null"]
          enum: [none, low, high, null]
          description: |
            Confidentiality impact.
            `none` = no loss.
            `low` = some loss; limited restricted information access.
            `high` = total loss; all resources divulged.
        i:
          type: [string, "null"]
          enum: [none, low, high, null]
          description: |
            Integrity impact.
            `none` = no loss.
            `low` = modification possible but limited in scope or consequence.
            `high` = total integrity loss or complete protection loss.
        a:
          type: [string, "null"]
          enum: [none, low, high, null]
          description: |
            Availability impact.
            `none` = no impact.
            `low` = performance reduced or interruptions occur.
            `high` = total availability loss; complete resource denial.
        exploitable:
          type: [string, "null"]
          description: Exploitability sub-score (ease of exploitation). CVE/NVD only; `null` for EUVD.
        impact:
          type: [string, "null"]
          description: Impact sub-score (overall impact of exploitation). CVE/NVD only; `null` for EUVD.

    Cvss4:
      type: [object, "null"]
      description: |
        CVSS v4.0 block. EUVD source only (~5% coverage).

        CVSS 4.0 replaces the single Scope metric with separate **Vulnerable System** and
        **Subsequent System** impact metrics, and introduces **Attack Requirements** (`at`).
        The value `safety` for `si`/`sa` indicates potential impact on human safety.

        Vector format: `CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N`

        **Severity ranges:** none = 0.0, low = 0.1–3.9, medium = 4.0–6.9, high = 7.0–8.9, critical = 9.0–10.0
      properties:
        version:
          type: string
          enum: ["4.0"]
        vector:
          type: string
          description: Full CVSS vector string
          example: "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N"
        score:
          type: string
          description: Base score (`0.0`–`10.0`)
        severity:
          type: string
          enum: [none, low, medium, high, critical]
        av:
          type: [string, "null"]
          enum: [network, adjacent, local, physical, null]
          description: |
            Attack Vector.
            `network` = internet-accessible.
            `adjacent` = same LAN / Bluetooth / local subnet.
            `local` = requires local access or user interaction.
            `physical` = requires physical device access.
        ac:
          type: [string, "null"]
          enum: [low, high, null]
          description: |
            Attack Complexity.
            `low` = no specialized conditions; repeatable success.
            `high` = success depends on uncontrollable conditions.
        at:
          type: [string, "null"]
          enum: [none, present, null]
          description: |
            Attack Requirements (new in v4).
            `none` = no additional deployment conditions required.
            `present` = specific deployment or configuration conditions must exist.
        pr:
          type: [string, "null"]
          enum: [none, low, high, null]
          description: |
            Privileges Required.
            `none` = no privileges needed.
            `low` = basic user privileges.
            `high` = administrative privileges.
        ui:
          type: [string, "null"]
          enum: [none, passive, active, null]
          description: |
            User Interaction.
            `none` = no interaction required.
            `passive` = user passively participates (e.g. visits a page).
            `active` = user must perform a specific action.
        vc:
          type: [string, "null"]
          enum: [none, low, high, null]
          description: Vulnerable System — Confidentiality impact
        vi:
          type: [string, "null"]
          enum: [none, low, high, null]
          description: Vulnerable System — Integrity impact
        va:
          type: [string, "null"]
          enum: [none, low, high, null]
          description: Vulnerable System — Availability impact
        sc:
          type: [string, "null"]
          enum: [none, low, high, null]
          description: Subsequent System — Confidentiality impact
        si:
          type: [string, "null"]
          enum: [none, low, high, safety, null]
          description: "Subsequent System — Integrity impact. `safety` = potential impact on human safety."
        sa:
          type: [string, "null"]
          enum: [none, low, high, safety, null]
          description: "Subsequent System — Availability impact. `safety` = potential impact on human safety."

    Ssvc:
      type: [object, "null"]
      description: |
        SSVC v2.0.3 (Stakeholder-Specific Vulnerability Categorization) + CISA KEV data.
        CVE source only (~85% of WordPress CVEs have SSVC data, ~0.04% are in KEV).
        `null` for all other sources (EUVD, JVN, PAT, WPS, WFN).
        Not present on infrastructure endpoints.
      properties:
        exploitation:
          type: [string, "null"]
          enum: [none, poc, active, null]
          description: |
            Exploitation state.
            `none` = no known exploitation.
            `poc` = proof-of-concept code exists.
            `active` = active exploitation in the wild.
        automatable:
          type: [string, "null"]
          enum: ["yes", "no", null]
          description: Whether the vulnerability can be reliably automated
        technical_impact:
          type: [string, "null"]
          enum: [partial, total, null]
          description: |
            Technical impact category.
            `partial` = limited impact on the vulnerable component.
            `total` = complete compromise of the vulnerable component.
        kev:
          type: boolean
          description: Whether the CVE is in the CISA Known Exploited Vulnerabilities catalog
        kev_date:
          type: [string, "null"]
          format: date
          description: Date added to the KEV catalog (YYYY-MM-DD); `null` if not in KEV

    # ---------------------------------------------------------------------------
    # Impact blocks
    # ---------------------------------------------------------------------------

    ImpactWP:
      type: [object, array]
      description: |
        Impact block for WordPress endpoints (core, plugin, theme).
        When no scoring data exists for a vulnerability (no CVE or EUVD source),
        this field is an **empty array** `[]` rather than an object.

        **CVSS** (Common Vulnerability Scoring System) provides Base metric scores from 0.0–10.0
        across three generations (v2.0, v3.0/3.1, v4.0).

        **EPSS** estimates the probability that a vulnerability will be exploited within the next 30 days (0.0–1.0).
        It complements CVSS by measuring likelihood rather than severity.

        **SSVC** (Stakeholder-Specific Vulnerability Categorization) provides exploitation state and KEV status.
        KEV is the CISA Known Exploited Vulnerabilities catalog — an authoritative list of CVEs with confirmed
        real-world exploitation evidence. A vulnerability can have a medium CVSS score but appear in KEV,
        meaning it is actively exploited despite not being the most severe on paper.

        **CWE** identifies the weakness type behind the vulnerability.

        Data source coverage:

        | Field | CVE/NVD | EUVD | JVN | PAT | WPS | WFN |
        |---|---|---|---|---|---|---|
        | `cvss` (legacy) | v3 only | — | — | — | — | — |
        | `cvss2` | — | 24% | — | — | — | — |
        | `cvss3` | 98% | 71% | — | — | — | — |
        | `cvss4` | — | 5% | — | — | — | — |
        | `epss` | — | 83% | — | — | — | — |
        | `ssvc` | 85% | — | — | — | — | — |
        | `cwe` | yes | — | — | — | — | — |
      properties:
        cvss:
          $ref: "#/components/schemas/CvssLegacy"
        cvss2:
          $ref: "#/components/schemas/Cvss2"
        cvss3:
          $ref: "#/components/schemas/Cvss3"
        cvss4:
          $ref: "#/components/schemas/Cvss4"
        epss:
          type: [string, "null"]
          description: |
            EPSS score — probability of exploitation in the next 30 days (0.0–1.0).
            EUVD source only (~83% of EUVD records); `null` for CVE, JVN, PAT, WPS, WFN sources.
        ssvc:
          $ref: "#/components/schemas/Ssvc"
        cwe:
          type: array
          items:
            $ref: "#/components/schemas/CweEntry"
          description: CWE weakness classifications; empty array if none

    ImpactInfra:
      type: [object, array]
      description: |
        Impact block for infrastructure endpoints (PHP, Apache, nginx, etc.).
        SSVC and EPSS are not available for infrastructure endpoints.
        When no OpenCVE record exists for a CVE, this field is an **empty array** `[]` rather than an object.
      properties:
        cvss2:
          $ref: "#/components/schemas/Cvss2"
        cvss3:
          $ref: "#/components/schemas/Cvss3"
        cvss4:
          $ref: "#/components/schemas/Cvss4"
        kev:
          type: boolean
          description: Whether the CVE is in the CISA Known Exploited Vulnerabilities catalog
        cwe:
          type: array
          items:
            $ref: "#/components/schemas/CweEntry"
          description: CWE weakness classifications; empty array if none

    # ---------------------------------------------------------------------------
    # Version operators
    # ---------------------------------------------------------------------------

    Operator:
      type: object
      description: |
        Version range for a vulnerability. Operators are lowercase and follow PHP `version_compare()` semantics.

        | Operator | Meaning |
        |---|---|
        | `lt` | Strictly less than |
        | `le` | Less than or equal to |
        | `eq` | Exactly equal |
        | `ne` | Not equal |
        | `gt` | Strictly greater than |
        | `ge` | Greater than or equal to |

        A `null` `min_version` / `min_operator` means no lower bound (all versions up to `max_version` are affected).

        **Type note on `unfixed`:** WordPress endpoints return a string (`"0"` / `"1"`); infrastructure
        endpoints return an integer (`0` / `1`) or `null`.
      properties:
        min_version:
          type: [string, "null"]
          description: Minimum version affected; `null` means no lower bound
        min_operator:
          type: [string, "null"]
          enum: [lt, le, eq, ne, gt, ge, null]
          description: Comparison operator for min; `null` when no lower bound
        max_version:
          type: [string, "null"]
          description: Maximum version affected; `null` means no upper bound (unfixed)
        max_operator:
          type: [string, "null"]
          enum: [lt, le, eq, ne, gt, ge, null]
          description: Comparison operator for max (e.g. `lt` = fixed in this version, `le` = this version is the last affected)
        unfixed:
          type: [string, integer, "null"]
          description: "`1` (or `\"1\"`) if no fix has been released; `0` (or `\"0\"`) otherwise"

    OperatorWP:
      description: Version range for WordPress plugin or theme vulnerabilities. Extends `Operator` with a `closed` flag.
      allOf:
        - $ref: "#/components/schemas/Operator"
        - type: object
          properties:
            closed:
              type: [string, integer, "null"]
              description: "`1` (or `\"1\"`) if the plugin or theme is closed in the WordPress.org repository; `0` otherwise"

    # ---------------------------------------------------------------------------
    # Vulnerability entries
    # ---------------------------------------------------------------------------

    VulnerabilityCore:
      type: object
      description: A vulnerability entry for WordPress core. Core entries do not have an `operator` block.
      properties:
        uuid:
          type: string
          format: uuid
          description: Unique vulnerability identifier
        name:
          type: string
          description: Vulnerability title
        description:
          type: [string, "null"]
          description: Detailed explanation
        source:
          type: array
          items:
            $ref: "#/components/schemas/Source"
        impact:
          $ref: "#/components/schemas/ImpactWP"

    VulnerabilityWP:
      type: object
      description: A vulnerability entry for a WordPress plugin or theme.
      properties:
        uuid:
          type: string
          format: uuid
          description: Unique vulnerability identifier
        name:
          type: string
          description: Vulnerability title with affected version range
        description:
          type: [string, "null"]
          description: Detailed explanation
        operator:
          $ref: "#/components/schemas/OperatorWP"
        source:
          type: array
          items:
            $ref: "#/components/schemas/Source"
        impact:
          $ref: "#/components/schemas/ImpactWP"

    VulnerabilitySoftware:
      type: object
      description: A vulnerability entry for an infrastructure software component.
      properties:
        uuid:
          type: string
          format: uuid
          description: Unique vulnerability identifier
        name:
          type: string
          description: Vulnerability name, e.g. `PHP 8.2 >= 8.2.0 - < 8.2.18`
        operator:
          $ref: "#/components/schemas/Operator"
        source:
          type: array
          items:
            $ref: "#/components/schemas/Source"
        impact:
          $ref: "#/components/schemas/ImpactInfra"

    # ---------------------------------------------------------------------------
    # Supply-chain
    # ---------------------------------------------------------------------------

    C2Infrastructure:
      type: object
      description: An Indicator of Compromise (IOC) extracted from a supply-chain audit.
      properties:
        kind:
          type: string
          description: IOC type, e.g. `domain`, `ip`, `url`
        value:
          type: string
          description: IOC value
        confidence:
          type: string
          enum: [high, medium, low]
          description: Confidence level
        notes:
          type: string
          description: Additional context or notes

    Signal:
      type: object
      description: Unverified early-warning signal from automated detection. May precede a full audit.
      properties:
        severity:
          type: string
          enum: [critical, high, medium, low, info]
          description: Signal severity
        rule:
          type: string
          description: Detection rule identifier
        detected_at:
          type: string
          format: date
          description: Detection date (YYYY-MM-DD)

    AffectedVersions:
      type: object
      description: Version range for a supply-chain attack.
      properties:
        min_version:
          type: [string, "null"]
          description: Last known clean version (lower bound); `null` if unknown
        min_operator:
          type: string
          enum: [ge]
          description: Always `ge` — versions >= `min_version` are considered affected
        max_version:
          type: [string, "null"]
          description: First clean version after remediation; `null` unless verdict is `cleaned`
        max_operator:
          type: [string, "null"]
          enum: [lt, null]
          description: "`lt` when `max_version` is set; `null` when there is no upper bound"

    SupplyChainEntry:
      type: object
      description: |
        A supply-chain audit entry. Covers plugin ownership hijacks and update-channel abuse.
        This data is distinct from CVE-based `vulnerability` records.
        A plugin may have been compromised more than once; multiple entries are possible.
      properties:
        verdict:
          type: string
          enum: [malicious, suspicious, cleaned]
          description: Audit verdict
        audit_id:
          type: integer
          description: Audit identifier
        affected_versions:
          $ref: "#/components/schemas/AffectedVersions"
        baseline_version:
          type: string
          description: Last known clean version (human-readable label)
        head_version:
          type: string
          description: Latest plugin version at the time of the audit
        ioc_count:
          type: integer
          description: Number of Indicators of Compromise found
        closed_by_wporg:
          type: boolean
          description: Whether WordPress.org closed the plugin as a result of this audit
        c2_infrastructure:
          type: array
          items:
            $ref: "#/components/schemas/C2Infrastructure"
          description: C2 / IOC objects; may be empty
        signals:
          type: array
          items:
            $ref: "#/components/schemas/Signal"
          description: Unverified early-warning signals; may be empty
        wpbeacon_url:
          type: string
          format: uri
          description: Direct link to the full audit report
        published_at:
          type: string
          format: date
          description: Audit publish date (YYYY-MM-DD)

    # ---------------------------------------------------------------------------
    # Endpoint data objects
    # ---------------------------------------------------------------------------

    CoreData:
      type: object
      properties:
        core:
          type: string
          description: WordPress core version queried
          example: "5.8.2"
        link:
          type: [string, "null"]
          format: uri
          description: WordPress core changelog URL
        vulnerability:
          type: [array, "null"]
          description: List of vulnerabilities; `null` when none exist for this version
          items:
            $ref: "#/components/schemas/VulnerabilityCore"

    PluginData:
      type: object
      properties:
        name:
          type: [string, "null"]
          description: Plugin's human-readable name; `null` for unknown slugs
        plugin:
          type: string
          description: Plugin slug identifier
          example: "updraftplus"
        link:
          type: [string, "null"]
          format: uri
          description: Official WordPress.org plugin page URL; `null` for external plugins not on .org
        latest:
          type: [string, "null"]
          description: Unix timestamp of the last plugin update as a numeric string (e.g. `"1776963060"`); `null` if unknown
        closed:
          type: [integer, "null"]
          description: "`1` if the plugin is closed in the WordPress.org repository, `0` if open, `null` if unknown or not in .org"
        vulnerability:
          type: [array, "null"]
          description: List of vulnerability objects; `null` when none exist
          items:
            $ref: "#/components/schemas/VulnerabilityWP"
        supplychain:
          type: array
          description: |
            Supply-chain audit entries. This field is **omitted** when no approved audit exists.
            Multiple entries are possible if the plugin was compromised more than once.
          items:
            $ref: "#/components/schemas/SupplyChainEntry"

    ThemeData:
      type: object
      properties:
        name:
          type: [string, "null"]
          description: Theme's human-readable name; `null` for unknown slugs
        theme:
          type: string
          description: Theme slug identifier
          example: "ripple"
        link:
          type: [string, "null"]
          format: uri
          description: Official WordPress.org theme page URL; `null` for external themes
        latest:
          type: [string, "null"]
          description: Unix timestamp of the last theme update as a numeric string; sparsely populated — `null` for most themes because WordPress.org theme data rarely includes an update timestamp
        closed:
          type: [integer, "null"]
          description: "`1` if closed in the WordPress.org repository, `0` if open, `null` if unknown"
        vulnerability:
          type: [array, "null"]
          description: List of vulnerability objects; `null` when none exist
          items:
            $ref: "#/components/schemas/VulnerabilityWP"

    SoftwareData:
      type: object
      description: |
        Common response shape for all infrastructure endpoints.

        One additional property is present whose **name matches the software type**
        (`php`, `apache`, `nginx`, `mariadb`, `mysql`, `imagemagick`, `curl`, `memcached`, `redis`, `sqlite`)
        and whose value is the version string queried (e.g. `"php": "8.2"`).
      properties:
        name:
          type: string
          description: Human-readable software + version label, e.g. `PHP 8.2`
        status:
          type: [string, "null"]
          description: |
            Support lifecycle status.
            `m` = Maintained.
            `s` = Security support only.
            `d` = Deprecated / unmaintained.
            `eol` = End of life (legacy value).
          enum: [m, s, d, eol, null]
        date_start:
          type: string
          format: date
          description: General availability date (YYYY-MM-DD)
        date_end:
          type: string
          format: date
          description: EOL / end-of-support date (YYYY-MM-DD)
        vulnerability:
          type: [array, "null"]
          description: List of vulnerability objects; `null` when none exist for this version
          items:
            $ref: "#/components/schemas/VulnerabilitySoftware"
      additionalProperties: true

    # ---------------------------------------------------------------------------
    # Statistics endpoint
    # ---------------------------------------------------------------------------

    VulnCountsByType:
      type: object
      properties:
        core:
          type: integer
          description: Count for WordPress core
        plugins:
          type: integer
          description: Count for plugins
        themes:
          type: integer
          description: Count for themes

    Stats:
      type: object
      properties:
        products:
          type: object
          description: Count of distinct products (versions/slugs) that have at least one vulnerability
          properties:
            core:
              type: integer
              description: Distinct WordPress core versions affected
            plugins:
              type: integer
              description: Distinct plugins with vulnerabilities
            themes:
              type: integer
              description: Distinct themes with vulnerabilities
        vulnerabilities:
          type: object
          description: Vulnerability record counts broken down by data source and component type
          properties:
            cve:
              $ref: "#/components/schemas/VulnCountsByType"
            euvd:
              $ref: "#/components/schemas/VulnCountsByType"
            jvn:
              $ref: "#/components/schemas/VulnCountsByType"
            patchstack:
              $ref: "#/components/schemas/VulnCountsByType"
            wpscan:
              $ref: "#/components/schemas/VulnCountsByType"
            wordfence:
              $ref: "#/components/schemas/VulnCountsByType"
        core:
          type: integer
          description: Total vulnerability records affecting WordPress core
        plugins:
          type: integer
          description: Total vulnerability records affecting plugins
        themes:
          type: integer
          description: Total vulnerability records affecting themes
        php:
          type: integer
          description: Total vulnerability records for PHP
        apache:
          type: integer
          description: Total vulnerability records for Apache HTTPD
        nginx:
          type: integer
          description: Total vulnerability records for nginx
        mariadb:
          type: integer
          description: Total vulnerability records for MariaDB
        mysql:
          type: integer
          description: Total vulnerability records for MySQL
        imagemagick:
          type: integer
          description: Total vulnerability records for ImageMagick
        curl:
          type: integer
          description: Total vulnerability records for cURL
        memcached:
          type: integer
          description: Total vulnerability records for Memcached
        redis:
          type: integer
          description: Total vulnerability records for Redis
        sqlite:
          type: integer
          description: Total vulnerability records for SQLite

    Person:
      type: object
      properties:
        name:
          type: string
        url:
          type: string
          format: uri
        image:
          type: string
          format: uri
          description: Logo or avatar URL

    BehindTheProject:
      type: object
      properties:
        sponsors:
          type: array
          items:
            $ref: "#/components/schemas/Person"
        contributors:
          type: array
          items:
            $ref: "#/components/schemas/Person"

    # ---------------------------------------------------------------------------
    # Bulk endpoints
    # ---------------------------------------------------------------------------

    AllCoreEntry:
      type: object
      properties:
        version:
          type: string
          description: WordPress core version
        apiurl:
          type: string
          format: uri
          description: Direct API URL for this version
        updated:
          type: integer
          description: Last update timestamp (Unix)

    AllSlugEntry:
      type: object
      properties:
        slug:
          type: string
          description: Plugin or theme slug
        apiurl:
          type: string
          format: uri
          description: Direct API URL for this slug
        updated:
          type: integer
          description: Last update timestamp (Unix)
