{
  "openapi": "3.1.0",
  "servers": [
    {
      "url": "https://vulnerabilityhistory.org",
      "description": "The main source of API calls"
    },
    {
      "url": "https://cnd.vulnerabilityhistory.org",
      "description": "A cached source of data, but generally faster"
    }
  ],
  "info": {
    "title": "Vulnerability History Project RESTful API",
    "description": "This read-only API allows detailed access to the VHP data.\n\nThis documentation is a work-in-progress. If you want to contribute, see [our issue on GitHub](https://github.com/VulnerabilityHistoryProject/vulnerability-history/issues/956).\n",
    "version": "1.0.0",
    "license": {
      "name": "MIT",
      "url": "https://opensource.org/licenses/MIT"
    }
  },
  "security": [],
  "tags": [
    {
      "name": "vulnerabilities",
      "description": "Putting the V in VHP.\n\nThese API calls are related to getting information about vulnerabilities, the files they impacted, and the ways we have categorized them.\n"
    },
    {
      "name": "commits",
      "description": "Data for commits in the VHP database: fixes, vulnerability-contributing commits (VCCs), and any commit marked \"interesting\" by a curator.\n"
    },
    {
      "name": "developers",
      "description": "Data for developers who are authors of any commits in VHP.\n\nThese are **not** a comprehensive list of the developers in the project. Far from it. These are only the people  who are involved in fixing, contributing, or otherwise directly related to code authorship involving a vulnerability.\n"
    },
    {
      "name": "filepaths",
      "description": "Data on any filepath fixed for a vulnerability. A filepath is the name of a file combined with the directories its in, rooted at the top of the source code repository.\n\nThese are **not** a comprehensive list of files in the project. These are only files involved in a vulnerability in some way.\n\nA subset of these files are **known offenders**, which are files that have been fixed for at least one vulnerability.\n"
    },
    {
      "name": "tags",
      "description": "Data on the tags we use to categorize vulnerabilities.\n\nTags have a many-many relationship with vulnerabilities and are used for a variety of things. They are very general-purpose in nature.\n"
    },
    {
      "name": "projects",
      "description": "Data on the open source projects that these vulnerabilities originate from.\n"
    }
  ],
  "paths": {
    "/api/vulnerabilities": {
      "get": {
        "summary": "/api/vulnerabilities",
        "operationId": "listVulnerabilities",
        "tags": [
          "vulnerabilities"
        ],
        "description": "Returns a non-detailed list of all vulnerabilities",
        "parameters": [
          {
            "name": "short_descriptions",
            "description": "Should the descriptions be truncated? Mainly used in the VHP UI\n",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "limit",
            "description": "Limit the number of results\n",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "description": "Return a subset of the results, offset by this number\n",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "description": "VHP's primary key. Subject to change without notice.",
                        "type": "integer",
                        "format": "int32"
                      },
                      "cve": {
                        "description": "Unique, public identifier string",
                        "type": "string"
                      },
                      "announced": {
                        "description": "Parseable date format",
                        "type": "string"
                      },
                      "upvotes": {
                        "description": "A community-generated measurement of how interesting this vulnerability is.",
                        "type": "integer",
                        "format": "int32"
                      },
                      "nickname": {
                        "description": "A community-generated nickname, under 30 chars\n",
                        "type": "string"
                      },
                      "project_name": {
                        "description": "Title of the project this vulnerability is fromt\n",
                        "type": "string"
                      },
                      "subdomain": {
                        "description": "Shorthand name for the project, e.g. \"httpd\" instead of \"Apache HTTPD Web Server\"",
                        "type": "string"
                      },
                      "tag_json": {
                        "description": "List of tags associated with this vulnerability\n",
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "description": "VHP's primary key for the tag. Subject to change without notice. A current list of tag mappings can be found at /api/tags endpoint.\n",
                              "type": "integer",
                              "format": "int32"
                            },
                            "importance": {
                              "description": "A subjective number calculated to visually prioritize tags according how important we think they are to this vulnerability's story.\n",
                              "type": "number"
                            }
                          }
                        }
                      },
                      "description": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "id": 1426,
                    "cve": "CVE-2017-5060",
                    "announced": "2017-04-19T00:00:00.000Z",
                    "upvotes": 50,
                    "nickname": "Omni-Puny",
                    "project_name": "Chromium",
                    "subdomain": "chromium",
                    "tag_json": [
                      {
                        "id": 27,
                        "importance": 1
                      },
                      {
                        "id": 273,
                        "importance": 0.45
                      },
                      {
                        "id": 257,
                        "importance": 0
                      },
                      {
                        "id": 748,
                        "importance": 0
                      },
                      {
                        "id": 750,
                        "importance": 0
                      },
                      {
                        "id": 2,
                        "importance": 0
                      }
                    ],
                    "description": "URL spoofing in Omnibox. Certain Cyrillic characters look incredibly similar\nto standard Roman Alphabet characters, so much so that certain fonts don't\ndistinguish between the two. Registering a domain with \"punycode\" escape\nsequences causes these characters to display in the browser.\n"
                  },
                  {
                    "id": 1472,
                    "cve": "CVE-2017-5107",
                    "announced": "2017-01-27T00:00:00.000Z",
                    "upvotes": 50,
                    "nickname": "Convoluted",
                    "project_name": "Chromium",
                    "subdomain": "chromium",
                    "tag_json": [
                      {
                        "id": 62,
                        "importance": 1
                      },
                      {
                        "id": 274,
                        "importance": 0.45
                      },
                      {
                        "id": 257,
                        "importance": 0
                      },
                      {
                        "id": 3,
                        "importance": 0
                      },
                      {
                        "id": 2,
                        "importance": 0
                      },
                      {
                        "id": 750,
                        "importance": 0
                      }
                    ],
                    "description": "User information leak via SVG. By rendering a FeConvolveMatrix SVG filter over\na target iframe and timing its execution an attacking page can extract pixel\nvalues from a cross-origin page being iframe'd.\n"
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/vulnerabilities/{cve}": {
      "get": {
        "summary": "/api/vulnerabilites/{cve}",
        "operationId": "showVulnerability",
        "tags": [
          "vulnerabilities"
        ],
        "description": "Returns detailed information on a vulnerability with the specified ID\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/CVEParam"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "VHP's primary key. Subject to change without notice.",
                      "type": "integer",
                      "format": "int32"
                    },
                    "cve": {
                      "description": "Unique, public identifier string",
                      "type": "string"
                    },
                    "project_id": {
                      "description": "Project ID that this vulnerability falls under",
                      "type": "integer",
                      "format": "int32"
                    },
                    "announced": {
                      "description": "The date that this vulnerability was announced",
                      "type": "string"
                    },
                    "description": {
                      "description": "The handwritten description of the vulnerability",
                      "type": "string"
                    },
                    "short_desc": {
                      "type": "string"
                    },
                    "upvotes": {
                      "type": "integer",
                      "format": "int32"
                    },
                    "nickname": {
                      "type": "string"
                    },
                    "notes": {
                      "$ref": "#/components/schemas/NotesObject"
                    }
                  }
                },
                "example": {
                  "id": 2427,
                  "cve": "CVE-2017-5638",
                  "project_id": 6,
                  "announced": "2017-03-02T00:00:00.000Z",
                  "description": "Apache Struts utilizes multipart parsers to handle HTTP POST requests,\nand there are two types available, Jakarta and Pell. The Jakarta\nMultiparser was the one that had the vulnerability, and it generates an\nexception when parsing the Content-Type. It raises this exception and\nincludes the invalid data in the error message, and does this by\nparsing the input and treating the parsed result as an OGNL expression.\nThis is potential for remote code execution.\n",
                  "short_desc": "Apache Struts utilizes multipart parsers to handle HTTP POST requests, and there are \ntwo types available, Jakarta and Pell",
                  "upvotes": 0,
                  "nickname": "The Equifax Breach"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/vulnerabilities/{cve}/events": {
      "get": {
        "summary": "/api/vulnerabilities/{cve}/events",
        "operationId": "listVulnerabilityEvents",
        "tags": [
          "vulnerabilities"
        ],
        "description": "Return all events for the specified vulnerability",
        "parameters": [
          {
            "$ref": "#/components/parameters/CVEParam"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "integer",
                        "format": "int32"
                      },
                      "title": {
                        "type": "string"
                      },
                      "description": {
                        "type": "string"
                      },
                      "date": {
                        "type": "string"
                      },
                      "event_type": {
                        "description": "Internal code for grouping events",
                        "type": "string"
                      },
                      "color": {
                        "type": "string"
                      },
                      "icon": {
                        "description": "VHP icon CSS class for what icon to use",
                        "type": "string"
                      },
                      "start_hidden": {
                        "description": "Whether or not to start hidden on the page",
                        "type": "boolean"
                      },
                      "notes": {
                        "$ref": "#/components/schemas/NotesObject"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "id": 2438,
                    "title": "Vulnerability Announced for CVE-2017-5638",
                    "description": "The vulnerability was officially announced by the development team.",
                    "date": "2017-03-02T00:00:00.000Z",
                    "event_type": "announced",
                    "color": "#9DD5D5",
                    "icon": "bug_report",
                    "notes": {},
                    "start_hidden": false
                  },
                  {
                    "id": 4378,
                    "title": "Fix for CVE-2017-5638: Uses default error key if specified key doesn't exist",
                    "description": "Our curators found that this vulnerability was fixed by this commit.\n\nThe commit had  lines changed.\n\n  * 9 insertions, and\n  * 12 deletions\n\nHere was the commit message.\n<blockquote>\nUses default error key if specified key doesn't exist\n</blockquote>\n\n[Learn more about this commit](/commits/6b8272ce47160036ed120a48345d9aa884477228)",
                    "date": "2017-03-06T10:17:38.000Z",
                    "event_type": "fix",
                    "color": "#9FE69F",
                    "icon": "lock",
                    "notes": {},
                    "start_hidden": false
                  },
                  {
                    "id": 6995,
                    "title": "Vulnerability-contributing commit for CVE-2017-5638: WW-4636 - File upload error message always in default language",
                    "description": "A **vulnerability-contributing commit** (VCC) occurred here. This means that a curator identified this commit as (one of) the possible origins of this vulnerability.\n\nThis VCC had:\n\n  * 22 insertions, and\n  * 175 deletions\n\nThus it had a total raw churn of .\n\nHere was the commit message.\n<blockquote>\n:description:\n</blockquote>\n\n[Learn more about this commit](/commits/33ac7ac49aabfcf792d38fa44d271a93433ffe56)\n\n[Learn more about vulnerability-contributing commits.](/articles/vccs.md)",
                    "date": "2016-10-15T12:25:14.000Z",
                    "event_type": "vcc",
                    "color": "#ED6049",
                    "icon": "report_problem",
                    "notes": {},
                    "start_hidden": false
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/commits": {
      "get": {
        "summary": "/api/commits",
        "operationId": "listCommits",
        "tags": [
          "commits"
        ],
        "description": "Returns a non-detailed list of all commits in the database. These are VCCs, fixes, and interesting commits.\n",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "description": "The primary key of the commit. Currently null for unknown reasons\n",
                        "type": "integer",
                        "format": "int32"
                      },
                      "commit_hash": {
                        "description": "The unique hash of the commit",
                        "type": "string"
                      },
                      "email": {
                        "description": "The email address of the developer responsible for the commit",
                        "type": "string"
                      },
                      "date_created": {
                        "description": "Parseable date format",
                        "type": "string"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "commit_hash": "639e20992a66d7a42fb59c974db91c8a0f730a1e",
                    "email": "foo@example.com",
                    "date_created": "2011-04-01T11:36:54.000Z",
                    "id": 0
                  },
                  {
                    "commit_hash": "b7b5c63a932f6c1ea05f9b65ad9054247bb5af57",
                    "email": "foo@example.com",
                    "date_created": "2011-04-01T10:49:43.000Z",
                    "id": 1
                  },
                  {
                    "commit_hash": "eae54419c6e196933998f63358367040edaa4a8c",
                    "email": "foo@example.com",
                    "date_created": "2006-07-20T12:50:34.000Z",
                    "id": 2
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/commits/{sha}": {
      "get": {
        "summary": "/api/commits/{sha}",
        "operationId": "showCommit",
        "tags": [
          "commits"
        ],
        "description": "Author of the given commit",
        "parameters": [
          {
            "$ref": "#/components/parameters/GitSHAParam"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "integer",
                      "format": "int32"
                    },
                    "commit_hash": {
                      "type": "string"
                    },
                    "project_id": {
                      "type": "integer",
                      "format": "int32"
                    },
                    "author_id": {
                      "type": "integer",
                      "format": "int32"
                    },
                    "message": {
                      "type": "string"
                    },
                    "date_created": {
                      "type": "string"
                    },
                    "notes": {
                      "$ref": "#/components/schemas/NotesObject"
                    }
                  }
                },
                "example": {
                  "id": 1,
                  "commit_hash": "639e20992a66d7a42fb59c974db91c8a0f730a1e",
                  "project_id": 8,
                  "author_id": 1,
                  "message": "Add additional configuration options to the DIGEST authenticator\nThis is the fix for CVE-2011-1184\n\ngit-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1087655 13f79535-47bb-0310-9956-ffa450edef68",
                  "date_created": "2011-04-01T11:36:54.000Z",
                  "notes": {
                    "date": "2011-04-01 11:36:54 UTC",
                    "email": "foo@example.com",
                    "author": "Example Person",
                    "message": "Add additional configuration options to the DIGEST authenticator\nThis is the fix for CVE-2011-1184\n\ngit-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1087655 13f79535-47bb-0310-9956-ffa450edef68",
                    "deletions": 1068,
                    "filepaths": {
                      "webapps/docs/changelog.xml": {
                        "deletions": 4,
                        "insertions": 0
                      },
                      "webapps/docs/config/valve.xml": {
                        "deletions": 34,
                        "insertions": 0
                      },
                      "java/org/apache/catalina/realm/RealmBase.java": {
                        "deletions": 7,
                        "insertions": 2
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/commits/{sha}/developer": {
      "get": {
        "summary": "/api/commits/{sha}/developer",
        "operationId": "showCommitAuthor",
        "tags": [
          "commits",
          "developers"
        ],
        "description": "Author of the given commit",
        "parameters": [
          {
            "$ref": "#/components/parameters/GitSHAParam"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Internal primary key. Subject to change.",
                      "type": "integer",
                      "format": "int32"
                    },
                    "email": {
                      "type": "string"
                    },
                    "nickname": {
                      "$ref": "#/components/schemas/Nickname"
                    },
                    "notes": {
                      "$ref": "#/components/schemas/NotesObject"
                    }
                  }
                },
                "example": {
                  "id": 88,
                  "email": "foo@example.com",
                  "nickname": "Warren the Whale",
                  "notes": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/developers": {
      "get": {
        "summary": "/api/developers",
        "operationId": "listDevelopers",
        "tags": [
          "developers"
        ],
        "description": "Return a list of the developers who are authors of vulnerability-contributing commits, or fix commits.\n",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "integer",
                        "format": "int32"
                      },
                      "email": {
                        "type": "string"
                      },
                      "nickname": {
                        "$ref": "#/components/schemas/Nickname"
                      },
                      "notes": {
                        "$ref": "#/components/schemas/NotesObject"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "id": 1,
                    "email": "foo@example.org",
                    "nickname": "Pauline the Wren",
                    "notes": {}
                  },
                  {
                    "id": 2,
                    "email": "foo2@example.org",
                    "nickname": "Harry the Sparrow",
                    "notes": {}
                  },
                  {
                    "id": 3,
                    "email": "foo3@example.org",
                    "nickname": "Agnes the Bear",
                    "notes": {}
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/developers/{developer_id}/commits": {
      "get": {
        "summary": "/api/developers/{developer_id}/commits",
        "operationId": "listDeveloperCommits",
        "tags": [
          "developers",
          "commits"
        ],
        "description": "List the commits for a developer\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/DeveloperIDParam"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "commit_hash": {
                        "type": "string"
                      },
                      "message": {
                        "type": "string"
                      },
                      "date_created": {
                        "type": "string"
                      },
                      "churn": {
                        "type": "integer",
                        "format": "nullable"
                      },
                      "id": {
                        "type": "integer",
                        "format": "nullable"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "commit_hash": "639e20992a66d7a42fb59c974db91c8a0f730a1e",
                    "message": "Add additional configuration options to the DIGEST authenticator\nThis is the fix for CVE-2011-1184\n\ngit-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1087655 13f79535-47bb-0310-9956-ffa450edef68",
                    "date_created": "2011-04-01T11:36:54.000Z",
                    "churn": 200,
                    "id": 1
                  },
                  {
                    "commit_hash": "b7b5c63a932f6c1ea05f9b65ad9054247bb5af57",
                    "message": "Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=12428\nAdd optional support for preemptive authentication on a per context basis\nBased on a patch suggested by Werner Donn\nThis includes the fix for CVE-2011-1183\n\ngit-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1087643 13f79535-47bb-0310-9956-ffa450edef68",
                    "date_created": "2011-04-01T10:49:43.000Z",
                    "churn": 100,
                    "id": 2
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/filepaths": {
      "get": {
        "summary": "/api/filepaths",
        "operationId": "listFilepaths",
        "tags": [
          "filepaths"
        ],
        "description": "List all files touched by any commit in the database",
        "parameters": [
          {
            "name": "offenders",
            "description": "Only return \"known offenders\", which are files that are part of at least one vulnerability fix\n",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "integer",
                        "format": "int32"
                      },
                      "filepath": {
                        "type": "string"
                      },
                      "slug": {
                        "$ref": "#/components/schemas/FilepathSlug"
                      },
                      "dir": {
                        "type": "string"
                      },
                      "is_code": {
                        "type": "boolean"
                      },
                      "note": {
                        "type": "string"
                      },
                      "project_id": {
                        "type": "integer",
                        "format": "int32"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "id": 1,
                    "filepath": "java/org/apache/catalina/authenticator/DigestAuthenticator.java",
                    "slug": "tomcat-java-org-apache-catalina-authenticator-digestauthenticator-java",
                    "dir": "java/org/apache/catalina/authenticator/",
                    "is_code": true,
                    "note": "",
                    "project_id": 8
                  },
                  {
                    "id": 2,
                    "filepath": "java/org/apache/catalina/authenticator/LocalStrings.properties",
                    "slug": "tomcat-java-org-apache-catalina-authenticator-localstrings-properties",
                    "dir": "java/org/apache/catalina/authenticator/",
                    "is_code": true,
                    "note": "",
                    "project_id": 8
                  },
                  {
                    "id": 3,
                    "filepath": "java/org/apache/catalina/authenticator/mbeans-descriptors.xml",
                    "slug": "tomcat-java-org-apache-catalina-authenticator-mbeans-descriptors-xml",
                    "dir": "java/org/apache/catalina/authenticator/",
                    "is_code": true,
                    "note": "",
                    "project_id": 8
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/filepaths/{filepath_id}/developers": {
      "get": {
        "summary": "/api/filepaths/{filepath_id}/developers",
        "operationId": "listFilepathDevelopers",
        "tags": [
          "filepaths",
          "developers"
        ],
        "description": "Returns a list of authors to the commits of the file. Only includes authors of commits in VHP.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/FilepathParam"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                },
                "example": null
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/filepaths/{filepath_id}/commits": {
      "get": {
        "summary": "/api/filepaths/{filepath_id}/commits",
        "operationId": "listFilepathCommits",
        "tags": [
          "filepaths",
          "commits"
        ],
        "description": "Returns a list of key commits to the file. Only includes VCCs, fixes, and interesting commits.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/FilepathParam"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                },
                "example": null
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/filepaths/{filepath_id}/vulnerabilities": {
      "get": {
        "summary": "/api/filepaths/{filepath_id}/vulnerabilities",
        "operationId": "listFilepathVulnerabilities",
        "tags": [
          "filepaths",
          "vulnerabilities"
        ],
        "description": "Returns a list of vulnerabilities fixed in this file.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/FilepathParam"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                },
                "example": null
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/tags": {
      "get": {
        "summary": "/api/tags",
        "operationId": "listTags",
        "tags": [
          "tags"
        ],
        "description": "List all tags in the database",
        "parameters": [
          {
            "name": "map",
            "description": "Change the return format from array to dictionary\n",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "integer",
                        "format": "int32"
                      },
                      "name": {
                        "type": "string"
                      },
                      "shortname": {
                        "type": "string"
                      },
                      "description": {
                        "type": "string"
                      },
                      "color": {
                        "type": "string"
                      },
                      "icon": {
                        "type": "string"
                      },
                      "short_desc": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "id": 373,
                    "name": "Chromium subsystem: autofill",
                    "shortname": "subsystem-chromium-autofill",
                    "description": "What subsystem was this in?\n\nMost software project don't make a definitive list of their subsystems, so the subsystems tags are our curators' best guess at what part(s) of the system a vulnerability was in. Often, curators will look at file paths primarily, but may also look at bug reports or commit messages to make this determination.\n\nAs part of the editorial process, we periodically combine subsystems together. If you see two subsystems that ought to be combined, then do a pull request against the vulnerabilities involved! We welcome that kind of edit.\n\n",
                    "color": "#d9e1ed",
                    "icon": "cogs",
                    "short_desc": "What subsystem was this in?\n\nMost software project don't make a definitive list of their subsystems, so the subsystems tags are our curators' best guess at what part(s) of the system a vulnerability was in. Often, curators will look at f..."
                  },
                  {
                    "id": 3,
                    "name": "Lesson: Code Refactors",
                    "shortname": "refactors",
                    "description": "The vulnerable code had a lot of refactors in its lifetime.\n\nA vulnerability with this tag has had at least 10 separate weeks where at least one commit mentioned the word \"refactoring\" in the commit message.\n\nRefactoring is generally considered to be a good practice to be doing regularly. It indicates regular maintenance and attention. While refactoring doesn't yield new features or fix defects, it greatly reduces the cost of them.",
                    "color": "#009696",
                    "icon": "branch",
                    "short_desc": "The vulnerable code had a lot of refactors in its lifetime.\n\nA vulnerability with this tag has had at least 10 separate weeks where at least one commit mentioned the word \"refactoring\" in the commit message."
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/tags/{tag_id}": {
      "get": {
        "summary": "/api/tags/{tag_id}",
        "operationId": "showTag",
        "tags": [
          "tags"
        ],
        "description": "Show details of a particular tag, including vulnerabilities that this\ntag has been applied to.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/TagIDParam"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": null
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/tags/overlaps/array": {
      "get": {
        "summary": "/api/tags/overlaps/array",
        "operationId": "Overlaps",
        "tags": [
          "overlaps"
        ],
        "description": "Returns the vulnerabilities in common between the tags provided in decending\norder according to upvotes\n",
        "parameters": [
          {
            "name": "overlaps",
            "description": "The tags to find the overlaps of.\n",
            "in": "query",
            "required": true,
            "schema": {
              "type": "array of tag shortnames",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "nodes": {
                      "$ref": "#/components/schemas/sankeyNodes"
                    },
                    "links": {
                      "$ref": "#/components/schemas/sankeyLinks"
                    }
                  }
                },
                "example": null
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/insights/tag-trends": {
      "get": {
        "summary": "/api/insights/tag-trends",
        "operationId": "TagTrends",
        "tags": [
          "tags"
        ],
        "description": "Returns a set of nodes and links based off of the families passed in. The nodes are the tags, and the links are the number of vulnerabilities that have both tags. The nodes are sized by the number of vulnerabilities that have that tag. The links are sized by the number of vulnerabilities that have both tags.\n",
        "parameters": [
          {
            "name": "family_list",
            "description": "A comma-separated string of tag families to common vulnerabilities with those tag families.\n",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "nodes": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "links": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "source": {
                          "type": "string"
                        },
                        "target": {
                          "type": "integer"
                        },
                        "value": {
                          "type": "integer",
                          "format": "int32"
                        }
                      }
                    }
                  }
                },
                "example": [
                  {
                    "nodes": {
                      "name": "project-xx"
                    },
                    "links": {
                      "source": "project-xx",
                      "target": "language-d",
                      "value": 1
                    },
                    "trend_json": "{\"nodes\": [{ \"name\": \"project-xx\" },{ \"name\": \"bounty\" },{ \"name\": \"language-d\" },{ \"name\": \"lifetime-10\" }],\"links\": [{ \"source\": \"project-xx\", \"target\":\"language-d\", \"value\": 1 },{ \"source\": \"bounty\", \"target\": \"lifetime-10\", \"value\": 2 }]}"
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/corpus": {
      "get": {
        "summary": "/api/corpus",
        "operationId": "corpus",
        "tags": [
          "vulnerabilities"
        ],
        "description": "Returns a list of vulnerabilities filtered by having written langauge in the `description` and `mistakes` fields. Also includes tag data too. Use for research purposes.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "integer",
                        "format": "int32"
                      },
                      "cve": {
                        "type": "string"
                      },
                      "project_name": {
                        "type": "string"
                      },
                      "description": {
                        "type": "string"
                      },
                      "mistakes": {
                        "type": "string"
                      },
                      "tag_list": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "integer",
                              "format": "int32"
                            },
                            "tag": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": [
                  {
                    "id": 1989,
                    "cve": "CVE-2014-0231",
                    "project_name": "httpd",
                    "description": "A CGI (Common Gateway Interface) is a protocol used by web servers that runs command-line interface scripts in response to client requests. Apache HTTP Server has a module \"mod_cgid\" which is responsible for running CGI scripts.\nCVE-2014-0231 was a vulnerability in Apache HTTP Server's mod_cgid module where users could create a denial of service attack by causing the process which ran these scripts to hang indefinitely. mod_cgid did not have any timeout feature. If an attacker found a request that caused one of a server's CGI scripts hosted in mod_cgid to halt, this would deny service to other users of the server's CGI scripts.",
                    "mistakes": "This is a particularly interesting case of finding a way to make the system fail gracefully. The issue - the process responsible for running CGI scripts hanging indefinitely - is an issue that occurs when a script fails to handle certain inputs properly. The failure to anticipate and handle this special case is what left open the opportunity for a DOS attack on the system.\nLack of unit testing is probably the most clear mistake here. The unit test suite for the project as a whole is relatively sparse, and an issue like this (a rare failure case) can be difficult to anticipate without thorough testing.",
                    "tag_list": [
                      {
                        "id": 2,
                        "tag": "cooks"
                      }
                    ]
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    },
    "/api/projects": {
      "get": {
        "summary": "/api/projects",
        "operationId": "listProjects",
        "tags": [
          "projects"
        ],
        "description": "Returns the list of projects\n",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "integer",
                        "format": "int32"
                      },
                      "name": {
                        "type": "string"
                      },
                      "fullname": {
                        "type": "string"
                      },
                      "subdomain": {
                        "$ref": "#/components/schemas/ProjectSubdomain"
                      },
                      "fg_color": {
                        "type": "string"
                      },
                      "bg_color": {
                        "type": "string"
                      },
                      "project_url": {
                        "type": "string"
                      },
                      "logo": {
                        "type": "string"
                      },
                      "git_commit_url_prefix": {
                        "type": "string"
                      },
                      "github_search_url_prefix": {
                        "type": "string"
                      },
                      "github_edit_cve_url_prefix": {
                        "type": "string"
                      },
                      "description": {
                        "type": "string"
                      },
                      "vulnerabilities_description": {
                        "type": "string"
                      },
                      "developers_description": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "id": 1,
                    "name": "Chromium",
                    "fullname": "Chromium Browser",
                    "subdomain": "chromium",
                    "fg_color": "#d9e1ed",
                    "bg_color": "#4587f4",
                    "project_url": "https://www.chromium.org/Home",
                    "logo": "chromium.png",
                    "git_commit_url_prefix": "https://github.com/chromium/chromium/commit/",
                    "github_search_url_prefix": "https://github.com/chromium/chromium/search?utf8=✓&q=",
                    "github_edit_cve_url_prefix": "https://github.com/andymeneely/chromium-vulnerabilities/edit/dev/cves/",
                    "description": "The Chromium Browser project is the open source project behind Google Chrome.\n\nThroughout the VHP, when we refer to Chromium, we are referring to the Browser. This study does not include ChromeOS.\n",
                    "vulnerabilities_description": "These vulnerabilities have been reported and confirmed\nby the Chromium team. Chromium typically releases this data on their [release\nblog](https://chromereleases.googleblog.com/).\n",
                    "developers_description": "The following is a list of developers who are involved\nin code that was found to be vulnerable. Specifically, developers end up here\nif they were the author of a commit to code that was, at some point in time, fixed\nfor a vulnerability. Note that this is NOT a comprehensive list, as Chromium has\n3,000+ contributors\n"
                  },
                  {
                    "id": 2,
                    "name": "Django",
                    "fullname": "Django",
                    "subdomain": "django",
                    "fg_color": "#20AA76",
                    "bg_color": "#20AA76",
                    "project_url": "https://www.djangoproject.com/",
                    "logo": "django.png",
                    "git_commit_url_prefix": "https://github.com/django/django/commit/",
                    "github_search_url_prefix": "https://github.com/django/django/search?utf8=✓&q=",
                    "github_edit_cve_url_prefix": "https://github.com/VulnerabilityHistoryProject/django-vulnerabilities/edit/dev/cves/",
                    "description": "\"Django makes it easier to build better Web apps more quickly and\nwith less code.\" -https://www.djangoproject.com/\n",
                    "vulnerabilities_description": "These vulnerabilities are reported by the Django development\nteam [on their news feed](https://www.djangoproject.com/weblog/)\n",
                    "developers_description": "The following is a list of developers who are involved\nin code that was found to be vulnerable. Specifically, developers end up here\nif they were the author of a commit to code that was, at some point in time, fixed\nfor a vulnerability. Note that this is NOT a comprehensive list.\n"
                  },
                  {
                    "id": 3,
                    "name": "FFmpeg",
                    "fullname": "FFmpeg",
                    "subdomain": "ffmpeg",
                    "fg_color": "#449D44",
                    "bg_color": "#449D44",
                    "project_url": "https://ffmpeg.org/",
                    "logo": "ffmpeg.png",
                    "git_commit_url_prefix": "https://github.com/FFmpeg/FFmpeg/commit/",
                    "github_search_url_prefix": "https://github.com/FFmpeg/FFmpeg/search?utf8=✓&q=",
                    "github_edit_cve_url_prefix": "https://github.com/VulnerabilityHistoryProject/ffmpeg-vulnerabilities/edit/dev/cves/",
                    "description": "\"FFmpeg is the leading multimedia framework, able to decode, encode,\ntranscode, mux, demux, stream, filter and play pretty much anything that humans\nand machines have created. It supports the most obscure ancient formats up to\nthe cutting edge. No matter if they were designed by some standards committee,\nthe community or a corporation. It is also highly portable: FFmpeg compiles, runs,\nand passes our testing infrastructure FATE across Linux, Mac OS X, Microsoft Windows,\nthe BSDs, Solaris, etc. under a wide variety of build environments, machine architectures,\nand configurations.\" -https://ffmpeg.org/\n",
                    "vulnerabilities_description": "These vulnerabilities are reported by the FFmpeg development\nteam [on their site](https://ffmpeg.org/security.html)\n",
                    "developers_description": "The following is a list of developers who are involved\nin code that was found to be vulnerable. Specifically, developers end up here\nif they were the author of a commit to code that was, at some point in time, fixed\nfor a vulnerability. Note that this is NOT a comprehensive list.\n"
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400Malformed"
          },
          "500": {
            "$ref": "#/components/responses/500Internal"
          }
        }
      }
    }
  },
  "components": {
    "responses": {
      "400Malformed": {
        "description": "Malformed request."
      },
      "500Internal": {
        "description": "Internal error. Please report these on our\n[issue tracker](https://github.com/VulnerabilityHistoryProject/vulnerability-history/issues).\n",
        "content": {}
      }
    },
    "schemas": {
      "Nickname": {
        "type": "string",
        "description": "Obfuscated developer email address.\n\nIn VHP, we avoid using developer names and email addresses. We don't want to assign blame to the developers publicly; instead, we deterministically assign an animal name to their email address.\n\nOur algorithm for assigning nicknames is relatively straightforward and can be found here: https://github.com/VulnerabilityHistoryProject/vulnerability-history/tree/master/lib/nicknames\n\nEssentially, we compute the SHA-256 hash of the email address. The first half of the SHA is modded by the length of 902 common names to get the name. The second half of the SHA is modded by a length of 500 animal names. With 902x500 combinations, this makes 451,000 possible combinations of animals.\n"
      },
      "FilepathSlug": {
        "type": "string",
        "description": "A URL-friendly conversion of a filepath to serves a unique identifier.\n\nWe use ActiveSupport's `parameterize` for this, which replaces most non-word characters with hyphens.\n\nFor example, for project `foo` and file `mydir/myfile.c`, it's `foo-mydir-myfile-c`\n\nThe filepath slug is guaranteed to be globally unique across all VHP data.\n"
      },
      "ProjectSubdomain": {
        "type": "string",
        "description": "The URL-friendly unique identifier for a project.\n\nThis is called **subdomain** for historical reasons. A more apt name might be \"slug\".\n"
      },
      "NotesObject": {
        "type": "object",
        "description": "A freeform document (i.e. JSON) of any extra information we have on this record. Sometimes we don't have an exact place in our schema to place things, so we err on the side of retaining records and record them here.\n\nImportantly, the schema of this object is subject to change. We try to keep it consistent, but all curators have a mind of their own.\n"
      },
      "sankeyNodes": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            }
          }
        }
      },
      "sankeyLinks": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "source": {
              "type": "string"
            },
            "target": {
              "type": "string"
            },
            "value": {
              "type": "integer"
            }
          }
        }
      }
    },
    "parameters": {
      "CVEParam": {
        "name": "cve",
        "in": "path",
        "description": "The unique CVE identifier of the vulnerability",
        "schema": {
          "type": "string",
          "format": "Common Vulnerabilities Enumeration",
          "pattern": "^CVE\\-\\d{4}\\-\\d+$"
        },
        "example": "CVE-2017-5638"
      },
      "GitSHAParam": {
        "name": "sha",
        "in": "path",
        "description": "The unique SHA hash string of a git commit",
        "schema": {
          "type": "string",
          "format": "Git SHA-256",
          "pattern": "^[\\da-f]{40}$",
          "example": "011a54315e46acdf288003566b8570440f5ac985"
        }
      },
      "DeveloperIDParam": {
        "name": "developer_id",
        "in": "path",
        "description": "The internal primary key of the developer. Subject to change without\nnotice.\n",
        "schema": {
          "type": "integer",
          "format": "int32"
        }
      },
      "FilepathParam": {
        "name": "filepath_id",
        "in": "path",
        "description": "The url-friendly identifier of a filepath.\n",
        "schema": {
          "type": "string"
        }
      },
      "TagIDParam": {
        "name": "tag_id",
        "in": "path",
        "description": "The url-friendly slug of a tag\n",
        "schema": {
          "type": "string"
        }
      }
    }
  }
}