-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_script.py
110 lines (97 loc) · 4.06 KB
/
test_script.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import yaml
import json
import os
import requests
def parse_github_actions_workflow(file_path):
try:
with open(file_path, 'r') as file:
workflow = yaml.safe_load(file)
return workflow
except FileNotFoundError:
print(f"File not found: {file_path}")
return None
def load_advisory_database(path):
advisories = []
for root, dirs, files in os.walk(path):
for file in files:
if file.endswith('.json'):
file_path = os.path.join(root, file)
print(f"Reading advisory file: {file_path}")
with open(file_path, 'r', encoding='utf-8') as f:
advisory = json.load(f)
advisories.append(advisory)
print(f"Loaded {len(advisories)} advisories.")
if advisories:
print(f"Sample advisory: {advisories[0]}")
return advisories
def detect_known_vulnerabilities(workflow, advisories):
vulnerabilities_found = []
jobs = workflow.get('jobs', {})
for job_id, job in jobs.items():
steps = job.get('steps', [])
for step in steps:
if 'uses' in step:
action = step['uses']
print(f"Checking action: {action}")
for advisory in advisories:
if action in advisory.get('affected', []):
vulnerabilities_found.append((job_id, step, advisory))
return vulnerabilities_found
# List of deprecated actions
deprecated_actions = [
'actions/setup-python@v1',
'actions/checkout@v1'
]
def detect_deprecated_actions(workflow):
deprecated_actions_found = []
jobs = workflow.get('jobs', {})
for job_id, job in jobs.items():
steps = job.get('steps', [])
for step in steps:
if 'uses' in step:
action = step['uses']
if action in deprecated_actions:
deprecated_actions_found.append((job_id, step))
return deprecated_actions_found
def get_latest_action_version(action):
response = requests.get(f'https://api.github.com/repos/{action}/releases/latest')
if response.status_code == 200:
latest_version = response.json().get('tag_name')
return latest_version
return None
def compare_action_versions(workflow):
version_issues = []
jobs = workflow.get('jobs', {})
for job_id, job in jobs.items():
steps = job.get('steps', [])
for step in steps:
if 'uses' in step:
action = step['uses']
action_name, action_version = action.split('@')
latest_version = get_latest_action_version(action_name)
if latest_version and action_version != latest_version:
version_issues.append((job_id, step, latest_version))
return version_issues
def update_deprecated_actions_list():
response = requests.get('https://example.com/deprecated-actions-list')
if response.status_code == 200:
global deprecated_actions
deprecated_actions = response.json().get('deprecated_actions', deprecated_actions)
# Example usage with non-vulnerable workflow
workflow = parse_github_actions_workflow('sample_workflow.yml')
advisories = load_advisory_database('advisory-database/advisories')
vulnerabilities = detect_known_vulnerabilities(workflow, advisories)
print('Known vulnerabilities found:', vulnerabilities)
# Example usage with vulnerable workflow
vulnerable_workflow = parse_github_actions_workflow('vulnerable_workflow.yml')
vulnerabilities_in_vulnerable_workflow = detect_known_vulnerabilities(vulnerable_workflow, advisories)
print('Known vulnerabilities found in vulnerable workflow:', vulnerabilities_in_vulnerable_workflow)
# Detect deprecated actions
deprecated_actions_found = detect_deprecated_actions(workflow)
print('Deprecated actions found:', deprecated_actions_found)
# Compare action versions
version_issues = compare_action_versions(workflow)
print('Version issues found:', version_issues)
# Update deprecated actions list
update_deprecated_actions_list()
print('Updated deprecated actions list:', deprecated_actions)