From 39a383662f2449acf5e6b0713923e8ed0f55e32c Mon Sep 17 00:00:00 2001 From: Matt Cowley Date: Tue, 16 Jan 2024 17:03:27 +0000 Subject: [PATCH] Restrict pattern for space-separated arguments in glob embed regex (#92) * Add test to reproduce ReDoS in glob regex * Restrict pattern for space-separated arguments in glob regex * Add to changelog --- CHANGELOG.md | 1 + rules/embeds/glob.js | 4 ++-- rules/embeds/glob.test.js | 12 +++++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40bc283..58e4def 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Any non-code changes should be prefixed with `(docs)`. See `PUBLISH.md` for instructions on how to publish a new version. --> +- (patch) Fix ReDoS in glob embed rule regex - (patch) Dependency updates - (patch) Mark markdown-it as a peer dependency diff --git a/rules/embeds/glob.js b/rules/embeds/glob.js index 68d82cb..e236792 100644 --- a/rules/embeds/glob.js +++ b/rules/embeds/glob.js @@ -1,5 +1,5 @@ /* -Copyright 2022 DigitalOcean +Copyright 2024 DigitalOcean Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -78,7 +78,7 @@ module.exports = md => { if (closingMark === -1) return false; // Check for glob match - const match = currentLines.slice(0, closingMark + 3).match(/^\[glob (.+?(?:(?: .+?)+|(?:\n.+?)+))\](?:$|\n)/); + const match = currentLines.slice(0, closingMark + 3).match(/^\[glob (.+?(?:(?: [^ \n]+?)+|(?:\n.+?)+))\](?:$|\n)/); if (!match) return false; // Get the full strings diff --git a/rules/embeds/glob.test.js b/rules/embeds/glob.test.js index 6981a9d..7b9ca24 100644 --- a/rules/embeds/glob.test.js +++ b/rules/embeds/glob.test.js @@ -1,5 +1,5 @@ /* -Copyright 2022 DigitalOcean +Copyright 2024 DigitalOcean Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -68,6 +68,16 @@ it('handles glob embeds with linebreaks and spaces in glob', () => { `); }); +it('handles glob embeds with many spaces in glob and a linebreak (ReDos)', () => { + expect(md.render(`[glob ${Array.from('a'.repeat(50)).join(' ')}\nb\nc]`)).toBe(`
+ + Explore ${Array.from('a'.repeat(50)).join(' ')} as a glob string in our glob testing tool + +
+ +`); +}); + it('handles glob embeds with multiple linebreaks (no embed)', () => { expect(md.render('[glob *.js\n\n/a\n\n/b]')).toBe(`

[glob *.js

/a