Update websocket.py - #77
Conversation
Fix SSL error: Traceback (most recent call last): File "pymax/base.py", line 131, in start File "pymax/app.py", line 88, in start ConnectionError: Failed to connect and handshake: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:992)
📝 WalkthroughWalkthroughThis change adds a module-level SSL context in the WebSocket transport module that disables hostname verification and certificate validation. Both the proxied and direct WebSocket connection code paths now pass this context to the connect call. ChangesSSL Context for WebSocket Connections
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/pymax/transport/websocket.py`:
- Around line 7-10: Remove the assignments disabling validation from the
module-level ssl_context in websocket.py, preserving the verified defaults
created by ssl.create_default_context(). If private CA support is required, load
it via load_verify_locations() without changing check_hostname or verify_mode;
any insecure local-development mode must be explicit and opt-in rather than
shared by both connection paths.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: d81a68d5-d8be-4de0-9863-e1a4a20cce73
📒 Files selected for processing (1)
src/pymax/transport/websocket.py
| import ssl | ||
| ssl_context = ssl.create_default_context() | ||
| ssl_context.check_hostname = False | ||
| ssl_context.verify_mode = ssl.CERT_NONE |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Tracked websocket.py files:\n'
git ls-files | grep -E '(^|/)websocket\.py$' || true
printf '\nRelevant file excerpt:\n'
if [ -f src/pymax/transport/websocket.py ]; then
nl -ba src/pymax/transport/websocket.py | sed -n '1,80p'
fi
printf '\nSearch for ssl_context use and transport connect definitions:\n'
rg -n "ssl_context|check_hostname|verify_mode|def connect|client\.connect|async def connect" src/pymax/transport/websocket.py src/pymax/transport || true
printf '\nPython ssl semantics probe for create_default_context mutations:\n'
python3 - <<'PY'
import ssl
ctx = ssl.create_default_context()
before = (ctx.check_hostname, ctx.verify_mode == ssl.CERT_NONE)
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
after = (ctx.check_hostname, ctx.verify_mode == ssl.CERT_NONE)
print("before_hostname_true:", before[0])
print("before_cert_verified:", not before[1])
print("after_hostname_false:", after[0])
print("after_cert_none:", after[1])
PY
printf '\nPackage version constraint context:\n'
if [ -f pyproject.toml ]; then
sed -n '1,80p' pyproject.toml | nl -ba
fiRepository: MaxApiTeam/PyMax
Length of output: 279
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Relevant file excerpt:\n'
awk '{printf "%6d\t%s\n", NR, $0}' src/pymax/transport/websocket.py | sed -n '1,80p'
printf '\nSearch for ssl_context use and transport connect definitions:\n'
rg -n "ssl_context|check_hostname|verify_mode|def connect|client\.connect|async def connect" src/pymax/transport src/pymax || true
printf '\nPython ssl semantics probe for create_default_context mutations:\n'
python3 - <<'PY'
import ssl
ctx = ssl.create_default_context()
before = (ctx.check_hostname, ctx.verify_mode == ssl.CERT_NONE)
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
after = (ctx.check_hostname, ctx.verify_mode == ssl.CERT_NONE)
print("before_hostname_true:", before[0])
print("before_cert_verified:", not before[1])
print("after_hostname_false:", after[0])
print("after_cert_none:", after[1])
PY
printf '\nPackage version constraint context:\n'
awk '{printf "%6d\t%s\n", NR, $0}' pyproject.toml | sed -n '1,80p'
printf '\nCall sites for build_connection / WebSocketTransport:\n'
rg -n "WebSocketTransport|_build_connection|WebSocketTransport\(" src/py* tests || trueRepository: MaxApiTeam/PyMax
Length of output: 8191
Security Misconfiguration (CWE-295): Improper Certificate Validation
Reachability: External
Do not ship an unverified WebSocket context.
Lines 8-10 set verify_mode to ssl.CERT_NONE and disable check_hostname, then both connection paths use the same context. This removes server certificate and hostname validation, so an attacker who can intercept the connection or control the proxy can impersonate the endpoint and read or modify WebSocket traffic.
Keep the default verified context. For private CAs, fix the server chain or load the CA bundle with load_verify_locations() while retaining hostname checking. Make any insecure local-dev mode explicit and opt-in.
Proposed fix
ssl_context = ssl.create_default_context()
-ssl_context.check_hostname = False
-ssl_context.verify_mode = ssl.CERT_NONE📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import ssl | |
| ssl_context = ssl.create_default_context() | |
| ssl_context.check_hostname = False | |
| ssl_context.verify_mode = ssl.CERT_NONE | |
| import ssl | |
| ssl_context = ssl.create_default_context() |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/pymax/transport/websocket.py` around lines 7 - 10, Remove the assignments
disabling validation from the module-level ssl_context in websocket.py,
preserving the verified defaults created by ssl.create_default_context(). If
private CA support is required, load it via load_verify_locations() without
changing check_hostname or verify_mode; any insecure local-development mode must
be explicit and opt-in rather than shared by both connection paths.
|
Дело в том что макс изменил вебсокет путь и протокол в вебе, в ветке uv add git+https://github.com/MaxApiTeam/PyMax@dev/2.4.0
# или
pip install git+https://github.com/MaxApiTeam/PyMax@dev/2.4.0 |
|
У ветки dev 2.4.0 |
Fix SSL error:
Traceback (most recent call last):
File "pymax/base.py", line 131, in start
File "pymax/app.py", line 88, in start
ConnectionError: Failed to connect and handshake: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:992)
Summary by CodeRabbit