mirror of https://github.com/OISF/suricata
detect: require both halves of a bidirectional rule before matching
A transactional ('=>') rule keeps the engines of both directions in a
single progress sorted list. While the toserver pass runs it steps over
the toclient engines, and the only thing that kept it from declaring a
full match was
if (direction == 0 && engine->next == NULL) { break; }
so it worked only when a toclient engine happened to be the last entry.
Engines are sorted by progress across both directions, so a rule whose
toserver buffer has the higher progress value ends with a toserver
engine: the loop steps over the toclient engine, runs the toserver
engine, falls off the end of the list with total_matches set and reports
a full match. The toclient condition is then silently ignored, and the
rule fires on the request alone. For 'http.host' (p2) and 'http.stat_msg'
(p1) the list is
http_host/toserver/http2/p1 | http_stat_msg/toclient/http2/p0 |
http_stat_msg/toclient/http/p1 | http_host/toserver/http/p2
and a response of "200 OK" still alerts on a content:"ZZZZZZ" in
http.stat_msg.
Track the skip instead of the list position: remember that an engine of
the other direction was stepped over un-inspected and require that to be
clear before setting DE_STATE_FLAG_FULL_INSPECT. The decision is now the
same for every list layout, and for the layout that already worked (the
toclient engine last) it changes nothing beyond 'engine' being NULL
rather than non-NULL at the end of the loop: neither sets FULL_INSPECT,
and both leave the toserver flags to be stored for the toclient pass,
which appends them for both directions (DetectRunStoreStateTx).
Ticket: #9087.
pull/16325/head
parent
bc48b4f44c
commit
c4c778035e
Loading…
Reference in New Issue