(
secret: Union[str, bytes],
name: str,
value: bytes,
max_age_days: float,
clock: Callable[[], float],
)
| 3700 | |
| 3701 | |
| 3702 | def _decode_signed_value_v1( |
| 3703 | secret: Union[str, bytes], |
| 3704 | name: str, |
| 3705 | value: bytes, |
| 3706 | max_age_days: float, |
| 3707 | clock: Callable[[], float], |
| 3708 | ) -> Optional[bytes]: |
| 3709 | parts = utf8(value).split(b"|") |
| 3710 | if len(parts) != 3: |
| 3711 | return None |
| 3712 | signature = _create_signature_v1(secret, name, parts[0], parts[1]) |
| 3713 | if not hmac.compare_digest(parts[2], signature): |
| 3714 | gen_log.warning("Invalid cookie signature %r", value) |
| 3715 | return None |
| 3716 | timestamp = int(parts[1]) |
| 3717 | if timestamp < clock() - max_age_days * 86400: |
| 3718 | gen_log.warning("Expired cookie %r", value) |
| 3719 | return None |
| 3720 | if timestamp > clock() + 31 * 86400: |
| 3721 | # _cookie_signature does not hash a delimiter between the |
| 3722 | # parts of the cookie, so an attacker could transfer trailing |
| 3723 | # digits from the payload to the timestamp without altering the |
| 3724 | # signature. For backwards compatibility, sanity-check timestamp |
| 3725 | # here instead of modifying _cookie_signature. |
| 3726 | gen_log.warning("Cookie timestamp in future; possible tampering %r", value) |
| 3727 | return None |
| 3728 | if parts[1].startswith(b"0"): |
| 3729 | gen_log.warning("Tampered cookie %r", value) |
| 3730 | return None |
| 3731 | try: |
| 3732 | return base64.b64decode(parts[0]) |
| 3733 | except Exception: |
| 3734 | return None |
| 3735 | |
| 3736 | |
| 3737 | def _decode_fields_v2(value: bytes) -> Tuple[int, bytes, bytes, bytes, bytes]: |
no test coverage detected