tornadoweb / tornadoweb/tornado
decode_signed_value raises ValueError for authenticated malformed timestamps
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 22.2k
- Forks
- 5.6k
- Avg merge
- 3h 42m
- Merged PRs (30d)
- 16
Description
`decode_signed_value` raises `ValueError` for a syntactically malformed
timestamp after the cookie signature has been successfully verified.
I expected an invalid signed cookie to be rejected with `None`, consistent
with `RequestHandler.get_signed_cookie`'s documented return behavior, rather
than causing an exception in request handling.
## Reproducer
This example constructs a structurally valid v2 signed value whose timestamp
field is `b"a"` and computes a valid HMAC using the configured secret:
```python
from tornado.escape import utf8
from tornado.web import _create_signature_v2, decode_signed_value
def field(value: bytes) -> bytes:
return str(len(value)).encode("ascii") + b":" + value
secret = b"s"
name = "a"
prefix = b"|".join(
[
b"2",
field(b"0"),
field(b"a"), # non-decimal timestamp
field(utf8(name)),
field(b""),
b"",
]
)
cookie = prefix + _create_signature_v2(secret, prefix)
assert decode_signed_value(
secret, name, cookie, clock=lambda: 1_500_000_000
) is None
Actual result
ValueError: invalid literal for int() with base 10: b'a'
The exception is raised by:
```python
timestamp = int(timestamp_bytes)
in _decode_signed_value_v2.
Expected result
Return None for this invalid cookie, without raising.
Scope / impact
This is not a signature-bypass issue: constructing this particular input
requires a valid signing key. However, it means a malformed cookie produced
by a key-holding component (or after a key compromise/migration issue) can
cause get_signed_cookie to raise and potentially turn a request into a 500
instead of treating the cookie as invalid.
I also observed an analogous uncaught ValueError path in the legacy v1
decoder after signature verification, so a fix may want to cover both v1 and
v2 timestamp conversions.
Tested on current master (e530031) and release v6.5.7.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at _decode_signed_value_v2, where timestamp_bytes is converted with int(), and inspect the analogous v1 decoder path mentioned in the report. Trace decode_signed_value through RequestHandler.get_signed_cookie, then add regression coverage showing authenticated malformed timestamps are rejected as None without an exception.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100