From Wave 5 security audit, finding F-O-08. Severity: low / medium (depends on threat model).
Code
`kalshi/_base_client.py:57-66`:
```python
try:
retry_after_val = float(retry_after)
except ValueError:
retry_after_val = None # HTTP-date format, fall back to computed backoff
```
No range check. `float("-1")`, `float("inf")`, `float("nan")` all succeed.
Impact
- `Retry-After: -1` → `min(-1, 30) = -1` → `time.sleep(-1)` is a no-op on POSIX. The client busy-loops the server-controlled retry. Effectively no backoff.
- `Retry-After: 1e308` → `min(inf, 30) == 30` — OK, capped correctly.
- `Retry-After: nan` → `min(nan, 30) == nan` → `time.sleep(nan)` raises `ValueError` and surfaces as an unexpected exception type rather than the documented retry pathway.
The cap is documented in `CLAUDE.md` as "prevents server-controlled sleep" but actually only caps the upper end.
Fix
```python
import math
...
try:
retry_after_val = float(retry_after)
if retry_after_val < 0 or not math.isfinite(retry_after_val):
retry_after_val = None
except ValueError:
retry_after_val = None
```
Five lines. Removes the lower-bound gap and the NaN crash.
Tests
Should also cover the `Retry-After` cap (currently untested per F-Q-01) and HTTP-date fallback (F-Q-02) — those are filed in the retry-test-coverage issue.
From Wave 5 security audit, finding F-O-08. Severity: low / medium (depends on threat model).
Code
`kalshi/_base_client.py:57-66`:
```python
try:
retry_after_val = float(retry_after)
except ValueError:
retry_after_val = None # HTTP-date format, fall back to computed backoff
```
No range check. `float("-1")`, `float("inf")`, `float("nan")` all succeed.
Impact
The cap is documented in `CLAUDE.md` as "prevents server-controlled sleep" but actually only caps the upper end.
Fix
```python
import math
...
try:
retry_after_val = float(retry_after)
if retry_after_val < 0 or not math.isfinite(retry_after_val):
retry_after_val = None
except ValueError:
retry_after_val = None
```
Five lines. Removes the lower-bound gap and the NaN crash.
Tests
Should also cover the `Retry-After` cap (currently untested per F-Q-01) and HTTP-date fallback (F-Q-02) — those are filed in the retry-test-coverage issue.