Skip to content

ReDoS Vulnerability in Jekyll LiveReload CSS URL Parsing #9868

@guiyi-he

Description

@guiyi-he

Summary

A Regular Expression Denial of Service (ReDoS) vulnerability exists in the Jekyll LiveReload functionality due to a vulnerable regex pattern used for parsing CSS url() functions.

Image As shown in the figure, the matching between the regular term and the attack string is nonlinear, and the time growth curve approaches exponential, indicating a ReDos vulnerability. For details, please refer to the website: https://mmmsssttt404.github.io/ReDos-Line-Chart-Drawing/

Vulnerability Details

Location: lib/jekyll/commands/serve/livereload_assets/livereload.js
Vulnerable Code:

newValue = value.replace(/\burl\s*\(([^)]*)\)/, (function(_this) {

Vulnerable Pattern: \burl\s*\(([^)]*)\)

Attack Vector

The regex pattern ([^)]*) creates a catastrophic backtracking scenario when processing malicious input. An attacker can exploit this by providing input such as:

"url(" + "url(".repeat(100000) + "\u0000"

This payload causes the regex engine to perform exponential backtracking, leading to:

  • High CPU consumption
  • Application hang/freeze
  • Potential denial of service

Impact

  • Severity: High
  • Attack Type: Regular Expression Denial of Service (ReDoS)
  • Affected Component: Jekyll LiveReload CSS processing
  • Impact: Application becomes unresponsive, potential DoS

Root Cause Analysis

The vulnerability stems from the nested quantifier ([^)]*) which attempts to match any character except ) zero or more times. When the input contains many opening parentheses followed by a character that doesn't match the expected closing pattern, the regex engine tries all possible combinations, causing exponential time complexity.

Recommended Fix

Replace the vulnerable regex pattern with a more robust version using negative lookahead to prevent catastrophic backtracking:

Current (Vulnerable):

/\burl\s*\(([^)]*)\)/

Fixed (Secure):

/\burl\s*\(([^)]*?)(?=\))\)/

Or even better, use a more restrictive pattern:

/\burl\s*\((['"]?)([^'")\s]+)\1\)/

Complete Fix Implementation:

// Replace the vulnerable line:
newValue = value.replace(/\burl\s*\(([^)]*)\)/, (function(_this) {

// With the secure version:
newValue = value.replace(/\burl\s*\((['"]?)([^'")\s]+)\1\)/, (function(_this) {

Verification

To verify the fix:

  1. Before Fix: Test with the attack payload - application should hang
  2. After Fix: Same payload should be processed without performance degradation

Timeline

  • Discovery Date: Current
  • Affected Versions: All versions containing the vulnerable regex
  • Recommended Action: Apply fix immediately

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions