Skip to content

Fix ReDoS vulnerability in tag validation regex#308

Merged
caronc merged 2 commits intocaronc:masterfrom
RinZ27:fix/redos-tag-validation
Mar 28, 2026
Merged

Fix ReDoS vulnerability in tag validation regex#308
caronc merged 2 commits intocaronc:masterfrom
RinZ27:fix/redos-tag-validation

Conversation

@RinZ27
Copy link
Copy Markdown
Contributor

@RinZ27 RinZ27 commented Mar 24, 2026

Description:

Fixed a ReDoS vulnerability in the tag validation regex within views.py. The original pattern suffered from catastrophic backtracking due to overlapping whitespace groups, which could lead to high CPU consumption with crafted payloads.

Replaced the regex with a linear-time alternative that maintains the same validation logic but prevents exponential complexity.

Related issue (if applicable): N/A

Checklist

  • The code change is tested and works locally.
  • There is no commented out code in this PR.
  • No lint errors (use ruff)
  • Tests added

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a potential regex-based denial-of-service (ReDoS) issue in tag validation by simplifying the tag validation regex and adding a regression test to catch catastrophic backtracking/performance issues.

Changes:

  • Updated TAG_VALIDATION_RE to remove redundant leading/trailing \s* and avoid catastrophic backtracking.
  • Added test_redos.py with a performance regression test and basic validation behavior checks.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
apprise_api/api/views.py Simplifies tag validation regex to mitigate ReDoS risk.
apprise_api/api/tests/test_redos.py Adds tests intended to validate both performance and correctness of the tag validation regex.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@RinZ27 RinZ27 force-pushed the fix/redos-tag-validation branch from 1b1787e to 0b103a9 Compare March 24, 2026 14:58
@caronc
Copy link
Copy Markdown
Owner

caronc commented Mar 24, 2026

Thank you! I really appreciate the PR. 🙏I’m working through it to fully understand the implications, although I’m not able to test it directly at the moment.

I’d like to clarify how this issue is actually exposed. My current understanding is that a potential DoS risk would only exist if the existing tag validation (which runs prior to applying the regex in question) were absent. If that validation is already enforced, would that not mitigate the concern? Please let me know if I’m misunderstanding this.

From reviewing the tests, it appears they demonstrate that the regex could present a DoS risk if used in isolation, but not necessarily in the way it is currently implemented. Is that accurate?

Also, is there a realistic scenario where this could be exploited via a GET or POST request through the API, or is this change more about defensive hardening to prevent future misuse or regression?

If possible, it would be helpful to include a test case that reflects a realistic exploitation path, assuming one exists.

@RinZ27 RinZ27 force-pushed the fix/redos-tag-validation branch from 0b103a9 to 0d6f42e Compare March 26, 2026 11:54
@RinZ27
Copy link
Copy Markdown
Contributor Author

RinZ27 commented Mar 26, 2026

@caronc, the vulnerability is actually reachable through the standard API endpoints. While there is a global 3MB limit on payloads, there isn't any specific length validation for the tag parameter before it hits the regex. I've added test_realistic_redos.py which uses the Django test client to demonstrate this. In my local tests, a 2000 character payload was enough to hang the worker for about 14 seconds with the old regex, whereas it's instant now. It affects both GET query parameters and JSON POST bodies since they both map directly to that same validation check.

@RinZ27 RinZ27 force-pushed the fix/redos-tag-validation branch from 0d6f42e to e941604 Compare March 27, 2026 12:47
@RinZ27
Copy link
Copy Markdown
Contributor Author

RinZ27 commented Mar 27, 2026

@caronc Done as requested and updated the test cases to reflect this change, also cleaned up the indentation and inline comment spacing in the test file, and switched to time.perf_counter() for better timing accuracy.

@RinZ27 RinZ27 force-pushed the fix/redos-tag-validation branch 3 times, most recently from d08e4d1 to 5109283 Compare March 27, 2026 13:42
@RinZ27 RinZ27 force-pushed the fix/redos-tag-validation branch from 5109283 to 39884ad Compare March 27, 2026 13:43
@caronc
Copy link
Copy Markdown
Owner

caronc commented Mar 27, 2026

If it helps, you can verify this works before you commit with options like:

# Just test /align formating where possible
tox -e format

# run tests yourself (if it's a test failing)
tox -e qa

# run a specific test (below 'just' runs any test_ with redos in function name):
tox -qa -- -k redos

@RinZ27
Copy link
Copy Markdown
Contributor Author

RinZ27 commented Mar 28, 2026

@caronc thanks for the tox tips!

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 28, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (ecc8655) to head (192c20b).
⚠️ Report is 84 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff             @@
##           master      #308      +/-   ##
===========================================
+ Coverage   99.37%   100.00%   +0.62%     
===========================================
  Files           7        12       +5     
  Lines         794      1239     +445     
  Branches        0       221     +221     
===========================================
+ Hits          789      1239     +450     
+ Misses          5         0       -5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@caronc caronc merged commit 8dca089 into caronc:master Mar 28, 2026
3 checks passed
@caronc
Copy link
Copy Markdown
Owner

caronc commented Mar 28, 2026

Merged! thank you very much @RinZ27 🚀

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.

3 participants