zizmor 1.2.1__tar.gz → 1.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of zizmor might be problematic. Click here for more details.
- {zizmor-1.2.1 → zizmor-1.2.2}/.github/workflows/zizmor.yml +2 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/Cargo.lock +3 -3
- {zizmor-1.2.1 → zizmor-1.2.2}/Cargo.toml +2 -2
- {zizmor-1.2.1 → zizmor-1.2.2}/PKG-INFO +1 -1
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/release-notes.md +11 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/usage.md +1 -1
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/excessive_permissions.rs +39 -22
- {zizmor-1.2.1 → zizmor-1.2.2}/src/github_api.rs +11 -1
- {zizmor-1.2.1 → zizmor-1.2.2}/src/main.rs +11 -2
- {zizmor-1.2.1 → zizmor-1.2.2}/src/models.rs +20 -2
- {zizmor-1.2.1 → zizmor-1.2.2}/src/registry.rs +1 -1
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshot.rs +19 -0
- zizmor-1.2.2/tests/snapshots/snapshot__excessive_permissions-10.snap +21 -0
- zizmor-1.2.2/tests/snapshots/snapshot__excessive_permissions-11.snap +19 -0
- zizmor-1.2.2/tests/snapshots/snapshot__excessive_permissions-12.snap +47 -0
- zizmor-1.2.2/tests/test-data/excessive-permissions/issue-472-repro.yml +23 -0
- zizmor-1.2.2/tests/test-data/excessive-permissions/reusable-workflow-call.yml +9 -0
- zizmor-1.2.2/tests/test-data/excessive-permissions/reusable-workflow-other-triggers.yml +21 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/.github/dependabot.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/.github/workflows/ci.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/.github/workflows/pypi.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/.github/workflows/release.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/.github/workflows/site.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/.gitignore +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/CONTRIBUTING.md +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/LICENSE +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/Makefile +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/README.md +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/assets/favicon48x48.png +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/assets/rainbow.svg +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/assets/zizmor-demo.gif +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/audits.md +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/configuration.md +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/development.md +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/index.md +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/installation.md +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/magiclink.css +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/quickstart.md +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/snippets/help.txt +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/snippets/render-sponsors.py +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/snippets/render-trophies.py +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/snippets/sponsors.html +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/snippets/sponsors.json +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/snippets/trophies.md +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/snippets/trophies.txt +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/docs/trophy-case.md +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/mkdocs.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/pyproject.toml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/artipacked.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/bot_conditions.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/cache_poisoning.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/dangerous_triggers.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/github_env.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/hardcoded_container_credentials.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/impostor_commit.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/insecure_commands.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/known_vulnerable_actions.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/mod.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/ref_confusion.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/secrets_inherit.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/self_hosted_runner.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/template_injection.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/unpinned_uses.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/audit/use_trusted_publishing.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/config.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/expr/expr.pest +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/expr/mod.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/finding/locate.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/finding/mod.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/models/coordinate.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/models/uses.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/render.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/sarif.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/state.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/src/utils.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/acceptance.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/common.rs +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__artipacked-2.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__artipacked-3.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__artipacked-4.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__artipacked.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__bot_conditions.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__cache_poisoning-10.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__cache_poisoning-11.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__cache_poisoning-12.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__cache_poisoning-13.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__cache_poisoning-14.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__cache_poisoning-2.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__cache_poisoning-3.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__cache_poisoning-4.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__cache_poisoning-5.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__cache_poisoning-6.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__cache_poisoning-7.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__cache_poisoning-8.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__cache_poisoning-9.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__cache_poisoning.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__cant_retrieve.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__conflicting_online_options-2.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__conflicting_online_options-3.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__conflicting_online_options.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__excessive_permissions-2.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__excessive_permissions-3.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__excessive_permissions-4.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__excessive_permissions-5.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__excessive_permissions-6.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__excessive_permissions-7.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__excessive_permissions-8.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__excessive_permissions-9.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__excessive_permissions.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__github_env-2.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__github_env-3.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__github_env.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__insecure_commands-2.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__insecure_commands-3.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__insecure_commands.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__secrets_inherit.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__self_hosted-2.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__self_hosted-3.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__self_hosted-4.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__self_hosted-5.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__self_hosted-6.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__self_hosted-7.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__self_hosted-8.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__self_hosted.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__template_injection-2.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__template_injection-3.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__template_injection-4.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__template_injection-5.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__template_injection-6.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__template_injection-7.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__template_injection-8.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__template_injection.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__unpinned_uses-2.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__unpinned_uses-3.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__unpinned_uses-4.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/snapshots/snapshot__unpinned_uses.snap +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/artipacked/issue-447-repro.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/artipacked.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/bot-conditions.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/cache-poisoning/caching-disabled-by-default.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/cache-poisoning/caching-enabled-by-default.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/cache-poisoning/caching-not-configurable.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/cache-poisoning/caching-opt-in-boolean-toggle.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/cache-poisoning/caching-opt-in-boolish-toggle.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/cache-poisoning/caching-opt-in-expression.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/cache-poisoning/caching-opt-in-multi-value-toggle.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/cache-poisoning/caching-opt-out.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/cache-poisoning/issue-343-repro.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/cache-poisoning/issue-378-repro.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/cache-poisoning/no-cache-aware-steps.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/cache-poisoning/publisher-step.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/cache-poisoning/workflow-release-branch-trigger.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/cache-poisoning/workflow-tag-trigger.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/cache-poisoning.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/excessive-permissions/issue-336-repro.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/excessive-permissions/jobs-broaden-permissions.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/excessive-permissions/workflow-default-perms-all-jobs-explicit.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/excessive-permissions/workflow-default-perms.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/excessive-permissions/workflow-empty-perms.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/excessive-permissions/workflow-read-all.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/excessive-permissions/workflow-write-all.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/excessive-permissions/workflow-write-explicit.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/excessive-permissions.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/github-env/action.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/github-env/github-path.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/github-env/issue-397-repro.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/github_env.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/hardcoded-credentials.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/inlined-ignores.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/insecure-commands/action.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/insecure-commands.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/secrets-inherit.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/self-hosted/issue-283-repro.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/self-hosted/self-hosted-matrix-dimension.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/self-hosted/self-hosted-matrix-exclusion.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/self-hosted/self-hosted-matrix-inclusion.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/self-hosted/self-hosted-runner-group.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/self-hosted/self-hosted-runner-label.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/self-hosted.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/template-injection/issue-22-repro.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/template-injection/issue-339-repro.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/template-injection/issue-418-repro.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/template-injection/pr-317-repro.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/template-injection/pr-425-backstop/action.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/template-injection/static-env.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/template-injection/template-injection-dynamic-matrix.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/template-injection/template-injection-static-matrix.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/template-injection.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/unpinned-uses/action.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/unpinned-uses/issue-433-repro.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/unpinned-uses.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/tests/test-data/use-trusted-publishing.yml +0 -0
- {zizmor-1.2.1 → zizmor-1.2.2}/uv.lock +0 -0
|
@@ -616,9 +616,9 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
|
|
616
616
|
|
|
617
617
|
[[package]]
|
|
618
618
|
name = "github-actions-models"
|
|
619
|
-
version = "0.
|
|
619
|
+
version = "0.22.0"
|
|
620
620
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
621
|
-
checksum = "
|
|
621
|
+
checksum = "ea4c30fa8bf11e002d3ca72233e7a7bac33ffce4dc50877d63a8f5a161e0cd84"
|
|
622
622
|
dependencies = [
|
|
623
623
|
"indexmap",
|
|
624
624
|
"serde",
|
|
@@ -3108,7 +3108,7 @@ dependencies = [
|
|
|
3108
3108
|
|
|
3109
3109
|
[[package]]
|
|
3110
3110
|
name = "zizmor"
|
|
3111
|
-
version = "1.2.
|
|
3111
|
+
version = "1.2.2"
|
|
3112
3112
|
dependencies = [
|
|
3113
3113
|
"annotate-snippets",
|
|
3114
3114
|
"anstream",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "zizmor"
|
|
3
3
|
description = "Static analysis for GitHub Actions"
|
|
4
|
-
version = "1.2.
|
|
4
|
+
version = "1.2.2"
|
|
5
5
|
edition = "2021"
|
|
6
6
|
repository = "https://github.com/woodruffw/zizmor"
|
|
7
7
|
homepage = "https://github.com/woodruffw/zizmor"
|
|
@@ -23,7 +23,7 @@ clap-verbosity-flag = { version = "3.0.2", features = [
|
|
|
23
23
|
], default-features = false }
|
|
24
24
|
etcetera = "0.8.0"
|
|
25
25
|
flate2 = "1.0.35"
|
|
26
|
-
github-actions-models = "0.
|
|
26
|
+
github-actions-models = "0.22.0"
|
|
27
27
|
http-cache-reqwest = "0.15.0"
|
|
28
28
|
human-panic = "2.0.1"
|
|
29
29
|
indexmap = "2.7.0"
|
|
@@ -11,6 +11,17 @@ of `zizmor`.
|
|
|
11
11
|
|
|
12
12
|
Nothing to see here (yet!)
|
|
13
13
|
|
|
14
|
+
## v1.2.2
|
|
15
|
+
|
|
16
|
+
### Bug Fixes 🐛
|
|
17
|
+
|
|
18
|
+
* The [excessive-permissions] audit is now more precise about both
|
|
19
|
+
reusable workflows and reusable workflow calls (#473)
|
|
20
|
+
|
|
21
|
+
### Improvements 🌱
|
|
22
|
+
|
|
23
|
+
* Fetch failures when running `zizmor org/repo` are now more informative (#475)
|
|
24
|
+
|
|
14
25
|
## v1.2.1
|
|
15
26
|
|
|
16
27
|
This is a small corrective release for some SARIF behavior that
|
|
@@ -57,12 +57,9 @@ impl Audit for ExcessivePermissions {
|
|
|
57
57
|
|
|
58
58
|
let all_jobs_have_permissions = workflow
|
|
59
59
|
.jobs()
|
|
60
|
-
.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
Some(&job.permissions)
|
|
60
|
+
.map(|job| match job {
|
|
61
|
+
Job::NormalJob(job) => &job.permissions,
|
|
62
|
+
Job::ReusableWorkflowCallJob(job) => &job.permissions,
|
|
66
63
|
})
|
|
67
64
|
.all(|perm| !matches!(perm, Permissions::Base(BasePermission::Default)));
|
|
68
65
|
|
|
@@ -71,17 +68,21 @@ impl Audit for ExcessivePermissions {
|
|
|
71
68
|
Permissions::Base(BasePermission::Default)
|
|
72
69
|
);
|
|
73
70
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
71
|
+
let workflow_is_reusable_only =
|
|
72
|
+
workflow.has_workflow_call() && workflow.has_single_trigger();
|
|
73
|
+
|
|
74
|
+
// Top-level permissions are a pedantic finding under the following
|
|
75
|
+
// conditions:
|
|
76
|
+
//
|
|
77
|
+
// 1. The workflow has only one job.
|
|
78
|
+
// 2. All jobs in the workflow have their own explicit permissions.
|
|
79
|
+
// 3. The workflow is reusable and has only one trigger.
|
|
80
|
+
let workflow_finding_persona =
|
|
81
|
+
if workflow.jobs.len() == 1 || all_jobs_have_permissions || workflow_is_reusable_only {
|
|
82
|
+
Persona::Pedantic
|
|
83
|
+
} else {
|
|
84
|
+
Persona::Regular
|
|
85
|
+
};
|
|
85
86
|
|
|
86
87
|
// Handle top-level permissions.
|
|
87
88
|
let location = workflow.location().primary();
|
|
@@ -93,20 +94,35 @@ impl Audit for ExcessivePermissions {
|
|
|
93
94
|
Self::finding()
|
|
94
95
|
.severity(severity)
|
|
95
96
|
.confidence(confidence)
|
|
96
|
-
.persona(
|
|
97
|
+
.persona(workflow_finding_persona)
|
|
97
98
|
.add_location(perm_location)
|
|
98
99
|
.build(workflow)?,
|
|
99
100
|
);
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
for job in workflow.jobs() {
|
|
103
|
-
let
|
|
104
|
-
|
|
104
|
+
let (permissions, job_location, job_finding_persona) = match job {
|
|
105
|
+
Job::NormalJob(job) => {
|
|
106
|
+
// For normal jobs: if the workflow is reusable-only, we
|
|
107
|
+
// emit pedantic findings.
|
|
108
|
+
let persona = if workflow_is_reusable_only {
|
|
109
|
+
Persona::Pedantic
|
|
110
|
+
} else {
|
|
111
|
+
Persona::Regular
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
(&job.permissions, job.location(), persona)
|
|
115
|
+
}
|
|
116
|
+
Job::ReusableWorkflowCallJob(job) => {
|
|
117
|
+
// For reusable jobs: the caller is always responsible for
|
|
118
|
+
// permissions, so we emit regular findings even if
|
|
119
|
+
// the workflow is reusable-only.
|
|
120
|
+
(&job.permissions, job.location(), Persona::Regular)
|
|
121
|
+
}
|
|
105
122
|
};
|
|
106
123
|
|
|
107
|
-
let job_location = job.location();
|
|
108
124
|
if let Some((severity, confidence, perm_location)) = self.check_job_permissions(
|
|
109
|
-
|
|
125
|
+
permissions,
|
|
110
126
|
explicit_parent_permissions,
|
|
111
127
|
job_location.clone(),
|
|
112
128
|
) {
|
|
@@ -114,6 +130,7 @@ impl Audit for ExcessivePermissions {
|
|
|
114
130
|
Self::finding()
|
|
115
131
|
.severity(severity)
|
|
116
132
|
.confidence(confidence)
|
|
133
|
+
.persona(job_finding_persona)
|
|
117
134
|
.add_location(job_location)
|
|
118
135
|
.add_location(perm_location.primary())
|
|
119
136
|
.build(workflow)?,
|
|
@@ -12,6 +12,7 @@ use github_actions_models::common::RepositoryUses;
|
|
|
12
12
|
use http_cache_reqwest::{
|
|
13
13
|
CACacheManager, Cache, CacheMode, CacheOptions, HttpCache, HttpCacheOptions,
|
|
14
14
|
};
|
|
15
|
+
use owo_colors::OwoColorize;
|
|
15
16
|
use reqwest::{
|
|
16
17
|
header::{HeaderMap, ACCEPT, AUTHORIZATION, USER_AGENT},
|
|
17
18
|
StatusCode,
|
|
@@ -399,7 +400,16 @@ impl Client {
|
|
|
399
400
|
// TODO: Could probably make this slightly faster by
|
|
400
401
|
// streaming asynchronously into the decompression,
|
|
401
402
|
// probably with the async-compression crate.
|
|
402
|
-
let
|
|
403
|
+
let resp = self.http.get(&url).send().await?;
|
|
404
|
+
|
|
405
|
+
if !resp.status().is_success() {
|
|
406
|
+
return Err(anyhow!(
|
|
407
|
+
"failed to fetch {url}: {status}",
|
|
408
|
+
status = resp.status().red()
|
|
409
|
+
));
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
let contents = resp.bytes().await?;
|
|
403
413
|
let tar = GzDecoder::new(contents.deref());
|
|
404
414
|
|
|
405
415
|
let mut archive = Archive::new(tar);
|
|
@@ -258,7 +258,16 @@ fn collect_from_repo_slug(
|
|
|
258
258
|
registry.register_input(workflow.into())?;
|
|
259
259
|
}
|
|
260
260
|
} else {
|
|
261
|
-
let inputs = client.fetch_audit_inputs(&slug)
|
|
261
|
+
let inputs = client.fetch_audit_inputs(&slug).with_context(|| {
|
|
262
|
+
tip(
|
|
263
|
+
format!(
|
|
264
|
+
"couldn't collect inputs from https://github.com/{owner}/{repo}",
|
|
265
|
+
owner = slug.owner,
|
|
266
|
+
repo = slug.repo
|
|
267
|
+
),
|
|
268
|
+
"confirm the repository exists and that you have access to it",
|
|
269
|
+
)
|
|
270
|
+
})?;
|
|
262
271
|
|
|
263
272
|
tracing::info!(
|
|
264
273
|
"collected {len} inputs from {owner}/{repo}",
|
|
@@ -267,7 +276,7 @@ fn collect_from_repo_slug(
|
|
|
267
276
|
repo = slug.repo
|
|
268
277
|
);
|
|
269
278
|
|
|
270
|
-
for input in
|
|
279
|
+
for input in inputs {
|
|
271
280
|
registry.register_input(input)?;
|
|
272
281
|
}
|
|
273
282
|
}
|
|
@@ -135,7 +135,7 @@ impl Workflow {
|
|
|
135
135
|
Jobs::new(self)
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
/// Whether this workflow
|
|
138
|
+
/// Whether this workflow is triggered by pull_request_target.
|
|
139
139
|
pub(crate) fn has_pull_request_target(&self) -> bool {
|
|
140
140
|
match &self.on {
|
|
141
141
|
Trigger::BareEvent(event) => *event == BareEvent::PullRequestTarget,
|
|
@@ -144,7 +144,7 @@ impl Workflow {
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
/// Whether this workflow
|
|
147
|
+
/// Whether this workflow is triggered by workflow_run.
|
|
148
148
|
pub(crate) fn has_workflow_run(&self) -> bool {
|
|
149
149
|
match &self.on {
|
|
150
150
|
Trigger::BareEvent(event) => *event == BareEvent::WorkflowRun,
|
|
@@ -152,6 +152,24 @@ impl Workflow {
|
|
|
152
152
|
Trigger::Events(events) => !matches!(events.workflow_run, OptionalBody::Missing),
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
|
+
|
|
156
|
+
/// Whether this workflow is triggered by workflow_call.
|
|
157
|
+
pub(crate) fn has_workflow_call(&self) -> bool {
|
|
158
|
+
match &self.on {
|
|
159
|
+
Trigger::BareEvent(event) => *event == BareEvent::WorkflowCall,
|
|
160
|
+
Trigger::BareEvents(events) => events.contains(&BareEvent::WorkflowCall),
|
|
161
|
+
Trigger::Events(events) => !matches!(events.workflow_call, OptionalBody::Missing),
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/// Whether this workflow is triggered by exactly one event.
|
|
166
|
+
pub(crate) fn has_single_trigger(&self) -> bool {
|
|
167
|
+
match &self.on {
|
|
168
|
+
Trigger::BareEvent(_) => true,
|
|
169
|
+
Trigger::BareEvents(events) => events.len() == 1,
|
|
170
|
+
Trigger::Events(events) => events.count() == 1,
|
|
171
|
+
}
|
|
172
|
+
}
|
|
155
173
|
}
|
|
156
174
|
|
|
157
175
|
/// Common behavior across both normal and reusable jobs.
|
|
@@ -99,7 +99,7 @@ impl InputKey {
|
|
|
99
99
|
InputKey::Local(local) => local
|
|
100
100
|
.prefix
|
|
101
101
|
.as_ref()
|
|
102
|
-
.and_then(|pfx| local.given_path.strip_prefix(
|
|
102
|
+
.and_then(|pfx| local.given_path.strip_prefix(pfx).ok())
|
|
103
103
|
.unwrap_or_else(|| &local.given_path)
|
|
104
104
|
.as_str(),
|
|
105
105
|
InputKey::Remote(remote) => remote.path.as_str(),
|
|
@@ -436,6 +436,25 @@ fn excessive_permissions() -> Result<()> {
|
|
|
436
436
|
"excessive-permissions/workflow-default-perms-all-jobs-explicit.yml"
|
|
437
437
|
))
|
|
438
438
|
.run()?);
|
|
439
|
+
|
|
440
|
+
insta::assert_snapshot!(zizmor()
|
|
441
|
+
.workflow(workflow_under_test(
|
|
442
|
+
"excessive-permissions/issue-472-repro.yml"
|
|
443
|
+
))
|
|
444
|
+
.run()?);
|
|
445
|
+
|
|
446
|
+
insta::assert_snapshot!(zizmor()
|
|
447
|
+
.workflow(workflow_under_test(
|
|
448
|
+
"excessive-permissions/reusable-workflow-call.yml"
|
|
449
|
+
))
|
|
450
|
+
.run()?);
|
|
451
|
+
|
|
452
|
+
insta::assert_snapshot!(zizmor()
|
|
453
|
+
.workflow(workflow_under_test(
|
|
454
|
+
"excessive-permissions/reusable-workflow-other-triggers.yml"
|
|
455
|
+
))
|
|
456
|
+
.run()?);
|
|
457
|
+
|
|
439
458
|
Ok(())
|
|
440
459
|
}
|
|
441
460
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
source: tests/snapshot.rs
|
|
3
|
+
expression: "zizmor().workflow(workflow_under_test(\"excessive-permissions/issue-472-repro.yml\")).run()?"
|
|
4
|
+
snapshot_kind: text
|
|
5
|
+
---
|
|
6
|
+
warning[excessive-permissions]: overly broad permissions
|
|
7
|
+
--> @@INPUT@@:19:3
|
|
8
|
+
|
|
|
9
|
+
19 | / job2:
|
|
10
|
+
20 | | # normal permissions finding here, since callers are always
|
|
11
|
+
21 | | # responsible for setting permissions, even if the workflow
|
|
12
|
+
22 | | # is reusable-only
|
|
13
|
+
23 | | uses: ./.github/workflows/fake.yml
|
|
14
|
+
| | -
|
|
15
|
+
| |_______________________________________|
|
|
16
|
+
| this job
|
|
17
|
+
| default permissions used due to no permissions: block
|
|
18
|
+
|
|
|
19
|
+
= note: audit confidence → Medium
|
|
20
|
+
|
|
21
|
+
3 findings (2 suppressed): 0 unknown, 0 informational, 0 low, 1 medium, 0 high
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
source: tests/snapshot.rs
|
|
3
|
+
expression: "zizmor().workflow(workflow_under_test(\"excessive-permissions/reusable-workflow-call.yml\")).run()?"
|
|
4
|
+
snapshot_kind: text
|
|
5
|
+
---
|
|
6
|
+
warning[excessive-permissions]: overly broad permissions
|
|
7
|
+
--> @@INPUT@@:7:3
|
|
8
|
+
|
|
|
9
|
+
7 | / job1:
|
|
10
|
+
8 | | # finding: reusable jobs should always specify their permissions
|
|
11
|
+
9 | | uses: ./.github/workflows/zizmor-child.yml
|
|
12
|
+
| | -
|
|
13
|
+
| |_______________________________________________|
|
|
14
|
+
| this job
|
|
15
|
+
| default permissions used due to no permissions: block
|
|
16
|
+
|
|
|
17
|
+
= note: audit confidence → Medium
|
|
18
|
+
|
|
19
|
+
2 findings (1 suppressed): 0 unknown, 0 informational, 0 low, 1 medium, 0 high
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
source: tests/snapshot.rs
|
|
3
|
+
expression: "zizmor().workflow(workflow_under_test(\"excessive-permissions/reusable-workflow-other-triggers.yml\")).run()?"
|
|
4
|
+
snapshot_kind: text
|
|
5
|
+
---
|
|
6
|
+
warning[excessive-permissions]: overly broad permissions
|
|
7
|
+
--> @@INPUT@@:1:1
|
|
8
|
+
|
|
|
9
|
+
1 | / name: reusable-workflow-other-triggers
|
|
10
|
+
2 | |
|
|
11
|
+
... |
|
|
12
|
+
20 | | # responsible for setting permissions
|
|
13
|
+
21 | | uses: ./.github/workflows/fake.yml
|
|
14
|
+
| |_______________________________________- default permissions used due to no permissions: block
|
|
15
|
+
|
|
|
16
|
+
= note: audit confidence → Medium
|
|
17
|
+
|
|
18
|
+
warning[excessive-permissions]: overly broad permissions
|
|
19
|
+
--> @@INPUT@@:11:3
|
|
20
|
+
|
|
|
21
|
+
11 | / job1:
|
|
22
|
+
12 | | # regular job-level finding, since we can be triggered by
|
|
23
|
+
... |
|
|
24
|
+
15 | | steps:
|
|
25
|
+
16 | | - run: echo hello
|
|
26
|
+
| | -
|
|
27
|
+
| |_______________________|
|
|
28
|
+
| this job
|
|
29
|
+
| default permissions used due to no permissions: block
|
|
30
|
+
|
|
|
31
|
+
= note: audit confidence → Medium
|
|
32
|
+
|
|
33
|
+
warning[excessive-permissions]: overly broad permissions
|
|
34
|
+
--> @@INPUT@@:18:3
|
|
35
|
+
|
|
|
36
|
+
18 | / job2:
|
|
37
|
+
19 | | # normal permissions finding here, since callers are always
|
|
38
|
+
20 | | # responsible for setting permissions
|
|
39
|
+
21 | | uses: ./.github/workflows/fake.yml
|
|
40
|
+
| | -
|
|
41
|
+
| |_______________________________________|
|
|
42
|
+
| this job
|
|
43
|
+
| default permissions used due to no permissions: block
|
|
44
|
+
|
|
|
45
|
+
= note: audit confidence → Medium
|
|
46
|
+
|
|
47
|
+
3 findings: 0 unknown, 0 informational, 0 low, 3 medium, 0 high
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# repro case for https://github.com/woodruffw/zizmor/issues/472
|
|
2
|
+
|
|
3
|
+
name: issue-472-repro
|
|
4
|
+
|
|
5
|
+
on:
|
|
6
|
+
workflow_call:
|
|
7
|
+
|
|
8
|
+
# no non-pedantic top-level permissions finding, since
|
|
9
|
+
# the workflow is reusable-only
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
job1:
|
|
13
|
+
# no non-pedantic job-level permissions finding, since
|
|
14
|
+
# the workflow is reusable-only
|
|
15
|
+
runs-on: ubuntu-24.04
|
|
16
|
+
steps:
|
|
17
|
+
- run: echo hello
|
|
18
|
+
|
|
19
|
+
job2:
|
|
20
|
+
# normal permissions finding here, since callers are always
|
|
21
|
+
# responsible for setting permissions, even if the workflow
|
|
22
|
+
# is reusable-only
|
|
23
|
+
uses: ./.github/workflows/fake.yml
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: reusable-workflow-other-triggers
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
push:
|
|
6
|
+
|
|
7
|
+
# regular top-level finding, since we can be triggered by
|
|
8
|
+
# either a workflow call or a push
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
job1:
|
|
12
|
+
# regular job-level finding, since we can be triggered by
|
|
13
|
+
# either a workflow call or a push
|
|
14
|
+
runs-on: ubuntu-24.04
|
|
15
|
+
steps:
|
|
16
|
+
- run: echo hello
|
|
17
|
+
|
|
18
|
+
job2:
|
|
19
|
+
# normal permissions finding here, since callers are always
|
|
20
|
+
# responsible for setting permissions
|
|
21
|
+
uses: ./.github/workflows/fake.yml
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|