-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathghas-for-ado-decorator-post.yml
162 lines (137 loc) · 9.98 KB
/
ghas-for-ado-decorator-post.yml
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# Use these variables in the main pipeline to control the values of the decorator
# variables:
# system.debugContext: true
# - When set to true, the pipeline will run in debug mode. This will display additional information in the logs.
# advancedsecurity.enable: true
# - When set to true, the pipeline will run the Advanced Security analysis.
# advancedsecurity.skip: true
# - When set to true, the pipeline will skip the Advanced Security analysis.
# advancedsecurity.dependencies.failoncritical.skip: true
# - When set to true, the pipeline will skip the Advanced Security Dependency Review (Fail on Critical).
# advancedsecurity.codescanning.failoncritical.skip: true
# - When set to true, the pipeline will skip the Advanced Security Code Scanning (Fail on Critical).
# advancedsecurity.codeql.autobuild.enable: true
# - When set to true, the pipeline will run the Advanced Security AutoBuild.
# https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services
# in(variables['Build.Reason'], 'Manual', 'IndividualCI', 'BatchedCI', 'PullRequest')
# Build.SourceBranch
# contains(variables['Build.DefinitionName'], 'CI')
# Build.DefinitionName
# System.TeamProject - The name of the project that contains this build.
# System.StageName - A string-based identifier for a stage, typically used for expressing dependencies and accessing output variables.
# https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/advanced-security-codeql-autobuild-v1
# https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/advanced-security-dependency-scanning-v1
# https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/advanced-security-codeql-analyze-v1
steps:
- ${{ if eq(variables['system.debugContext'], 'true') }}:
- task: CmdLine@2
displayName: '(injected) Run POST debug script'
#condition: and(succeeded(), eq(variables['system.debugContext'], 'true'))
inputs:
script: |
echo "advancedsecurity.enable: ${{ variables['advancedsecurity.enable'] }}"
echo "advancedsecurity.skip: ${{ variables['advancedsecurity.skip'] }}"
echo "advancedsecurity.codeql.autobuild.enable: ${{ variables['advancedsecurity.codeql.autobuild.enable'] }}"
echo "Build.DefinitionName: ${{ variables['Build.DefinitionName'] }}"
echo "Build.SourceBranch: ${{ variables['Build.SourceBranch'] }}"
echo "Build.Reason: ${{ variables['Build.Reason'] }}"
echo "repository defaultBranch: ${{ resources.repositories['self'].defaultBranch }}"
echo "repository ref: ${{ resources.repositories['self'].ref }}"
echo "Either above variables do NOT match"
echo "OR task 'AdvancedSecurity-Dependency-Scanning (f97aace4-962a-441b-9141-b842d806b9c7)' is already present in the job"
echo "OR task 'AdvancedSecurity-Codeql-Analyze (a9efc1ef-3900-494f-a460-963e3f5f6928)' is already present in the job"
echo "OR task 'AdvancedSecurity-Codeql-Autobuild (a63ec2fb-3600-494f-a460-963e3f5f6928)' is already present in the job"
# (Enabled AND DefaultBranch AND NOT contains Task)
# OR
# ((Build Reason OR Definition Name) AND DefaultBranch AND NOT contains Task AND NOT Skip)
- ${{ if or( and(eq(variables['advancedsecurity.enable'], 'true'), eq(variables['advancedsecurity.codeql.autobuild.enable'], 'true'), eq(resources.repositories['self'].ref, resources.repositories['self'].defaultBranch), not(containsValue(job.steps.*.task.id, 'a63ec2fb-3600-494f-a460-963e3f5f6928'))), and( eq(variables['advancedsecurity.codeql.autobuild.enable'], 'true'), or(in(variables['Build.Reason'], 'Manual', 'IndividualCI', 'BatchedCI', 'PullRequest'), contains(variables['Build.DefinitionName'], 'CI')), eq(resources.repositories['self'].ref, resources.repositories['self'].defaultBranch), not(containsValue(job.steps.*.task.id, 'a63ec2fb-3600-494f-a460-963e3f5f6928')), ne(variables['advancedsecurity.skip'], 'true') ) ) }}:
- task: AdvancedSecurity-Codeql-Autobuild@1
displayName: '(injected) Advanced Security AutoBuild v1'
- ${{ if or( and(eq(variables['advancedsecurity.enable'], 'true'), eq(resources.repositories['self'].ref, resources.repositories['self'].defaultBranch), not(containsValue(job.steps.*.task.id, 'f97aace4-962a-441b-9141-b842d806b9c7'))), and( or(in(variables['Build.Reason'], 'Manual', 'IndividualCI', 'BatchedCI', 'PullRequest'), contains(variables['Build.DefinitionName'], 'CI')), eq(resources.repositories['self'].ref, resources.repositories['self'].defaultBranch), not(containsValue(job.steps.*.task.id, 'f97aace4-962a-441b-9141-b842d806b9c7')), ne(variables['advancedsecurity.skip'], 'true') ) ) }}:
- task: AdvancedSecurity-Dependency-Scanning@1
displayName: '(injected) Advanced Security Dependency Scanning v1'
- task: PowerShell@2
displayName: '(injected) Advanced Security Dependency Review (Fail on Critical)'
condition: and(succeeded(), ne(variables['advancedsecurity.dependencies.failoncritical.skip'], 'true'))
inputs:
targetType: 'inline'
failOnStderr: true
pwsh: true
script: |
$organization = [regex]::Match("$(System.CollectionUri)", "(?<=\/)[^\/]+(?=\/$)").Value
$teamProject = "$(System.TeamProject)"
$repoID = "$(Build.Repository.ID)"
$branchname= "$(Build.SourceBranchName)"
$accessToken = "Bearer $(System.AccessToken)"
$AdvSecEnablement = "https://advsec.dev.azure.com/$($organization)/$($teamProject)/_apis/management/repositories/$($repoID)/enablement"
Write-Host "AdvSec Enablement URL: $AdvSecEnablement"
$response = Invoke-RestMethod -Uri $AdvSecEnablement -Headers @{Authorization = $accessToken} -ContentType "application/json" -Method Get
Write-Host "Response: $response"
$isEnabled = $response.advSecEnabled -eq "True"
Write-Host "AdvSecEnablement: $isEnabled"
if ($isEnabled)
{
$CriticalURL = "https://advsec.dev.azure.com/$($organization)/$($teamProject)/_apis/alert/Repositories/$($repoID)/Alerts?criteria.alertType=dependency&criteria.branchName=$($branchname)&criteria.onlyDefaultBranchAlerts=true&top=100&orderBy=severity&criteria.states=active"
Write-Host "AdvSec Alerts URL: $CriticalURL"
$response = Invoke-RestMethod -Uri $CriticalURL -Headers @{Authorization = $accessToken} -ContentType "application/json" -Method Get
Write-Host "Response: $response"
$filteredData = $response.value | Where-Object { $_.severity -eq "critical" }
if ($($filteredData.Count) -gt 0)
{
Write-Host "##[error]Found [$($filteredData.Count)] critical dependency vulnerabilities."
Write-Host "##[error]CRITICAL: Build Failed"
exit 1
}
else
{
Write-Host "##[section]No critical dependency vulnerabilities found."
}
}
else
{
Write-Host "##[warning]Advanced Security not enabled on this repository."
}
- ${{ if or( and(eq(variables['advancedsecurity.enable'], 'true'), eq(resources.repositories['self'].ref, resources.repositories['self'].defaultBranch), not(containsValue(job.steps.*.task.id, 'a9efc1ef-3900-494f-a460-963e3f5f6928'))), and( or(in(variables['Build.Reason'], 'Manual', 'IndividualCI', 'BatchedCI', 'PullRequest'), contains(variables['Build.DefinitionName'], 'CI')), eq(resources.repositories['self'].ref, resources.repositories['self'].defaultBranch), not(containsValue(job.steps.*.task.id, 'a9efc1ef-3900-494f-a460-963e3f5f6928')), ne(variables['advancedsecurity.skip'], 'true') ) ) }}:
- task: AdvancedSecurity-Codeql-Analyze@1
displayName: '(injected) Advanced Security Perform CodeQL Analysis v1'
- task: PowerShell@2
displayName: '(injected) Advanced Security Code Scanning (Fail on Critical)'
condition: and(succeeded(), ne(variables['advancedsecurity.codescanning.failoncritical.skip'], 'true'))
inputs:
targetType: 'inline'
failOnStderr: true
pwsh: true
script: |
$organization = [regex]::Match("$(System.CollectionUri)", "(?<=\/)[^\/]+(?=\/$)").Value
$teamProject = "$(System.TeamProject)"
$repoID = "$(Build.Repository.ID)"
$branchname= "$(Build.SourceBranchName)"
$accessToken = "Bearer $(System.AccessToken)"
$AdvSecEnablement = "https://advsec.dev.azure.com/$($organization)/$($teamProject)/_apis/management/repositories/$($repoID)/enablement"
Write-Host "AdvSec Enablement URL: $AdvSecEnablement"
$response = Invoke-RestMethod -Uri $AdvSecEnablement -Headers @{Authorization = $accessToken} -ContentType "application/json" -Method Get
Write-Host "Response: $response"
$isEnabled = $response.advSecEnabled -eq "True"
Write-Host "AdvSecEnablement: $isEnabled"
if ($isEnabled)
{
$CriticalURL = "https://advsec.dev.azure.com/$($organization)/$($teamProject)/_apis/alert/Repositories/$($repoID)/Alerts?criteria.alertType=code&criteria.branchName=$($branchname)&criteria.onlyDefaultBranchAlerts=true&top=100&orderBy=severity&criteria.states=active"
Write-Host "AdvSec Alerts URL: $CriticalURL"
$response = Invoke-RestMethod -Uri $CriticalURL -Headers @{Authorization = $accessToken} -ContentType "application/json" -Method Get
Write-Host "Response: $response"
$filteredData = $response.value | Where-Object { $_.severity -eq "critical" }
if ($($filteredData.Count) -gt 0)
{
Write-Host "##[error]Found [$($filteredData.Count)] critical code scanning vulnerabilities."
Write-Host "##[error]CRITICAL: Build Failed"
exit 1
}
else
{
Write-Host "##[section]No critical code scanning vulnerabilities found."
}
}
else
{
Write-Host "##[warning]Advanced Security not enabled on this repository."
}