Current collected state Current
Observed since 20 Oct, 18:34 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
actions-scanner
GitHub Actions vulnerability scanner for PwnRequest attacks
= GitHub Actions PwnRequest Vulnerability Scanner A toolkit for detecting GitHub Actions workflows vulnerable to the https://securitylab.github.com/research/github-actions-preventing-pwn-requests/[PwnRequest] attack pattern — where `pull_request_target` workflows check out and execute untrusted PR code, allowing secret exfiltration. CAUTION: Use findings responsibly and follow responsible disclosure practices. == Installation [source,bash] ---- uv tool install git+https://github.com/SecKatie/actions-scanner.git ---- == Usage [source,bash] ---- # Scan an org, repo URL, local directory, or list file (default format: csv) actions-scanner scan your-org -o results.csv # Validate findings with AI-assisted confirmation (accepts csv or json) actions-scanner validate results.csv # Export to markdown actions-scanner report results.csv -o report.md --format markdown ---- == What It Detects The scanner flags workflows where all three conditions exist in the same job: 1. **Trigger:** `pull_request_target` (runs with write permissions and secrets) 2. **Checkout:** Untrusted PR ref (`head.sha`, `head.ref`, `merge_commit_sha`, `github.head_ref`) 3. **Execution:** Build commands (`npm install`, `make`, `pip install`, `docker build`, etc.) or local actions (`./action`) == Development **Prerequisites:** Python 3.11+, https://github.com/astral-sh/uv[uv], `gh` CLI (authenticated), `git` [source,bash] ---- git clone https://github.com/SecKatie/actions-scanner.git && cd actions-scanner uv sync uv run pytest tests/ -v ---- === Environment Variables [cols="1,2"] |=== |Variable |Description |`GITHUB_TOKEN` |GitHub personal access token (required for org scanning) |=== == References * https://securitylab.github.com/research/github-actions-preventing-pwn-requests/[GitHub Security Lab: Preventing pwn requests] * https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions[GitHub Docs: Security hardening for GitHub Actions] == License Internal use only.
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
aiofilesEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | aiofiles>=23.2.0 | runtime |
aiohttpEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | aiohttp>=3.9.0 | runtime |
clickEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | click>=8.1.7 | runtime |
pydantic-settingsEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pydantic-settings>=2.1.0 | runtime |
pydanticEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pydantic>=2.5.0 | runtime |
pyyamlEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pyyaml>=6.0.1 | runtime |
richEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | rich>=13.7.0 | runtime |
aioresponsesEnvironment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | aioresponses>=0.7.0; extra == "all" | runtime |
ldap3Environment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | ldap3>=2.9.1; extra == "all" | runtime |
pre-commitEnvironment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pre-commit>=3.6.0; extra == "all" | runtime |
pytest-asyncioEnvironment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pytest-asyncio>=0.23.0; extra == "all" | runtime |
pytest-covEnvironment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pytest-cov>=4.1.0; extra == "all" | runtime |
pytestEnvironment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pytest>=7.4.0; extra == "all" | runtime |
ruffEnvironment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | ruff>=0.4.0; extra == "all" | runtime |
tyEnvironment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | ty>=0.0.1; extra == "all" | runtime |
aioresponsesEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | aioresponses>=0.7.0; extra == "dev" | runtime |
pre-commitEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pre-commit>=3.6.0; extra == "dev" | runtime |
pytest-asyncioEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pytest-asyncio>=0.23.0; extra == "dev" | runtime |
pytest-covEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pytest-cov>=4.1.0; extra == "dev" | runtime |
pytestEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pytest>=7.4.0; extra == "dev" | runtime |
ruffEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | ruff>=0.4.0; extra == "dev" | runtime |
tyEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | ty>=0.0.1; extra == "dev" | runtime |
ldap3Environment{
"extras": "",
"marker": "extra == \"ldap\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | ldap3>=2.9.1; extra == "ldap" | runtime |
bdist_wheel · 68.73 KB · Python py3
sdist · 72.41 KB · Python source
Observed since 20 Oct, 18:34 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:6c9ea9bbba3f7fff0c3b402d33baa93a8a5697a0aeded182b21abfdf2e45e9f5