Skip to content

[medium] Fix TTL boundary in cache freshness check - #39

Open
elhoim wants to merge 1 commit into
MISP:mainfrom
elhoim:fix/32-ttl-boundary
Open

[medium] Fix TTL boundary in cache freshness check#39
elhoim wants to merge 1 commit into
MISP:mainfrom
elhoim:fix/32-ttl-boundary

Conversation

@elhoim

@elhoim elhoim commented Aug 31, 2026

Copy link
Copy Markdown
Member

BLUF — get_cached_response() serves entries aged exactly the TTL, so --cache-ttl-seconds 0 still caches.

  • Problemget_cached_response() in bin/cli.py tests freshness with now - cached_at > ttl_seconds, so an entry whose age exactly equals the TTL is still served as a hit. --cache-ttl-seconds 0, the obvious way to disable caching, still returns a cached response for queries made in the same second.
  • Fix — Changes the comparison to >=.
  • Effect — An entry expires the instant its age reaches the TTL, and the zero-TTL flag actually bypasses the cache.

Finding 32 (Low) — bin/cli.py:656

Problem

The freshness test is 'now - cached_at > ttl_seconds', so an entry exactly at the TTL boundary is still served; --cache-ttl-seconds 0, the natural way to disable caching, still returns a hit within the same second.

Fix

Finding #32 (ttl-boundary, low severity): get_cached_response() in bin/cli.py used now - cached_at > ttl_seconds to decide whether a cache entry was still fresh, so an entry exactly at the TTL boundary was still served as a hit. Concretely, --cache-ttl-seconds 0 — the natural way to disable caching entirely — still returned a cached response when queried within the same second it was written. Fixed by changing the comparison to >=, so an entry is treated as expired the instant its age reaches the TTL, matching the documented "TTL seconds" semantics. Minimal one-character diff, no other behavior touched.

Verification

Reproduced against the unmodified code at 9b8c605, then re-checked after the change.

Before
python3 (via importlib) with cache={"entries": {}}; set_cached_response(cache, "k", {"data": 1}, now=100); get_cached_response(cache, "k", now=100, ttl_seconds=0) -> {'cached_at': 100, 'response': {'data': 1}} (a hit, even though ttl_seconds=0 should mean "never fresh")
After
Same setup after fix: get_cached_response(cache, "k", now=100, ttl_seconds=0) -> None. Also verified now=110, ttl_seconds=10 (exact boundary) -> None, while now=105, ttl_seconds=10 (still within window) -> hit as expected.

python bin/cli.py --help exits 0 and the module still imports cleanly. Verification was performed offline against the pure functions — no running misp-modules instance is required.

Branched from 9b8c605. This PR addresses only this finding; the other findings from the same review are in separate PRs, so they will need rebasing against each other as they merge.

🤖 Generated with Claude Code

get_cached_response used 'now - cached_at > ttl_seconds', so an entry exactly at the TTL boundary was still served as fresh. This means --cache-ttl-seconds 0, the natural way to disable caching, still returned a cache hit within the same second. Changed the comparison to >= so an entry is considered expired once its age reaches the TTL.
@elhoim elhoim changed the title Fix TTL boundary in cache freshness check [medium] Fix TTL boundary in cache freshness check Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant