1
0
mirror of https://github.com/lancedikson/bowser synced 2026-09-23 20:44:24 +00:00

fix: resolve open GitHub security findings (#630)

This commit is contained in:
Naor Peled
2026-08-30 21:05:22 +03:00
committed by GitHub
parent a88622557d
commit 1d7923497f
7 changed files with 322 additions and 563 deletions

39
test/unit/redos.js Normal file
View File

@@ -0,0 +1,39 @@
import test from 'ava';
import Bowser from '../../src/bowser';
/*
* Regression tests for CodeQL js/polynomial-redos. Each input used to drive a
* quadratic backtracking path; fixed, they parse in single-digit milliseconds,
* so this budget has ~2 orders of magnitude of headroom and is not machine-sensitive.
*/
const TIME_BUDGET_MS = 500;
function timeParse(ua) {
const startedAt = process.hrtime.bigint();
Bowser.parse(ua);
return Number(process.hrtime.bigint() - startedAt) / 1e6;
}
test('parses a Linespider UA made of repeated name tokens in linear time', (t) => {
const ua = 'linespider-'.repeat(20000);
const elapsed = timeParse(ua);
t.true(elapsed < TIME_BUDGET_MS, `took ${elapsed.toFixed(0)}ms, budget ${TIME_BUDGET_MS}ms`);
});
test('parses a SlackBot UA made of repeated name tokens in linear time', (t) => {
const ua = 'slackbot-'.repeat(20000);
const elapsed = timeParse(ua);
t.true(elapsed < TIME_BUDGET_MS, `took ${elapsed.toFixed(0)}ms, budget ${TIME_BUDGET_MS}ms`);
});
test('parses an unrecognised slash-heavy UA without a device spec in linear time', (t) => {
const ua = `/${'/a'.repeat(60000)}`;
const elapsed = timeParse(ua);
t.true(elapsed < TIME_BUDGET_MS, `took ${elapsed.toFixed(0)}ms, budget ${TIME_BUDGET_MS}ms`);
});
test('parses an unrecognised slash-heavy UA with a device spec in linear time', (t) => {
const ua = `/${'/a'.repeat(60000)}(`;
const elapsed = timeParse(ua);
t.true(elapsed < TIME_BUDGET_MS, `took ${elapsed.toFixed(0)}ms, budget ${TIME_BUDGET_MS}ms`);
});