Github Vulnerability
Import findings from Github vulnerability scan (GraphQL Query): https://help.github.com/en/github/managing-security-vulnerabilities
Currently the parser is able to manage only RepositoryVulnerabilityAlert
object.
The parser has some kind of search feature which detect the data in the report.
Here is the mandatory objects and attributes:
vulnerabilityAlerts (RepositoryVulnerabilityAlert object)
+ id
+ createdAt (optional)
+ vulnerableManifestPath
+ state (optional)
+ securityVulnerability (SecurityVulnerability object)
+ severity (CRITICAL/HIGH/LOW/MODERATE)
+ package (optional)
+ name (optional)
+ advisory (SecurityAdvisory object)
+ description
+ summary
+ description
+ identifiers
+ value
+ references (optional)
+ url (optional)
+ cvss (optional)
+ score (optional)
+ vectorString (optional)
+ cwes (optional)
References:
- https://docs.github.com/en/graphql/reference/objects#repositoryvulnerabilityalert
- https://docs.github.com/en/graphql/reference/objects#securityvulnerability
Github v4 graphql query to fetch data, with extended information like the repository name and url, alert number.
query getVulnerabilitiesByRepoAndOwner($name: String!, $owner: String!) {
repository(name: $name, owner: $owner) {
vulnerabilityAlerts(first: 100, after:AFTER, states: OPEN) {
nodes {
id
createdAt
vulnerableManifestPath
securityVulnerability {
severity
updatedAt
package {
name
ecosystem
}
firstPatchedVersion {
identifier
}
vulnerableVersionRange
advisory {
description
summary
identifiers {
value
type
}
references {
url
}
cvss {
vectorString
}
}
}
vulnerableManifestPath
state
vulnerableManifestFilename
vulnerableRequirements
number
dependencyScope
dismissComment
dismissReason
dismissedAt
fixedAt
}
totalCount
pageInfo {
endCursor
hasNextPage
hasPreviousPage
startCursor
}
}
nameWithOwner
url
}
}
Another example of Python script, to have a function that queries any repository, with support for paginated responses and get all findings. Has a filter to only get OPEN dependabot alerts but this can be removed in the GraphQL query
def make_query(after_cursor=None):
return """
query getVulnerabilitiesByRepoAndOwner($name: String!, $owner: String!) {
repository(name: $name, owner: $owner) {
vulnerabilityAlerts(first: 100, after:AFTER, states: OPEN) {
nodes {
id
createdAt
vulnerableManifestPath
securityVulnerability {
severity
updatedAt
package {
name
ecosystem
}
firstPatchedVersion {
identifier
}
vulnerableVersionRange
advisory {
description
summary
identifiers {
value
type
}
references {
url
}
cvss {
vectorString
}
}
}
vulnerableManifestPath
state
vulnerableManifestFilename
vulnerableRequirements
number
dependencyScope
dismissComment
dismissReason
dismissedAt
fixedAt
}
totalCount
pageInfo {
endCursor
hasNextPage
hasPreviousPage
startCursor
}
}
nameWithOwner
url
}
}
""".replace(
"AFTER", '"{}"'.format(after_cursor) if after_cursor else "null"
)
# accumulates all pages data into a single object
def get_dependabot_alerts_repository(repo, owner):
keep_fetching = True
after_cursor = None
output_result = {"data": {"repository": {"vulnerabilityAlerts": {"nodes": []}}}}
while keep_fetching:
headers = {"Authorization": AUTH_TOKEN}
request = requests.post(
url="https://api.github.com/graphql",
json={
"operationName": "getVulnerabilitiesByRepoAndOwner",
"query": make_query(after_cursor),
"variables": {"name": repo, "owner": owner},
},
headers=headers,
)
result = request.json()
output_result["data"]["repository"]["name"] = result["data"]["repository"][
"name"
]
output_result["data"]["repository"]["url"] = result["data"]["repository"]["url"]
if result["data"]["repository"]["vulnerabilityAlerts"]["totalCount"] == 0:
return None
output_result["data"]["repository"]["vulnerabilityAlerts"]["nodes"] += result[
"data"
]["repository"]["vulnerabilityAlerts"]["nodes"]
keep_fetching = result["data"]["repository"]["vulnerabilityAlerts"]["pageInfo"][
"hasNextPage"
]
after_cursor = result["data"]["repository"]["vulnerabilityAlerts"]["pageInfo"][
"endCursor"
]
print(
"Fetched {} alerts for repo {}/{}".format(
result["data"]["repository"]["vulnerabilityAlerts"]["totalCount"],
owner,
repo,
)
)
return json.dumps(output_result, indent=2)
Sample Scan Data
Sample Github Vulnerability scans can be found here.
Last modified January 19, 2024: :sparkles: advance parser docs to provide sample scan data (#9347) (f1e435e59)