Skip to content

build: close NU1903 (AutoMapper CVE) while staying on the last free MIT version - #588

Merged
jsboige merged 1 commit into
masterfrom
fix/automapper-nu1903-mit-pure
Jun 23, 2026
Merged

build: close NU1903 (AutoMapper CVE) while staying on the last free MIT version#588
jsboige merged 1 commit into
masterfrom
fix/automapper-nu1903-mit-pure

Conversation

@jsboige

@jsboige jsboige commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Contexte

Suite à la décision jsboige (interactif, 2026-06-23) sur NU1903 (AutoMapper 14.0.0, GHSA-rvv3-g6hj-g44x / CVE-2026-32933, DoS par récursion non bornée, sévérité 7.5).

Recherche (vérifiée) : il n'existe aucune version free patchée. Le fix n'est livré que sur 15.1.1 / 16.1.1, qui appartiennent à la ligne commerciale dual-licence d'AutoMapper (le passage commercial est à v15.0 ; 14.x ne reçoit aucun patch — confirmé par le mainteneur). 14.0.0 EST déjà la dernière version libre MIT — il n'y a pas de bump free possible.

Décision jsboige : « on reste en MIT pur, mais migre vers la dernière version libre ». → On est déjà sur la dernière version libre (14.0.0) ; on garde le repo MIT-pur et on clôt NU1903 par justification, sans adopter une dépendance commerciale.

Pourquoi le vuln n'est pas atteignable ici

Le seul Profile AutoMapper est une map plate et acyclique : CreateMap<ArgumentVirtue, Fallacy>() avec uniquement des ForMember scalaires + ReverseMap() (cf Entities/MappingProfile.cs). Le chemin de récursion vulnérable n'est jamais emprunté.

Changements

  • MappingProfile.cs : MaxDepth(1) explicite dans les deux sens — reproduit le fix vendeur (MaxDepth par défaut), borne explicite (ceinture-bretelles, output-neutral sur une map plate).
  • .csproj : <NuGetAuditSuppress Include="https://github.com/advisories/GHSA-rvv3-g6hj-g44x" /> — suppression ciblée sur CE seul advisory (pas un NoWarn global), commentée avec le rationale complet.

Validation

  • ✅ Build solution : zéro warning CS ET NU (NU1903 clos)
  • ✅ Tests : 533 passed / 0 failed / 5 skipped (MaxDepth(1) vérifié output-neutral — mapping inchangé)

Avec #587 (warnings CS) + cette PR, le build est intégralement zéro-warning pour la release v0.9.0.

🤖 Generated with Claude Code

…IT version

Decision jsboige 2026-06-23: keep the repo MIT-pure rather than adopt AutoMapper's
commercial dual-licensed line. 14.0.0 is the LAST free MIT version — 15.0.0+ is the
commercial line and there is NO free patched build (14.x receives no fix for
GHSA-rvv3-g6hj-g44x). "Migrate to the latest free version" is already satisfied:
14.0.0 IS the latest free version.

The advisory (CVE-2026-32933, DoS via uncontrolled recursion) is not reachable here:
the only AutoMapper Profile is a flat, acyclic ArgumentVirtue<->Fallacy map (scalar
ForMember projections only), so the vulnerable recursion path is never taken.

- MappingProfile.cs: add explicit MaxDepth(1) on both directions — mirrors the vendor's
  MaxDepth-default fix, makes the bound explicit (belt-and-suspenders, output-neutral on
  a flat map).
- .csproj: targeted <NuGetAuditSuppress> for THIS advisory only (not a blanket NoWarn),
  with a comment documenting the rationale.

Build is now fully zero-warning (CS + NU). Tests: 533 passed / 0 failed / 5 skipped
(MaxDepth(1) verified output-neutral).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jsboige
jsboige merged commit 6caf583 into master Jun 23, 2026
3 checks passed
@jsboige
jsboige deleted the fix/automapper-nu1903-mit-pure branch June 23, 2026 10:44
jsboige added a commit that referenced this pull request Jul 26, 2026
…vendored npm + AutoMapper) (#910)

No dependabot.yml existed in the repo; dependabot was running on GitHub UI/auto-detected
config and produced ~34 PRs in a single cycle (mostly the same package bumped across many
vendored 2sxc module trees — e.g. loader-utils x5, json5 x4, braces x2). This adds an explicit
config encoding the policy ai-01 dispatched (`3zhzkb`):

  1. nuget (our .NET pipeline)         -> group + ignore AutoMapper majors (license barrier)
  2. npm vendored DNNPlatform trees     -> group + ignore majors (unvalidated in CI)
  3. npm our trees (CardPen, pdf-val)   -> group + ignore majors

Why groups: collapses multiple same-directory bumps into ONE pull request (N-per-dir -> 1-per-dir).

Why ignore-major on npm vendored: a major bump edits package.json in a tree that nothing in CI
builds or consumes — #901 (webpack-dev-server 5->6 in Bootstrap 4 Instant) is the canonical
case ai-01 held for exactly this reason. Patch/minor are lockfile-only no-ops, merged per
precedent #120.

Why ignore-major on AutoMapper: 14.0.0 is the LAST MIT release; 15.0.0+ flips to RPL-1.5 /
commercial (Lucky Penny). Pinned by decision jsboige 2026-06-23 (#588); ignoring the major at
the source stops dependabot re-proposing the commercial line (#887).

Directories are enumerated exactly because dependabot does NOT glob directories — each block
targets one path. The vendored list (26 trees) is generated from `find package-lock.json`, not
hand-typed (gen script in scratchpad).

OPEN AS A PR — NOT merged. Scope is a deliberate jsboige arbitration (see PR body, option A vs B).

Co-authored-by: Your <your.email@example.com>
Co-authored-by: Claude-Code <noreply@anthropic.com>
jsboige added a commit that referenced this pull request Jul 26, 2026
…ot bumps (#942) (#943)

The first grouped nuget PR under the #910 policy (#941) bundled 24 updates,
three of which move packages CLAUDE.md pins for licence or runtime reasons:

  QuestPDF                     2022.12.12 -> 2026.7.1
  SkiaSharp.NativeAssets.Win32 2.88.6     -> 4.150.1
  Microsoft.Playwright         1.43.0     -> 1.61.0

QuestPDF is the load-bearing one, and it is measured, not assumed. NuGet catalog,
2026-07-26:

  questpdf 2022.12.12  licenseExpression = "MIT"
  questpdf 2026.7.1    licenseExpression = (none), licenseUrl = aka.ms/deprecateLicenseUrl

i.e. the embedded <license type="file"> form — the exact mechanism #905 identified as
invisible to expression-only scanners (same shape as FluentAssertions 8.x). The #905
release gate reports "24/24 permissive" by reading those SPDX expressions, so merging
#941 would remove the evidence that gate stands on, days after it passed as a #134 gate.

Skia and Playwright are compatibility pins, majors only: Skia is QuestPDF's native
backend and must move with it; Playwright 1.43.0 is what the CI Test step has been
launching real Chromium with since #911, mirror-fallback included.

Deliberately NOT a blanket major filter on .NET. Grouping is all-or-nothing, so the
list names only pins that are already-recorded decisions (#588, #905, CLAUDE.md
"Stable Dependency Versions"); everything else keeps flowing and is triaged on merit.
Newtonsoft 13.0.3->13.0.4, PdfPig, dotNetRdf, CsvHelper and the rest of #941 remain
available for a deliberate tested pass after the tag.

Validated: 29 update blocks preserved, schemastore dependabot-2.0 PASS.

Refs #942, #905, #910, #941

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
jsboige added a commit that referenced this pull request Jul 27, 2026
…949 condition 2 (#955)

Downgrade FluentAssertions 8.5.0 -> 7.2.2 in Tests.csproj and add a
semver-major `ignore` entry in dependabot.yml, in the same PR.

License MEASURED on the restored nuspecs (license=truth, not ai-01's claim
taken on faith):
  7.2.2 -> license expression "Apache-2.0" (licenseUrl licenses.nuget.org/Apache-2.0)
  8.5.0 -> license expression "LICENSE" (literal token, not SPDX) + licenseUrl
           aka.ms/deprecateLicenseUrl — the opaque commercial-Xceed shape #905
           flagged as invisible to expression-only scanners.

8.0+ is commercial Xceed; 7.2.2 is the last Apache-2.0 release. Licence-purity
pin on the same basis as AutoMapper #588 and the PdfPig swap #908. #949 proposed
8.10.0 inside a grouped bump and would have shipped the commercial line; ai-01's
#949 disposition names this downgrade + its ignore entry as merge condition 2
(owner po-2024).

Sequence matters (ai-01: "la séquence importe"): the downgrade ships WITH the
ignore entry so dependabot never re-proposes 8.x. semver-major only — 7.2.x
Apache patches keep flowing; only the 7->8 commercial jump is blocked.

Verified empirically (post-#909: cite the summary line, not the check color):
  Debug   build 0 warn/0 err; test «échec: 0, réussite: 638, ignorée(s): 5»
  Release build 0 warn/0 err; test «échec: 0, réussite: 638, ignorée(s): 5»
Baseline 638/0/5 held across both matrix legs. The 8->7 downgrade compiles
clean across all 67 files using FluentAssertions (test code uses only APIs
stable across 7.x/8.x).

Lane: po-2024 (license-hygiene, per #905/#908 precedent). 0 prod write, 0 OWL
path touched (publication-safe). Tracking #949 disposition condition 2.

Co-authored-by: Your <your.email@example.com>
Co-authored-by: Claude-Code <noreply@anthropic.com>
jsboige added a commit that referenced this pull request Jul 28, 2026
…follow-up) (#962)

The release-gate dossier carried six facts measured stale against master
3094d42. All are mechanical/premise drift from July merges — no verdict,
no release scope changed. This pass corrects the dossier body that #959
(header/§0) deliberately left untouched.

1. §3.2 Virtues .content.svg were marked FR-figé ("gap structural"). FALSE:
   Argumentum_Virtues_MindMap_{lang}.content.svg are native-script 8/8,
   committed via #665/#715/#724/#686 (9f52446). Distinct-size proof
   (git cat-file -s): fr 431931 / en 418954 / ru 485254 / pt 446948 /
   es 432142 / ar 461859 / fa 461654 / zh 1148677 — a FR clone would be
   ~431931 everywhere. Twin premise of #636 (CLOSED 2026-07-06), false for
   the same reason. Marked RÉSOLU.

2. §3.2 es/ar/fa/zh mindmap SVG count 3 → 5 each (git ls-files | wc -l).
   fr 6 / en 5 / ru 5 / pt 5 / es 5 / ar 5 / fa 5 / zh 5.

3. §4 tests 596/601 → 643/638/0/5 (CI run 30280070312, both matrix legs),
   aligning with §0/#959. The 596/601 was pre-#911 (Test step was a no-op).

4. §4 Magick.NET 14.14.0 → 14.15.0 (#871 6f1a6e1a, 5 advisories patched).
   Also adds AutoMapper 14.0.0 (#588) and PdfPig 0.1.14 official (#908).

5. §3.6 + §5.8 + §7 + §8.2(c) "PT titre English Channel — open finding,
   appel à décision" → RÉSOLU. git grep "English Channel" -- Cards/ = 0.
   Per ai-01 precision: the string lived in an EMBEDDED csv key that is
   IGNORED at runtime (HarvestManager.cs overwrites it with the real CSV),
   so the defect never reached a card — NOT "resolved by #803". The
   observed mistranslation was stale-harvest, not a live prod defect.
   Separated from PT row-1 cover contamination (#306, distinct, also closed).

6. §5.4(a) + §8.2(a) #636 "arbitrage ouvert" → CLOSED 2026-07-06 (twin
   premise of #1).

Every value above is re-read at source (git ls-files / cat-file -s / grep /
gh issue view), not taken from an intermediate report. 3 audit-probe
imperfections (Fallacies/Scenarii counts grabbed Archive/2022; skos:prefLabel
grep namespace-split) are documented honestly in the audit report, not masked.

Scope: 1 docs file, docs-only, 0 prod write, 0 OWL, 0 CSV. Correction PR,
decision to merge = ai-01 (pre-tag sensitive zone, #134 gate).

Audit report: docs/investigations/2026-07-28-release-validation-v0.9.0-audit.md
(landed in #961). This PR is the body-correction follow-up ai-01 gave GO on
(arbitrage qgsvq4, 2 precisions applied: "n'a jamais atteint une carte"
phrasing + PT vs EN distinct #306).

Co-authored-by: Your <your.email@example.com>
Co-authored-by: Claude-Code <noreply@anthropic.com>
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