Skip to content

Convert Bash escaping to support linear regexp engine#2358

Merged
ericcornelissen merged 6 commits intomainfrom
lregexp-bash
Feb 8, 2026
Merged

Convert Bash escaping to support linear regexp engine#2358
ericcornelissen merged 6 commits intomainfrom
lregexp-bash

Conversation

@ericcornelissen
Copy link
Copy Markdown
Owner

Relates to #2122

Update `bash.js` to use the lregexp package to transparently create
regular expressions that use the linear engine in order to avoid any
ReDoS vulnerabilities. This commit target the logic behind Shescape's
`escape(All)` API only. The refactoring is mostly straightforward with
the exception of the logic for `~` (home directory expansion). Please
note that this logic is related to CVE-2022-24725, so extra care has
been taken to avoid re-introducing a vulnerability.

In particular, before this change there were two regular expressions
that escaped `~`, namely:

- `/(?<=^|\s)([#~])/gu`
- `/(?<=[:=])(~)(?=[\s+\-/0:=]|$)/gu`

The former is for the straightforward case where `~` (or `#`, comments)
is preceded by whitespace (or is at the start of the string, in which
case it is implicitly preceded by whitespace) in which case Bash expand
it to the user's home directory. The former is a more complicated case
in which

It is the second expression that has been changed. In particular, we now
always escape `~` when it is preceded by either `=` or `:` instead of
conditionally based on what succeeds it. The reason for this change is
that the linear regular expression engine does not support lookaheads,
but the suffix of the expression that used to be on line 19 may be part
of the prefix of the same expression. With lookaheads the succeeding
characters are not consumed so can be matched again for the prefix, but
without lookaheads this is not the case. For this reason we now escape
unconditionally (on the suffix), which also allows us to fold the two
separate expressions into one.

The impact of this change is that we may now unnecessarily escape `~`
in certain cases, as evidenced by the fixture changes, which 1) is not
a problem because it does not affect the meaning of the command, and 2)
is extremely rare in practice except for malicious commands.

As demonstrated by the explanation of the changes as well as the changes
to the test fixtures, this change should be safe (w.r.t. the concerns of
CVE-2022-24725) as the new implementation only escapes `~` in more
scenarios.
@ericcornelissen ericcornelissen added the refactor Changes existing code without changing functionality label Feb 3, 2026
@github-actions github-actions Bot added the test Relates to testing label Feb 3, 2026
@deepsource-io
Copy link
Copy Markdown

deepsource-io Bot commented Feb 3, 2026

Here's the code health analysis summary for commits 0e20f36..4c77eee. View details on DeepSource ↗.

Analysis Summary

AnalyzerStatusSummaryLink
DeepSource JavaScript LogoJavaScript✅ SuccessView Check ↗

💡 If you’re a repository administrator, you can configure the quality gates from the settings.

@ericcornelissen

This comment was marked as resolved.

@chatgpt-codex-connector

This comment was marked as outdated.

@ericcornelissen

This comment was marked as resolved.

@coderabbitai

This comment was marked as spam.

@coderabbitai

This comment was marked as spam.

@ericcornelissen ericcornelissen merged commit 4f72b2a into main Feb 8, 2026
45 checks passed
@ericcornelissen ericcornelissen deleted the lregexp-bash branch February 8, 2026 07:42
@ericcornelissen ericcornelissen changed the title Refactor regular expression for escaping for bash using lregexp Convert bash escaping to support linear regexp engine Mar 1, 2026
@ericcornelissen ericcornelissen changed the title Convert bash escaping to support linear regexp engine Convert Bash escaping to support linear regexp engine Apr 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactor Changes existing code without changing functionality test Relates to testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant