Skip to content

security: roave/security-advisories guard cannot be refreshed — blocked by web-token/jwt-framework ^3 (over-broad conflict rule) #2299

Description

@rubenvdlinde

Summary

The roave/security-advisories guard in composer.lock cannot be refreshed in this repo
without a major-version upgrade of web-token/jwt-framework, because the current guard tip
conflicts with the version this repo is pinned to.

This repo is therefore still running a stale guard, and is unprotected against every
advisory published since its pinned commit. Every other fleet repo was refreshed to the
2026-08-01 guard tip today; this one is blocked.

What the refresh demands

$ composer update roave/security-advisories --no-scripts --no-install

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - web-token/jwt-framework is locked to version 3.4.10 and an update of this
      package was not requested.
    - roave/security-advisories dev-latest conflicts with
      web-token/jwt-experimental <4.1.7
      (web-token/jwt-framework 3.4.10 replaces web-token/jwt-experimental self.version).
    - Root composer.json requires roave/security-advisories dev-latest
      -> satisfiable by roave/security-advisories[dev-latest].

composer.json pins "web-token/jwt-framework": "^3". The guard's conflict rule is
<4.1.7, so no 3.x release can satisfy it. Refreshing the guard requires changing
that constraint to ^4 — a major upgrade, and a composer.json change, not a lockfile
bump. That is out of scope for a security-guard refresh and needs its own change with
real testing.

Important: this is very probably a false positive in the guard, not a live vulnerability

We are pinned to web-token/jwt-framework 3.4.10, and every upstream advisory for that
package is fixed in exactly 3.4.10. From the Packagist advisory API:

Severity Affected versions Advisory
high <3.4.10 | >=4.0.0,<4.0.7 | >=4.1.0,<4.1.7 RSA1_5 decryption lacks implicit rejection — Bleichenbacher/Marvin padding oracle (GHSA-5739-39v2-5754)
high <3.4.10 | >=4.0.0,<4.0.7 | >=4.1.0,<4.1.7 Chacha20Poly1305 key-encryption discards the Poly1305 auth tag — no authentication on decrypt (GHSA-6vvh-pxr4-25r7)
medium <3.4.10 | >=4.0.0,<4.0.7 | >=4.1.0,<4.1.7 JWSVerifier uses algorithm from the unprotected header — algorithm confusion (GHSA-jc38-x7x8-2xc8)
<3.4.10 | >=4.0.0,<4.0.7 | >=4.1.0,<4.1.7 PBES2-HS*+A*KW unwrap accepts unbounded p2c — CPU amplification

composer audit --locked reports 0 advisories for this repo, consistent with the above.

The block comes from a replaces aliasing artifact:

  • The advisory as recorded against the split package web-token/jwt-experimental carries the
    range <=4.1.6without the <3.4.10 carve-out that the same advisory has against
    web-token/jwt-framework.
  • The monolithic jwt-framework package declares replace: web-token/jwt-experimental: self.version.
  • So Composer sees "jwt-experimental 3.4.10", tests it against <4.1.7, and conflicts —
    even though 3.4.10 is the patched 3.x release.

Note that roave encodes the range correctly for the sibling split packages:

web-token/jwt-library <3.4.10|>=4,<4.0.7|>=4.1,<4.1.7     <- correct
web-token/jwt-bundle  <3.4.10|>=4,<4.0.7|>=4.1,<4.1.7     <- correct
web-token/jwt-experimental <4.1.7                          <- over-broad
web-token/jwt-framework    <4.1.7                          <- over-broad

Options

  1. Upstream fix (preferred) — report the over-broad range to
    FriendsOfPHP/security-advisories
    so web-token/jwt-experimental and web-token/jwt-framework get the <3.4.10 carve-out.
    The guard then refreshes with no dependency change at all.
  2. Major upgrade — move composer.json to "web-token/jwt-framework": "^4" (>= 4.1.7)
    as its own change, with tests.
  3. Narrow the dependency — if only the JWT library surface is used, depend on
    web-token/jwt-library ^3.4.10 instead of the jwt-framework metapackage. The
    jwt-library conflict rule is correctly scoped, so this unblocks the guard immediately
    without a major upgrade. Needs a check of which sub-packages are actually used.

What was explicitly NOT done

  • No composer audit ignore/allow-list entry was added.
  • The guard was not removed or downgraded to make anything pass.

The guard staleness is left visible on purpose.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions