audit-labs/audit-tools
A collection of scripts, queries, and other goodies you can use in an audit.
clone: git clone https://gitbay.org/audit-labs/audit-tools.git
v1.0.0: applications/github/collectors/security_alerts.py · raw
1"""
2Collect open secret-scanning and Dependabot alerts across the organization.
3
4Both require GitHub Advanced Security (or public repos) and admin access. If the
5org or token can't reach them, the collector returns an empty list with a
6warning instead of failing the run.
7"""
8
9import sys
10
11import requests
12
13from .api import paginate
14
15
16def secret_scanning(org, cfg):
17 return _org_alerts(org, cfg, "secret-scanning", _secret_row, "secret scanning")
18
19
20def dependabot_alerts(org, cfg):
21 return _org_alerts(org, cfg, "dependabot", _dependabot_row, "Dependabot")
22
23
24def _org_alerts(org, cfg, kind, row_fn, label):
25 try:
26 alerts = paginate(
27 f"https://api.github.com/orgs/{org}/{kind}/alerts", cfg, {"state": "open"}
28 )
29 except requests.HTTPError as e:
30 if e.response is not None and e.response.status_code in (403, 404):
31 print(
32 f"Warning: {label} alerts require GitHub Advanced Security and "
33 "org admin access -- skipping.",
34 file=sys.stderr,
35 )
36 return []
37 raise
38 return [row_fn(a) for a in alerts]
39
40
41def _secret_row(alert):
42 return {
43 "repo": alert.get("repository", {}).get("full_name", ""),
44 "secret_type": alert.get("secret_type_display_name")
45 or alert.get("secret_type", ""),
46 "state": alert.get("state", ""),
47 "created_at": alert.get("created_at", ""),
48 "html_url": alert.get("html_url", ""),
49 }
50
51
52def _dependabot_row(alert):
53 dependency = alert.get("dependency", {})
54 advisory = alert.get("security_advisory", {})
55 return {
56 "repo": alert.get("repository", {}).get("full_name", ""),
57 "package": dependency.get("package", {}).get("name", ""),
58 "severity": advisory.get("severity", ""),
59 "summary": advisory.get("summary", ""),
60 "state": alert.get("state", ""),
61 "created_at": alert.get("created_at", ""),
62 "html_url": alert.get("html_url", ""),
63 }