Skip to content

ISS-6235: record the array-component bypass GHSA-rmj7-2vxq-3g9f, and assert it - #33

Open
mbryzek wants to merge 3 commits into
mainfrom
i6235
Open

ISS-6235: record the array-component bypass GHSA-rmj7-2vxq-3g9f, and assert it#33
mbryzek wants to merge 3 commits into
mainfrom
i6235

Conversation

@mbryzek

@mbryzek mbryzek commented Aug 26, 2026

Copy link
Copy Markdown
Owner

Closes the GHSA-rmj7-2vxq-3g9f advisory record for this repository.

What this is

A resume. The branch i6235 was already pushed and this pull request already open (no
prior review on it). Merge-on-ready returned conflicts on lib-util#31 at head 8624be2c
and requeued the issue; all four branches on this issue are brought up to date together.
origin/main has been merged in — never rebased — and the conflict is resolved by taking
main's Jackson block. The branch's earlier diff is gone; what is below is what it now
contains.

The advisory is already remediated on main, and the earlier diff was wrong

BasicPolymorphicTypeValidator.Builder.allowIfSubTypeIsArray() allowlisted any array on
clazz.isArray() alone and never validated the component type, so a validator configured
to permit arrays admitted an array of a denied class and instantiated its elements with no
further check. Fixed in 2.18.8 and 2.21.4; affected >=2.10.0 <2.18.8 || >=2.19.0 <2.21.4.

Three pull requests landed on main between this branch being cut and this session
(ISS-6227, ISS-6229, ISS-6233) and they pin the entire Jackson family at 2.22.2 through
ThisBuild / dependencyOverrides — out of this advisory's range on both lines. The fleet's
scanner asks sbt what the build resolves rather than parsing build.sbt
(ocaml/lib/security_sbt_dependencies.ml), so a dependencyOverrides pin is exactly what
it reads. The resolved classpath needs no change.

The earlier commit on this branch declared the Jackson artifacts at compile scope so the
floor would reach consumers through the published POM. That is dropped, on two grounds:

  1. main's own comment states the opposite decision explicitly and with its reasons — the
    pin "governs THIS build's resolution only … and imposes no floor on a consumer. A consumer
    states its own, as platform and acumen do." Re-litigating a decision recorded in the code
    on a security-sweep branch is not this issue's business.
  2. This library imports no Jackson type of its own, so a compile-scope dependency would
    declare a dependency the code does not have.

What this pull request actually changes

The gap main left is documentation and coverage, not resolution — and this repo has a
precedent for closing it, because ISS-6229 did exactly this for the advisory that shares the
same range:

  • build.sbt — the floor paragraph named three advisories; it now names four, with the
    array-component bypass stated as behaviour rather than as a version number. The range is
    unchanged: GHSA-rmj7-2vxq-3g9f shares the 2.18.8 / 2.21.4 boundaries GHSA-j3rv-43j4-c7qm
    already set, so the pin does not move.
  • JacksonPinSpec — a fifth assertion. It builds a validator with
    allowIfSubTypeIsArray() plus one allowed concrete container, names a denied type as an
    array's component ([Ljava.util.HashMap;), and requires the refusal. A version number
    cannot be read off a classpath at runtime; this can.

Verification

  • The new assertion discriminates. Against the pinned 2.22.2 the spec is 5/5 green.
    With jacksonVersion temporarily moved to 2.18.7 (inside the range) it fails, next to
    the generics assertion that shares the range:

    - must apply the PolymorphicTypeValidator to a type id's generic ARGUMENTS … *** FAILED ***
    - must apply the PolymorphicTypeValidator to an array's COMPONENT type … *** FAILED ***
    Tests: succeeded 3, failed 2
    

    The pin was restored before committing; build.sbt still reads 2.22.2.

  • Full ci/build.sh clean at the pushed head (the fleet pre-push hook ran it), all tests
    passing.

Decisions & assumptions

  • Advisory floor over head-of-line. 2.22.2 is above the advisory's own 2.18.8 floor and is
    what platform and acumen pin, so consumers resolve one Jackson rather than two. Not changed
    here — inherited from main.
  • No compile-scope declaration, per the two grounds above. If the POM-floor question is
    worth revisiting it is a policy decision across all four libraries and their consumers, not
    a side effect of a security sweep.
  • The advisory record ends up satisfied by main's pin; this pull request is what keeps a
    future regression of that pin from passing silently.

Alternatives considered

  • Close these four pull requests as superseded. main already resolves out of range, so
    nothing was strictly owed. Rejected: the pin is the only thing standing between these repos
    and the advisory, and until this change nothing in the repo asserted the array bypass — a
    later bump back onto an affected line would have gone green.
  • Bump to the advisory's literal 2.18.8 target. Rejected: it is a floor, not a target, and
    moving down from 2.22.2 would reopen GHSA-r7wm-3cxj-wff9's neighbourhood and split the
    version from what the consumers run.
  • Keep the compile-scope declarations and merge them on top of main's overrides. Rejected
    — see "the earlier diff was wrong".

Related

Jackson reaches this library only transitively at 2.14.3, inside the affected
range. Declare the compile-classpath artifacts directly at 2.22.2 so the fix
reaches consumers through the published POM, and pin the test-only ones with
dependencyOverrides so they stay out of it.
@mbryzek
mbryzek marked this pull request as ready for review August 26, 2026 03:45
main pins the whole Jackson family at 2.22.2 through ThisBuild / dependencyOverrides
(ISS-6227, ISS-6229, ISS-6233), which is out of the GHSA-rmj7-2vxq-3g9f range and is
what the sbt-resolution scan reads. This branch's compile-scope declarations are
dropped in favour of that block: main states, with its reasons, that the pin governs
this build's resolution and imposes no floor on a consumer, and this library imports
no Jackson type of its own to declare a dependency for.
…assert it

The Jackson pin main already carries is out of this advisory's range, so the resolved
classpath needs no change. What was missing is the same thing ISS-6229 added for the
advisory sharing that range: a statement of which behaviour sets the floor, and an
assertion that fails by name when the pin slips back into it.

BasicPolymorphicTypeValidator answered allowIfSubTypeIsArray on clazz.isArray() alone
and never validated the array's component type, so a validator configured to allow
arrays admitted an array of a denied class and instantiated its elements with no
further check. The new assertion names a denied type as an array component and asks
for the refusal; run against 2.18.7 it fails, alongside the generics one that shares
the range.
@mbryzek mbryzek changed the title ISS-6235: move Jackson out of the GHSA-rmj7-2vxq-3g9f range ISS-6235: record the array-component bypass GHSA-rmj7-2vxq-3g9f, and assert it Aug 26, 2026
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