Skip to content

[high] fix: [cof2misp] fix operator precedence in COF timestamp validation - #894

Merged
adulau merged 1 commit into
MISP:mainfrom
elhoim:fix/086-cof-precedence
Sep 8, 2026
Merged

[high] fix: [cof2misp] fix operator precedence in COF timestamp validation#894
adulau merged 1 commit into
MISP:mainfrom
elhoim:fix/086-cof-precedence

Conversation

@elhoim

@elhoim elhoim commented Aug 31, 2026

Copy link
Copy Markdown
Member

BLUF — Missing parentheses in is_cof_valid_simple() make Python reject valid zone-time COF records.

  • Problemis_cof_valid_simple() in misp_modules/lib/cof2misp/cof.py writes its timestamp check as not (A) or (B), but Python binds not tighter than or, so the intended not (A or B) is never evaluated. Any COF passive DNS record carrying only the documented zone_time_first/zone_time_last pair is rejected with a misleading missing-required-fields message.
  • Fix — Adds the parentheses so the two valid-pair checks are combined before negation.
  • Effectcof2misp imports zone-time records instead of discarding them, so analysts stop losing legitimate passive DNS data on import.

The defect

In misp_modules/lib/cof2misp/cof.py, is_cof_valid_simple() checked for the presence of a valid timestamp pair like this:

if not ("time_first" in d and "time_last" in d) or ("zone_time_first" in d and "zone_time_last" in d):

Due to Python operator precedence, not binds tighter than or, so this parses as:

(not ("time_first" in d and "time_last" in d)) or ("zone_time_first" in d and "zone_time_last" in d)

The intent was "reject the record unless it has EITHER the time_first/time_last pair OR the zone_time_first/zone_time_last pair" — i.e. not (A or B). Instead, the expression evaluates to (not A) or B, which is true (and so returns False, rejecting the record) whenever A is false, regardless of B. Concretely: a record that has only zone_time_first/zone_time_last (and lacks time_first/time_last) makes A false, so not A is True, and the whole condition is True — the record is wrongly rejected as missing required fields, even though it actually has a valid timestamp pair.

Impact

Any COF (Common Output Format) DNS record that carries only the zone_time_first/zone_time_last fields — a legitimate, documented alternative to time_first/time_last — is silently dropped by the cof2misp conversion before it ever reaches MISP. An analyst importing passive DNS data in this format loses valid records without any indication that they were rejected, other than a generic stderr message that (incorrectly) claims required fields are missing.

The fix

Add the missing parentheses so the or combines the two "has a valid pair" checks before negation, matching the intended not (A or B) semantics:

if not (("time_first" in d and "time_last" in d) or ("zone_time_first" in d and "zone_time_last" in d)):

No behaviour change beyond correcting this logic error to match the documented/intended validation rule.

Verification

  • python -m py_compile misp_modules/lib/cof2misp/cof.py — clean.
  • Full module test suite: 161 passed, 4 skipped, 5 subtests passed in 22.08s.

Found during a review of the repository; other findings are being submitted as separate PRs.

🤖 Generated with Claude Code

is_cof_valid_simple checked `not (A and B) or (C and D)`, which Python
parses as `(not (A and B)) or (C and D)` rather than the intended
`not ((A and B) or (C and D))`. As a result, a record carrying only the
valid zone_time_first/zone_time_last pair (and no time_first/time_last)
was rejected as invalid, since `not (A and B)` is already True in that
case and short-circuits the OR to True, triggering the "missing
mandatory fields" error and a False return even though the record is
well-formed. A record with both pairs present was also flagged wrong
for the same reason.

Parenthesised the check as `not ((A and B) or (C and D))` so validation
succeeds whenever either timestamp pair is present, matching the
intended COF semantics.

Verified with py_compile and the full pytest suite against a live
modules server on port 6786: 161 passed, 4 skipped, 5 subtests passed,
matching the documented baseline.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018dfYpyaSZd1nxSRLr8suj8
@elhoim elhoim changed the title fix: [cof2misp] fix operator precedence in COF timestamp validation [high] fix: [cof2misp] fix operator precedence in COF timestamp validation Sep 3, 2026
@adulau
adulau merged commit ea6e4b8 into MISP:main Sep 8, 2026
7 checks passed
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.

2 participants