github / github/codeql

Unpinned floating tags (e.g. `v4`) on immutable Actions are not flagged by `actions/unpinned-tag`

Open
#22,414 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
CodeQL
Stars
10.1k
Forks
2.1k
Avg merge
2d 15h
Merged PRs (30d)
141

Description

**Description of the issue**

The `actions/unpinned-tag` query (`actions/ql/src/Security/CWE-829/UnpinnedActionsTag.ql`) exempts any Action on the immutable-actions allow list from the unpinned-tag warning, regardless of the ref used. The exclusion is version-independent:

```ql
not exists(UsesStep step | uses = step and isImmutableAction(step, nwo))
```

and `isImmutableAction` (`actions/ql/lib/codeql/actions/security/UseOfUnversionedImmutableAction.qll`) only checks membership in `immutableActionsDataModel(nwo)`; it never inspects the version.

**Why this is a gap**

GitHub's immutability guarantee only applies to fully-expanded SemVer release tags (`vX.Y.Z`) and full commit SHAs. Floating tags such as `v4`, `v4.0` and `main` remain mutable: maintainers move them to the latest matching release, so they can change under a consumer exactly like any other tag. See [Using immutable releases and tags to manage your action's releases](https://docs.github.com/en/actions/how-tos/create-and-publish-actions/using-immutable-releases-and-tags-to-manage-your-actions-releases).

As a result, a reference like `actions/checkout@v2` is flagged by neither query:

- `UnpinnedActionsTag` skips it because `actions/checkout` is on the immutable list.
- `UnversionedImmutableAction` skips it because its `isSemVer` predicate accepts a bare major tag like `v2`.

So a genuinely mutable floating tag on an immutable Action goes unwarned.

**Suggested direction**

Narrow the exemption so an immutable Action is only exempt when pinned to a full `vX.Y.Z` (or a SHA), for example:

```ql
not (isImmutableAction(step, nwo) and isFullSemVer(version))
```

with an `isFullSemVer` stricter than the current `isSemVer` (which also matches floating `vX` and `vX.Y`). This would need care because the immutable-action model is shared with the experimental `UnversionedImmutableAction` query, and it would increase alert volume for consumers pinning immutable Actions to floating major tags, so it deserves its own change note and review.

Filed as a follow-up to #22409 (which is scoped to the trusted-owner allow list and does not address this).

Contributor guide

Open the contributing guide

Research direction

Read actions/ql/src/Security/CWE-829/UnpinnedActionsTag.ql and actions/ql/lib/codeql/actions/security/UseOfUnversionedImmutableAction.qll, starting with isImmutableAction and the existing SemVer predicate. Done means full vX.Y.Z tags and full SHAs remain exempt while floating refs such as vX and vX.Y are reported, with the required change note included.

Written by the indexing model from the issue text.

Assessment

Domain
security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.