Skip to main content
REDoS in UAParser.js: A 72-Hour FixIncident
4 min readFor Compliance Teams

REDoS in UAParser.js: A 72-Hour Fix

What Happened

In 2020, researcher Yeting Li discovered a Regular Expression Denial of Service (REDoS) vulnerability in UAParser.js, a widely-used JavaScript library for parsing user agent strings. The vulnerability existed in regular expressions designed to identify browsers on Xiaomi Redmi phones and Mi Pad tablets. Li disclosed the finding to Snyk, who coordinated with the package maintainer. The maintainer committed a fix within 72 hours, and the vulnerability received CVE-2020-7733.

At disclosure, nearly 21,000 packages monitored by Snyk contained vulnerable versions of UAParser.js.

Timeline

Day 0: Yeting Li identifies the REDoS vulnerability using an automated detection algorithm and reports it to Snyk.

Day 1-2: Snyk validates the vulnerability and contacts the UAParser.js maintainer through coordinated disclosure channels.

Day 3: Maintainer commits fix to the repository.

Post-fix: Snyk publishes security advisory. CVE-2020-7733 assigned and published to vulnerability databases.

Which Controls Failed or Were Missing

This incident reveals gaps in three distinct control areas:

Secure development lifecycle controls: The vulnerable regular expressions made it into production without detection. No automated tooling flagged the problematic patterns during development or code review. The package lacked pre-commit hooks or CI/CD gates that would test regex patterns against known REDoS patterns.

Dependency security monitoring: The 21,000 downstream packages using UAParser.js had no visibility into this supply chain risk until after public disclosure. Most organizations running these packages didn't know they were exposed. Without automated dependency scanning, you only discover these vulnerabilities when someone tells you—often too late.

Vulnerability disclosure process: This process actually worked well. The maintainer's 72-hour response time prevented widespread exploitation. However, most organizations have no documented process for handling vulnerability reports in their dependencies. Who receives the report? Who validates it? Who decides whether to patch immediately or wait for the next release cycle?

What the Standards Require

PCI DSS v4.0.1 Requirement 6.3.2 mandates maintaining an inventory of bespoke and custom software and third-party components. It specifically calls for identifying security vulnerabilities using industry-recognized sources. If UAParser.js processes payment card data anywhere in your stack—even indirectly through user agent logging in payment flows—you need automated scanning that would catch this.

OWASP ASVS v4.0.3 Section 5.1.5 requires validation that regular expression patterns don't create ReDoS conditions. This is a testable control. Your build pipeline should reject regex patterns that exhibit exponential time complexity with crafted input.

ISO/IEC 27001:2022 Control 8.31 (Security of information in use) requires protecting information during processing. A ReDoS attack that crashes your parser is a denial of service against information processing. Your risk assessment should identify which parsing operations are vulnerable to algorithmic complexity attacks.

NIST 800-53 Rev 5 Control SI-2 (Flaw Remediation) requires you to remediate flaws within organization-defined time periods. The 72-hour timeline in this case sets a benchmark. For libraries processing untrusted input, you need a process that can move from disclosure to deployed patch in under a week.

Lessons and Action Items for Your Team

Build regex testing into your pipeline: If you write or maintain code that uses regular expressions against untrusted input, add ReDoS detection to your CI/CD. Tools like safe-regex (for JavaScript) or regex-static-analysis (for Python) catch catastrophic backtracking before merge. Make the build fail on patterns that exhibit quadratic or exponential complexity.

Map your transitive dependencies: Run npm ls or pip show and export the full dependency tree for every production service. Filter for packages that parse external input—user agents, URLs, JSON payloads, file uploads. These are your ReDoS attack surface. You can't protect what you don't inventory.

Set up automated vulnerability monitoring: Configure Snyk, Dependabot, or your preferred scanner to alert on new CVEs in your dependencies within 24 hours. Route alerts to a Slack channel or ticketing queue that security and engineering both monitor. The 21,000 affected packages in this case illustrate why manual tracking doesn't scale.

Document your disclosure response process: Write a one-page runbook that answers: Who receives vulnerability reports? What's the SLA for validating the report? Who has authority to approve emergency patches outside the normal release cycle? Who communicates with the reporter? Without this, your 72-hour response becomes a 72-day response while you figure out internal process.

Test your parser libraries under load: Don't wait for a researcher to find your ReDoS vulnerabilities. Generate malicious input patterns and run them against your parsers in staging. A user agent string with nested repetition groups should not take 10 seconds to parse. If it does, you have a problem.

Establish patch deployment timelines by risk: Critical vulnerabilities in parsing libraries that process untrusted input should deploy within 72 hours, matching the timeline in this case. Lower-severity issues can wait for your normal sprint cycle. Document these SLAs and track your actual performance against them. NIST 800-53 Control SI-2 requires defined time periods—define them.

The UAParser.js case demonstrates that rapid remediation is possible when researchers, security vendors, and maintainers coordinate effectively. Your job is to build the internal controls that let you respond just as quickly when the next disclosure lands in your inbox.

Topics:Incident

You Might Also Like