Repository navigation
140 lines (128 loc) · 6.36 KB
/
Copy pathapi-full-scan-with-auth.yml
File metadata and controls
140 lines (128 loc) · 6.36 KB
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
name: "API Full ZAP Scan with Authentication"
# This workflow is experimental and is not functioning as intended.
# IMPORTANT NOTE:
# 1. This workflow uses the `zap-auth-per-endpoint.js` script to dynamically determine the correct token
# (either `auth_token` or `client_token`) based on the Swagger JSON specification for each endpoint.
# 2. The script reads the OpenAPI spec, analyzes the security requirements for each endpoint, and sets the
# appropriate authentication headers for scanning:
# - If an endpoint requires `auth_token`, it sets the `Authorization` header to "Bearer AUTH_TOKEN".
# - If an endpoint requires `client_token`, it sets the `Authorization` header to "Bearer CLIENT_TOKEN" and
# includes an additional `x-client-id` header.
# - If no token is required, it omits the `Authorization` header.
# 3. The intended functionality of this workflow is to improve upon the "API Security Scan with Selectable Token"
# workflow by automating the token selection process for each endpoint.
# 4. However, this workflow currently does not work as intended because:
# - The `zap-auth-per-endpoint.js` script is not being successfully invoked or integrated during the scan.
# - This results in incorrect or missing authentication headers, causing the scan to fail for authenticated endpoints.
# 5. Please exercise caution and review the workflow before proceeding.
on:
workflow_dispatch:
inputs:
confirmUsage:
description: 'WARNING: This workflow is experimental and has known issues. Review the developer comments and confirm if you want to proceed. (yes/no)'
required: true
default: 'no'
openapiurl:
description: 'The OpenAPI Swagger JSON to import'
required: true
default: 'https://api.epa.gov/easey/perf/camd-services/swagger-json'
openapitargeturl:
description: 'The OpenAPI target URL to scan'
required: true
default: 'https://api.epa.gov/easey/perf/'
zapscanpolicy:
description: 'The ZAP scan policy to use'
required: true
type: choice
options:
- 'Default Policy'
- 'St-Ins-Th-Low'
- 'St-Ins-Th-Med'
- 'St-Ins-Th-High'
- 'St-High-Th-Low'
- 'St-High-Th-Med'
- 'St-High-Th-High'
- 'St-Medium-Th-Low'
- 'St-Medium-Th-Med'
- 'St-Medium-Th-High'
- 'St-Low-Th-Low'
- 'St-Low-Th-Med'
- 'St-Low-Th-High'
jobs:
zap_scan:
runs-on: ubuntu-latest
steps:
# 1. Display Warning and Confirm Usage
- name: Confirm Workflow Usage
run: |
echo "WARNING: This workflow is experimental and may not function as intended."
echo "Developer Note: Review the workflow configuration and ensure all steps align with your project requirements before proceeding."
if [ "${{ github.event.inputs.confirmUsage }}" != "yes" ]; then
echo "Exiting workflow as confirmation was not provided."
exit 1
fi
echo "Proceeding with the workflow as confirmation was provided."
# 2. Checkout Code
- name: Checkout code
uses: actions/checkout@v4
# 3. Echo Input Parameters
- name: Echo Input Parameters
run: |
echo "OpenAPI URL: ${{ github.event.inputs.openapiurl }}"
echo "Target URL: ${{ github.event.inputs.openapitargeturl }}"
echo "Scan Policy: ${{ github.event.inputs.zapscanpolicy }}"
# 4. Replace '<<policy>>' in the api_scan.py File
- name: Replace '<<policy>>' in the api_scan.py file
run: sed -i "s/<<policy>>/${{ github.event.inputs.zapscanpolicy }}/g" scan-hooks/api_scan.py
# 5. Install jq
- name: Install jq
run: sudo apt-get update && sudo apt-get install -y jq
# 6. Obtain Authentication Token
- name: Obtain Authentication Token
id: get_auth_token
env:
X_API_KEY: ${{ secrets.OWASP_ZAP_SCAN_API_KEY }}
SCAN_USER_ID: ${{ secrets.SCAN_USER_ID }}
run: |
AUTH_RESPONSE=$(curl -s -X POST \
"${{ github.event.inputs.openapitargeturl }}auth-mgmt/sign-in" \
-H "Content-Type: application/json" \
-H "x-api-key: $X_API_KEY" \
-d "{\"sessionId\": \"${SCAN_USER_ID:-scanUser1}\"}")
AUTH_TOKEN=$(echo "$AUTH_RESPONSE" | jq -r '.token')
echo "AUTH_TOKEN=$AUTH_TOKEN" >> $GITHUB_ENV
# 7. Obtain Client Token
- name: Obtain Client Token
id: get_client_token
env:
X_API_KEY: ${{ secrets.OWASP_ZAP_SCAN_API_KEY }}
SCAN_CLIENT_ID: ${{ secrets.SCAN_CLIENT_ID }}
SCAN_CLIENT_SECRET: ${{ secrets.SCAN_CLIENT_SECRET }}
run: |
CLIENT_RESPONSE=$(curl -s -X POST \
"${{ github.event.inputs.openapitargeturl }}auth-mgmt/tokens/client" \
-H "Content-Type: application/json" \
-H "x-api-key: $X_API_KEY" \
-d "{\"clientId\": \"${SCAN_CLIENT_ID}\", \"clientSecret\": \"${SCAN_CLIENT_SECRET}\"}")
CLIENT_TOKEN=$(echo "$CLIENT_RESPONSE" | jq -r '.token')
echo "CLIENT_TOKEN=$CLIENT_TOKEN" >> $GITHUB_ENV
# 8. Download OpenAPI Spec
- name: Download OpenAPI Spec
run: |
curl -s -o openapi-spec.json "${{ github.event.inputs.openapiurl }}"
# 9. Run ZAP Scan with Custom Script
- name: Run ZAP Scan
uses: zaproxy/action-full-scan@v0.12.0
env:
AUTH_TOKEN: ${{ env.AUTH_TOKEN }}
CLIENT_TOKEN: ${{ env.CLIENT_TOKEN }}
X_API_KEY: ${{ secrets.OWASP_ZAP_SCAN_API_KEY }}
SCAN_CLIENT_ID: ${{ secrets.SCAN_CLIENT_ID }}
OPENAPI_SPEC_PATH: '/zap/wrk/openapi-spec.json'
with:
token: ${{ secrets.GITHUB_TOKEN }}
target: ${{ github.event.inputs.openapitargeturl }}
docker_name: 'ghcr.io/zaproxy/zaproxy:latest'
allow_issue_writing: 'false'
rules_file_name: 'rules-api.tsv'
cmd_options: "-a -d --hook=scan-hooks/api_scan.py -z \"-addoninstall openapi -openapiurl ${{ github.event.inputs.openapiurl }} -openapitargeturl ${{ github.event.inputs.openapitargeturl }} -config script.scripts.name=zap-auth-per-endpoint -config script.scripts.type=httpsender -config script.scripts.engine='Oracle Nashorn' -config script.scripts.file=scripts/zap-auth-per-endpoint.js -config script.scripts.enabled=true\""