Sortable icon indicating copy to clipboard operation
Sortable copied to clipboard

fix(prettify): replace regex-based query parsing to avoid ReDoS

Open wukunyu264 opened this issue 6 months ago • 0 comments

Checklist (per Contribution Guidelines) Target branch is master

Only source files are modified (st/prettify/run_prettify.js)

No build artifacts are committed (builds will be generated on release)

Local setup: npm i completed

Verified locally that the change works as expected

Background

In st/prettify/run_prettify.js, the query string was parsed via a global regex replace:

B.replace(/[?&]([^&=]+)=([^&]+)/g, function (g, r, x) {
  x = decodeURIComponent(x);
  r = decodeURIComponent(r);
  r == "autorun" ? (U = !/^[0fn]/i.test(x))
    : r == "lang" ? H.push(x)
    : r == "skin" ? P.push(x)
    : r == "callback" && M.push(x);
});

This pattern can suffer from catastrophic backtracking on crafted inputs (e.g. '?'.repeat(100000) + '=') and leads to a potential ReDoS risk if the query is attacker-controlled.

Solution

Replace the regex-based parsing with a linear, index-based split that preserves behavior but avoids backtracking:

B.split(/[?&]/).forEach(function (s) {
  if (!s) return;
  var i = s.indexOf('=');
  if (i < 0 || i === s.length - 1) return; // ignore invalid / valueless pairs

  var r = decodeURIComponent(s.slice(0, i));
  var x = decodeURIComponent(s.slice(i + 1));

  r == 'autorun' ? (U = !/^[0fn]/i.test(x))
    : r == 'lang' ? H.push(x)
    : r == 'skin' ? P.push(x)
    : r == 'callback' && M.push(x);
});

Why safer: No backtracking hotspots; runtime grows linearly with input length. Behavior: Keys handled are unchanged (autorun, lang, skin, callback); invalid pairs are ignored just like before; decodeURIComponent preserved.

Screenshots

before: image after: 屏幕截图 2025-08-12 144435

Type of change

Bug fix (non-breaking change which fixes an issue)

Notes

If the project prefers tests to be in its existing framework only, I can adjust or remove the accompanying regression test.

wukunyu264 avatar Aug 12 '25 09:08 wukunyu264