Skip to content

fix(scoring): cap labelPatternToRegExp wildcard groups to prevent ReDoS - #2481

Closed
luciferlive112116 wants to merge 1 commit into
JSONbored:mainfrom
luciferlive112116:fix/scoring-label-pattern-wildcard-cap
Closed

fix(scoring): cap labelPatternToRegExp wildcard groups to prevent ReDoS#2481
luciferlive112116 wants to merge 1 commit into
JSONbored:mainfrom
luciferlive112116:fix/scoring-label-pattern-wildcard-cap

Conversation

@luciferlive112116

Copy link
Copy Markdown
Contributor

Summary

Fixes #2456

labelPatternToRegExp in src/scoring/preview.ts compiles registry-supplied label_multipliers keys into anchored RegExps with unbounded chained * wildcards. A malicious or accidental key with too many * groups can make .test() catastrophically backtrack — the same ReDoS class globToRegExp in change-guardrail.ts already guards against (#2445).

This caps fnmatch label patterns at two wildcard groups (each * counts as one group). Over-complex patterns compile to a cached never-match RegExp instead of a pathological matcher, mirroring the fail-safe direction used elsewhere in scoring path compilation.

Scope

Validation

  • git diff --check
  • npm run typecheck
  • npm run test:coverage — extended label pattern matcher memoization with over-complex wildcard rejection and cap-boundary cases.
  • npm run test:ci

If any required check was skipped, explain why:

  • Node/npm is unavailable in this environment; CI will run the full gate on the PR.

Safety

  • No secrets/wallets/hotkeys; over-complex registry keys fail closed to never-match instead of hanging request handling.
  • No auth/API/UI change.

Notes

  • Reproduction: labelMatchesPattern("type:bug-fix", "*:*:*:*:*") previously compiled a ReDoS-prone RegExp; after the fix it returns false immediately via the cached never-match matcher. Two-wildcard patterns like *:* and type:* still match normally.

@dosubot dosubot Bot added the size:S label Jul 2, 2026
@loopover-orb

loopover-orb Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-02 05:40:31 UTC

2 files · 1 AI reviewer · no blockers · readiness 55/100 · CI green · clean

⏸️ Suggested Action - Manual Review

  • Touches a guarded path — held for manual review

Review summary
The change adds a cached fail-closed path for label patterns with more than two `*` wildcards and covers the rejection path plus the cap boundary in the existing matcher test group. The implementation is small, local to `labelPatternToRegExp`, and avoids compiling the pathological chained `.*` regexes while preserving normal literal and two-wildcard cases shown in the tests. CI is green on the provided commit and I do not see a reachable correctness break in the visible diff.

Nits — 6 non-blocking
  • nit: `src/scoring/preview.ts:949` counts every `*` byte before glob parsing, so please confirm bracket-literal forms such as `[*]` are intentionally counted against the wildcard cap rather than treated as non-wildcard syntax.
  • nit: `test/unit/scoring.test.ts:1922` verifies repeated calls return false, but it does not directly prove the over-complex pattern is memoized to the never-match regex rather than re-counted each time.
  • Add a small boundary test in `test/unit/scoring.test.ts` for adjacent wildcards such as `**:*` or `***` so the intended “each `*` counts” behavior is locked down.
  • If bracket expressions are supported by `labelPatternToRegExp`, add a test for `[*]` or document in `src/scoring/preview.ts` that the cap deliberately treats literal-star bracket syntax as complexity too.
  • Readiness score is below the configured threshold — Use the readiness panel as advisory maintainer context; the score does not block this PR.
  • Touches a guarded path — held for manual review — A maintainer must review and merge this change.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #2456
Related work ⚠️ 2 scoped overlaps Top overlaps are listed below; lower-confidence bulk is hidden.
Change scope ❌ 8/20 High review scope from cached public metadata (size label size:S; 1 linked issue).
Validation posture ❌ 5/25 Preflight is holding this PR: the review lane is unavailable, so it is not ready for automated review.
Contributor workload ✅ 10/10 Author activity: 29 registered-repo PR(s), 11 merged, 7 issue(s).
Contributor context ✅ Confirmed Gittensor contributor luciferlive112116; Gittensor profile; 29 PR(s), 7 issue(s).
Gate result ⚠️ Not blocking Advisory; not blocking this PR.
Review context
Contributor next steps
  • Review top overlaps.
  • Add a concise scope and risk note.
  • Await review-lane availability.
  • Triage stale or unlinked PRs.
  • Refresh registry data or choose a registered active repo.
  • Check active issues and PRs before submitting.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

@loopover-orb loopover-orb Bot added gittensor gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. labels Jul 2, 2026
@codecov

codecov Bot commented Jul 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.94%. Comparing base (118d537) to head (8257cff).
⚠️ Report is 22 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2481      +/-   ##
==========================================
+ Coverage   95.93%   95.94%   +0.01%     
==========================================
  Files         225      226       +1     
  Lines       25338    25382      +44     
  Branches     9218     9231      +13     
==========================================
+ Hits        24308    24354      +46     
  Misses        417      417              
+ Partials      613      611       -2     
Files with missing lines Coverage Δ
src/scoring/preview.ts 99.13% <100.00%> (+0.02%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@dosubot dosubot Bot added the lgtm label Jul 2, 2026
@JSONbored
JSONbored self-requested a review July 2, 2026 05:44

@JSONbored JSONbored left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a maintainer only issue, closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier.

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

fix(scoring): cap labelPatternToRegExp wildcard groups to prevent ReDoS

2 participants