Project

General

Profile

Actions

Bug #8948

open
YD OD

firewall: app-layer hook rules for IMAP load without error but never match (IMAP is detection-only)

Bug #8948: firewall: app-layer hook rules for IMAP load without error but never match (IMAP is detection-only)

Added by Yash Datre 1 day ago. Updated 1 day ago.

Status:
Triaged
Priority:
High
Assignee:
Target version:
Affected Versions:
Effort:
Difficulty:
Label:

Description

In firewall mode a rule can hook an application-layer state, e.g. accept:hook <proto>:request_started or drop:flow <proto>:request_started. For IMAP these rules load without any error or warning, but they are completely inert: they never match, and the app-layer firewall policy never engages for an IMAP flow.

The reason is that IMAP is detection-only in Suricata. src/app-layer-imap.c registers protocol-detection patterns but registers no parser, no transactions and no progress states. Firewall app-layer hooks bind to a protocol's progress states, so for IMAP there is no state for the hook to bind to and the hook is never reached.

Net effect: an operator who writes a firewall rule to control IMAP at the app layer (for example drop:flow imap:request_started to block IMAP) gets a rule that Suricata silently accepts and that has zero effect. The IMAP flow is still detected as app_proto: imap and passes untouched. This is misleading and is a latent policy/security gap, because the authored control is never enforced and there is no diagnostic to say so.

Steps to reproduce

Firewall ruleset (firewall.rules):

# Accept the TCP session at the packet level so packets flow and the flow
# reaches app-layer classification.
accept:hook tcp:all any any <> any any (flow:not_established; alert; sid:1000;)
accept:hook tcp:all any any <> any any (flow:established; alert; sid:1001;)

# Intended policy: drop every IMAP flow at the request hook.
drop:flow imap:request_started any any -> any any (alert; sid:2000;)

Replay an IMAP session (e.g. tests/imap-detection/input.pcap) in simulated IPS mode:

suricata --simulate-ips -k none -c suricata.yaml \
    -r input.pcap --firewall-rules-exclusive firewall.rules

Expected behaviour

Either of the following would be acceptable:

  • The drop:flow imap:request_started rule enforces the policy: the IMAP flow is dropped, sid:2000 alerts (alert.action: blocked), first drop drop.reason: "firewall rules", and stats.firewall.drop_reason.rules >= 1; or
  • Suricata rejects or warns at rule load that IMAP exposes no app-layer hook/progress state to bind to, so the operator knows the rule can never take effect (analogous to how other invalid hook specifications are reported).

Actual behaviour

  • The rule loads with no error and no warning.
  • sid:2000 never fires -- no alert is generated for it.
  • Nothing is dropped: no event_type: drop, stats.firewall.blocked: 0, stats.firewall.drop_reason.rules: 0, default_app_policy: 0, flow_drop: 0; stats.ips.blocked: 0.
  • The flow is still detected as IMAP: one event_type: flow with app_proto: imap, and the packet-level hook alerts (sid:1001) carry app_proto: imap.

Observed on the pcap above: stats.firewall.accepted: 106, stats.firewall.blocked: 0; sid:1000 x3, sid:1001 x103, sid:2000 x0.

Regression test

A suricata-verify test that asserts the expected behaviour (the drop:flow imap:request_started rule blocks the IMAP flow). It currently fails, reproducing the bug, and will start passing once the issue is fixed:

The test passes a control check (the flow is still detected as app_proto: imap) and then asserts the two currently-failing expectations:

- filter:                       # the drop rule must fire and block
    count: 1
    match:
      event_type: alert
      alert.signature_id: 2000
      alert.engine: fw
      alert.action: blocked
      app_proto: imap
- stats:                        # the flow must actually be dropped
    firewall.drop_reason.rules.__gte: 1
    firewall.blocked.__gte: 1

Open question for maintainers

Is the intended contract that firewall app-layer hooks may only be used with protocols that register app-layer progress states? If so, should the rule loader reject (or at least warn on) an app-layer hook targeting a detection-only protocol such as IMAP, so that a rule which can never match is not silently accepted? Alternatively, should detection-only protocols expose minimal progress states so that basic request/response hooks are usable in firewall mode?

JI Updated by Jason Ish 1 day ago Actions #1

  • Status changed from New to Triaged
  • Assignee set to OISF Dev
Actions

Also available in: PDF Atom