Skip to content

fix(security): restrict core-ref to existing tags only#48

Draft
DeepDiver1975 wants to merge 1 commit intomainfrom
fix/security-core-ref-tags-only
Draft

fix(security): restrict core-ref to existing tags only#48
DeepDiver1975 wants to merge 1 commit intomainfrom
fix/security-core-ref-tags-only

Conversation

@DeepDiver1975
Copy link
Copy Markdown
Member

Summary

Supersedes #45, which added a character-allowlist check that is insufficient on its own.

The root problem: core-ref is passed directly to actions/checkout's ref: parameter, then make runs against the checked-out code. An attacker who can influence the core-ref value can point the checkout at code they control, getting arbitrary execution via the Makefile.

Why #45's regex is not enough:
A character-allowlist ([a-zA-Z0-9._/=-]+) blocks obviously malformed values but still permits:

  • Branch names like main (mutable — can change under you)
  • PR head refs like refs/pull/9999/head — this is the main attack vector: an attacker opens a PR against owncloud/core with a malicious Makefile, then points core-ref at refs/pull/9999/head. GitHub creates this ref automatically for every open PR, no merge required.

This PR's fix — two-stage validation:

  1. Slash check after prefix stripping — strips the optional refs/tags/ prefix then rejects any remaining /. This blocks refs/pull/N/head, refs/heads/branch, and any other full ref path while still accepting short tag names (v10.14.0) and the explicit refs/tags/v10.14.0 form.

  2. git ls-remote --tags existence check — confirms the value resolves to an actual tag in owncloud/core. This prevents:

    • Non-existent values from silently falling back to the default branch
    • Branch names that happen to contain no slash (e.g., main) — these have no matching refs/tags/main entry and will fail

What callers need to do

No change for callers already using tag names like v10.14.0. Callers using branch names or omitting core-ref entirely (defaults to '', which skips validation) are unaffected.

Test plan

  • core-ref: v10.14.0 — passes (existing tag, no slash)
  • core-ref: refs/tags/v10.14.0 — passes (prefix stripped, tag verified)
  • core-ref: refs/pull/9999/head — rejected at slash check
  • core-ref: main — rejected at git ls-remote check (no refs/tags/main in owncloud/core)
  • core-ref: v99.99.99 — rejected at git ls-remote check (tag does not exist)
  • core-ref: '' (default) — validation step skipped entirely

🤖 Generated with Claude Code

Replace the loose character-allowlist validation from the earlier fix
with a two-stage check that:
1. Strips an optional refs/tags/ prefix then rejects any remaining
   slash, blocking branch refs (refs/heads/...) and PR head refs
   (refs/pull/N/head) which pass character-only validation but point
   at mutable or attacker-controlled code.
2. Uses git ls-remote --tags to confirm the value resolves to an
   actual annotated or lightweight tag in owncloud/core, so a caller
   cannot silently supply a non-existent or branch-shaped ref.

Also updates input descriptions to document the tag-only constraint.
@DeepDiver1975 DeepDiver1975 force-pushed the fix/security-core-ref-tags-only branch from 375bea8 to 0626f62 Compare April 17, 2026 08:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant