-
Notifications
You must be signed in to change notification settings - Fork 5
Block outbound calls from ci runners to unallowed endpoints #1175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,10 +16,17 @@ jobs: | |
| name: Documentation | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Harden the runner (Audit all outbound calls) | ||
| - name: "Harden the runner (Block egress traffic: Only allow calls to allowed endpoints)" | ||
| uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 | ||
| with: | ||
| egress-policy: audit | ||
| egress-policy: block | ||
| allowed-endpoints: >+ | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| github.com:443 | ||
| pypi.org:443 | ||
| files.pythonhosted.org:443 | ||
| plantuml.com:80 | ||
| plantuml.com:443 | ||
| www.plantuml.com:80 | ||
|
|
||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
| with: | ||
|
|
@@ -41,10 +48,17 @@ jobs: | |
| name: Landing page | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Harden the runner (Audit all outbound calls) | ||
| - name: "Harden the runner (Block egress traffic: Only allow calls to allowed endpoints)" | ||
| uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 | ||
| with: | ||
| egress-policy: audit | ||
| egress-policy: block | ||
| allowed-endpoints: >+ | ||
| github.com:443 | ||
| pypi.org:443 | ||
| files.pythonhosted.org:443 | ||
| plantuml.com:80 | ||
| plantuml.com:443 | ||
| www.plantuml.com:80 | ||
|
|
||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
|
|
||
|
|
@@ -75,10 +89,24 @@ jobs: | |
| permissions: | ||
| contents: write | ||
| steps: | ||
| - name: Harden the runner (Audit all outbound calls) | ||
| - name: "Harden the runner (Block egress traffic: Only allow calls to allowed endpoints)" | ||
| uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 | ||
| with: | ||
| egress-policy: audit | ||
| egress-policy: block | ||
| allowed-endpoints: >+ | ||
| _http._tcp.azure.archive.ubuntu.com:443 | ||
| _https._tcp.archive.ubuntu.com:443 | ||
| _https._tcp.security.ubuntu.com:443 | ||
| archive.ubuntu.com:443 | ||
| azure.archive.ubuntu.com:443 | ||
| azure.archive.ubuntu.com:80 | ||
| files.pythonhosted.org:443 | ||
| github.com:443 | ||
| plantuml.com:443 | ||
| plantuml.com:80 | ||
| pypi.org:443 | ||
| security.ubuntu.com:443 | ||
| www.plantuml.com:80 | ||
|
Comment on lines
+92
to
+109
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: cat -n .github/workflows/docs.ymlRepository: dfetch-org/dfetch Length of output: 5214 🌐 Web query:
💡 Result: The GitHub release asset upload endpoint is POST /repos/{owner}/{repo}/releases/{release_id}/assets, but the actual URL is dynamic and provided as the 'upload_url' in the response from the Create a release API endpoint (e.g., https://uploads.github.com/repos/OWNER/REPO/releases/RELEASE_ID/assets?X-Amz-Algorithm=... etc., with presigned parameters). It requires headers like Content-Type (e.g., application/zip), Content-Length, and authentication (e.g., Authorization: token ...). The raw binary file is sent in the request body. The softprops/action-gh-release GitHub Action handles creating/updating releases and uploading assets via the 'files' input (newline-delimited globs). It uses the GitHub Release API internally, including the upload_url for assets, and outputs the upload_url among others. It can upload to existing releases if the tag matches. Example curl from official docs: curl -L -X POST https://uploads.github.com/repos/OWNER/REPO/releases/RELEASE_ID/assets?name=example.zip -H 'Authorization: token XXX' -H 'Content-Type: application/zip' --data-binary Citations:
Add The 🤖 Prompt for AI Agents |
||
|
|
||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
| with: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,10 +26,11 @@ jobs: | |
| id-token: write | ||
|
|
||
| steps: | ||
| - name: Harden the runner (Audit all outbound calls) | ||
| - name: "Harden the runner (Block egress traffic: Only allow calls to allowed endpoints)" | ||
| uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 | ||
| with: | ||
| egress-policy: audit | ||
| egress-policy: block | ||
| allowed-endpoints: >+ | ||
|
Comment on lines
+29
to
+33
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: cat .github/workflows/scorecard.yml | head -60Repository: dfetch-org/dfetch Length of output: 2150 🏁 Script executed: # Check if there's more context in the workflow or if endpoints are defined elsewhere
rg -A 10 "allowed-endpoints" .github/workflows/scorecard.ymlRepository: dfetch-org/dfetch Length of output: 424 🌐 Web query:
💡 Result: In StepSecurity's Harden-Runner GitHub Action, when using block mode (egress-policy: block) with an empty allowed-endpoints list (default is ""), Harden-Runner blocks all outbound network connections except those automatically allowed for its own operation (e.g., to StepSecurity APIs over TLS, which do not need explicit addition). Any other outbound traffic to endpoints not explicitly listed is blocked at DNS (Layer 7) and network layers (Layers 3/4), including DNS exfiltration attempts. This creates a restrictive deny-by-default policy, preventing data exfiltration. Workflows typically fail if they require external network access without allowed endpoints configured, as seen in guides for fixing blocked endpoints by adding legitimate ones after audit mode. Examples always include specific endpoints like github.com:443 when using block mode. Policy Store can centralize allowlists, but local empty list takes precedence and enforces strict blocking. Citations:
🌐 Web query:
💡 Result: The actions/checkout GitHub Action makes outbound network calls to github.com domains during execution, specifically to api.github.com and related endpoints. Primary network egress: - Git protocol fetches/clones/pushes to github.com (ports 22/443), using GITHUB_TOKEN or SSH key for authentication. This is the default behavior when Git is available (version 2.18+). - HTTPS git operations to github.com. Additional calls when Git is unavailable or fallback triggered: - REST API calls to api.github.com to get default branch (octokit.rest.repos.get) and download archive (downloadTarballArchive or downloadZipballArchive). - These use Citations:
🏁 Script executed: # Check if there are any other harden-runner configurations in the repo that show examples
rg "harden-runner" .github/workflows/ -A 5 -B 2Repository: dfetch-org/dfetch Length of output: 8301 Add allowed GitHub endpoints to unblock the workflow. The Or use the recommended policy approach from the step-security/harden-runner documentation. 🤖 Prompt for AI Agents |
||
|
|
||
| - name: "Checkout code" | ||
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: dfetch-org/dfetch
Length of output: 91
🏁 Script executed:
# Read the full workflow file to understand the build job cat -n .github/workflows/build.ymlRepository: dfetch-org/dfetch
Length of output: 11235
🏁 Script executed:
Repository: dfetch-org/dfetch
Length of output: 916
🌐 Web query:
Chocolatey choco install default feed endpoint community.chocolatey.org💡 Result:
The default Chocolatey feed endpoint for community packages is: https://community.chocolatey.org/api/v2/ So your command corresponds to explicitly using the Community Repository (community feed) OData v2 endpoint.
Citations:
🌐 Web query:
dotnet tool install NuGet feed endpoints api.nuget.org💡 Result:
The dotnet tool install command uses NuGet feeds, with api.nuget.org (nuget.org) as the default public feed. It first fetches the V3 service index at https://api.nuget.org/v3/index.json to discover available resources and endpoints. Key endpoints used include: - Service Index: https://api.nuget.org/v3/index.json (entry point listing all resources like SearchQueryService, PackageBaseAddress, RegistrationsBaseUrl). - SearchQueryService: e.g., https://api-v2v3search-0.nuget.org/query (for package search and version resolution, specifically via NugetToolSearchApiRequest; filters for dotnet-tool packageType). - PackageBaseAddress: https://api.nuget.org/v3-flatcontainer/ (for downloading .nupkg files, e.g., https://api.nuget.org/v3-flatcontainer/{LOWER_ID}/{LOWER_VERSION}/{LOWER_ID}.{LOWER_VERSION}.nupkg). - RegistrationsBaseUrl: https://api.nuget.org/v3/registration2/ (for package metadata). If no version is specified, it queries the search endpoint on nuget.org first (fails if blocked without --version). Use --source, --add-source, or --ignore-failed-sources to control feeds. Official docs confirm dotnet tool install resolves packages via standard NuGet V3 protocol from configured sources, defaulting to nuget.org.
Citations:
🌐 Web query:
GitHub softprops/action-gh-release upload endpoint uploads.github.com💡 Result:
softprops/action-gh-release uploads release assets to GitHub Releases using the upload_url returned by the Releases API (a hypermedia resource). For GitHub.com, the “uploads” host you referenced (uploads.github.com) is used by the Release assets upload endpoint: POST https://uploads.github.com/repos/{owner}/{repo}/releases/{release_id}/assets This is documented as the “Upload a release asset” endpoint; GitHub expects the raw binary asset in the request body (not JSON), with appropriate Content-Type and authentication. How this maps to softprops/action-gh-release 1) The action creates (or fetches) the release. 2) It uses the release’s upload_url (returned by the Releases API) to upload each file specified via with.files. 3) The action exposes upload_url as an output (“upload_url”). So, the key point is: softprops/action-gh-release does not hardcode uploads.github.com; it uses the upload_url provided by GitHub for the specific release, whose upload host is typically uploads.github.com.
Citations:
Add missing Windows package and release upload endpoints to the allowlist.
The Windows build jobs run
choco install zig(line 53) anddotnet tool install --global wix(line 73), which requirecommunity.chocolatey.organdapi.nuget.orgrespectively. The latersoftprops/action-gh-releasestep (line 128) uploads assets viauploads.github.com. These three endpoints are absent from the current allowlist and will cause failures under egress block mode.🤖 Prompt for AI Agents