Skip to content

fix: mitigate ReDoS in /nodes/conf_search (CWE-1333)#442

Open
mattimustang wants to merge 1 commit into
ytti:masterfrom
mattimustang:fix/redos-conf-search
Open

fix: mitigate ReDoS in /nodes/conf_search (CWE-1333)#442
mattimustang wants to merge 1 commit into
ytti:masterfrom
mattimustang:fix/redos-conf-search

Conversation

@mattimustang

Copy link
Copy Markdown

Summary

  • Regexp.new was called directly on unsanitised user input with no error handling or timeout, allowing an authenticated attacker to supply a pathological regex that hangs a Puma worker thread indefinitely, or an invalid pattern that raises an unhandled 500 exception
  • Wrap Regexp.new in rescue RegexpError → returns HTTP 400 for syntactically invalid patterns (all Ruby versions)
  • Wrap each per-node config match in Timeout.timeout(2) → skips that node and continues if a pattern runs long, preventing thread pool exhaustion (Ruby 3.0+)

Test plan

  • bundle exec rake passes (RuboCop + full test suite) — 43 tests, 0 failures
  • POST /nodes/conf_search with invalid pattern (e.g. [invalid() returns 400
  • POST /nodes/conf_search with valid pattern returns matching nodes as before
  • POST /nodes/conf_search with a slow/malicious pattern no longer hangs the server indefinitely

Regexp.new was called directly on unsanitised user input with no error
handling or timeout, allowing an authenticated attacker to supply a
pathological pattern that hangs a Puma worker thread indefinitely, or
an invalid pattern that raises an unhandled exception.

- Wrap Regexp.new in rescue RegexpError → HTTP 400 for invalid patterns
- Wrap each per-node config match in Timeout.timeout(2) → skip node on
  timeout, preventing a crafted regex from exhausting the thread pool
- Add tests covering invalid pattern, no match, match, and timeout cases
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant