Repository navigation
fix(a2a): decode percent-encoded password in redis url - #8206
devYRPauli wants to merge 2 commits into
Conversation
_parse_redis_url passed parsed.password from REDIS_URL to the aiocache config unchanged, so a percent-encoded password reached the server encoded. Decode it with unquote, as redis-py from_url does. Fixes crewAIInc#8205 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Strix Security ReviewWarning This pull request has 57 commits after the last Strix review ( No security issues found. Review summaryReviewed the two-file change to Updated for Reviewed by Strix |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Priority: ⬇️ Low Severity of issue fixed: Low Merge Risk: ⚪ Minimal · up to
|
VANDRANKI
left a comment
There was a problem hiding this comment.
I ran this on Windows with Python 3.13.3, against main (40bb2d3) and the PR head. I installed a2a-sdk 0.3.x, aiocache and redis-py 8.1.0 into a temp folder so crewai.a2a.utils.task imports.
I compared _parse_redis_url with redis.connection.parse_url from redis-py, which from_url uses. I looked at the password in each result.
| URL password | main | PR | redis-py |
|---|---|---|---|
p%40ss%2Fw%3Ard+1 |
p%40ss%2Fw%3Ard+1 |
p@ss/w:rd+1 |
p@ss/w:rd+1 |
pa%2523ss |
pa%2523ss |
pa%23ss |
pa%23ss |
a%20b (rediss://) |
a%20b |
a b |
a b |
plain |
plain |
plain |
plain |
% alone, and p%zzw |
unchanged | unchanged | unchanged |
| no password | no password key |
no password key |
none |
So the PR matches redis-py for every URL I tried. The + stays a +, which is right, because unquote is used and not unquote_plus. The double-encoded %2523 decodes once only, as redis-py does.
The exact dict from the PR's test (redis://:p%40ss%2Fw%3Ard+1@cache.internal:6380/2) compares equal on the PR and not equal on main. I checked that equality by hand in a one-liner. I could not run the test through pytest. In my environment all 17 tests in tests/a2a/utils/test_task.py error during setup with RuntimeError: Network is disabled, on the PR and on main, before any test body runs.
One thing I saw that is outside this PR. The username in the URL is still dropped, and rediss:// still gives no TLS setting. For rediss://user:p%40ss@h:6380/1 the config is only cache, endpoint, port, db and password. redis-py returns user as the username. If a Redis ACL user is needed, auth would still fail after this fix. That could be a follow-up. I did not connect to a Redis server.
The change is correct for the password. Approving.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Related issue
Fixes #8205
Summary
_parse_redis_urlnow decodes the password fromREDIS_URLwithurllib.parse.unquotebefore it puts the password in the aiocache config. redis-pyfrom_urldecodes the password the same way, andcrewai_core/lock_store.pyalready reads the sameREDIS_URLthroughfrom_url. A URL with no password still adds nopasswordkey.Verification
Tests added or updated for the changed behavior
Relevant tests and quality checks pass locally
New test
TestParseRedisUrl.test_decodes_percent_encoded_passwordinlib/crewai/tests/a2a/utils/test_task.pychecks the full config forredis://:p%40ss%2Fw%3Ard+1@cache.internal:6380/2. It fails on main and passes with this change.unquote_plusin place ofunquotefails the test, because the test password contains+.I pointed
aiocache.RedisCacheat a RESP stub server with the parsed config. On main the client sendsHELLO 3 AUTH default p%40ss%2Fw%3Ard+1. With this change it sendsp@ss/w:rd+1. Versions: redis 8.0.0, aiocache 0.12.3.pytest lib/crewai/tests/a2aon Python 3.12 with thea2aextra: 101 passed on main, 102 passed with this change.ruff check,ruff format --checkandmypyontask.pypass.Additional context
One behavior changes. A password written unencoded that contains a valid
%XXsequence is now decoded. redis-py decodes it the same way, so aREDIS_URLthat works for the lock store is not affected.Open PR #5700 moves this parsing to
parse_cache_urlin a newcache_config.py. That function also passesparsed.passwordunchanged, so it needs the sameunquoteif #5700 merges after this PR.I used Claude Code CLI with Opus 5.5. I cannot set the
llm-generatedlabel, so please add it.Note
Low Risk
Small, localized change to Redis URL parsing for A2A caching; aligns with redis-py and only affects password handling when
REDIS_URLis set.Overview
Fixes A2A Redis cache setup when
REDIS_URLincludes a percent-encoded password._parse_redis_urlnow runs the URL password throughurllib.parse.unquotebefore putting it in the aiocache config, matching redis-pyfrom_urlbehavior (and the lock store path that already usesfrom_url).A new unit test asserts the full parsed config for a URL with encoded
@,/,:, and+in the password. URLs with no password are unchanged.Reviewed by Cursor Bugbot for commit fbfcb6f. Bugbot is set up for automated code reviews on this repo. Configure here.