Rules with sticky buffers and content modifiers

Hey everyone,

I’ve been looking up the Suricata 5 release and notices that a lot of keywords like http.uri and so on are now sticky buffers. However there is something that I don’t fully understand even after reading through the documentation. On https://suricata.readthedocs.io/en/suricata-5.0.2/rules/intro.html#rules-modifiers it says, that a sticky buffer applies to all keywords following it. But what happens in a rule where both sticky buffers and the older style content modifiers are used? For example (part of the rule only):

content:“key=”; http_header_names; content:!“Referer|0d 0a|”; content:!“User-Agent”; content:!“Cookie|0d 0a|”; http_connection; content:“data=”

Does the content modifier http_connection for the “Cookie” content overturn the sticky buffer? And is the sticky buffer still applying to the last “data=” content?

This is my understanding of how this works. In your example “key=” would match anywhere in the reassembled stream, “Referer|0d 0a|” and “User-Agent” would match the http_header_names buffer and “data=” would match the http_connection buffer.

All content matches following a sticky buffer will apply to that buffer as well as most other content matching keywords. I mix sticky buffers and content modifiers like this to avoid confusion:

content:"modifier match" http_uri; content:"full stream match"; content:"modifier match"; http_uri; http_header_names; content:"sticky match"; content:"sticky 2;

Thanks for your reply, I agree with your approach on how to structure the rule to avoid this confusion. Overall I also agree with your explanation, I only now noticed that http_connection always was a sticky buffer - my mistake. I should have went with something like http_uri like you did in your example.

So from what I gather, the sticky buffer applies to all following keywords, unless there is a content modifier for this specific keyword (like http_uri) or a new sticky buffer? So the rule, if not “properly” formatted (as I don’t write the rules myself for my usage), would look something like this?

content:“full stream match”; http_header_names; content:“sticky header names”; content:“modifier match”; http_uri; content:“sticky header names 2”; http_connection; “sticky connection”;

Do note that all http keywords have been converted to sticky buffers in the lastest Suricata release.

I might be on thin ice here, but all payload keywords following a sticky buffer relate to that buffer.
An exception might be dsize and some pcre modifiers.
Most other keyword types either define other buffers or don’t make sense in that context (think TCP or IP header keywords, flowstate keywords etc.)

Regarding your example. My understanding is that Suricata will complain and refuse to use your rule if you mix sticky buffers and modifiers in an ambiguous way.

Yes, I am aware of that, however I also need backwards compatibility to the older content modifier syntax as a large part of my rule set still uses the older keywords.
Ok, this is how I understand it as well. I also only meant the content or pcre keywords, of course the sticky buffer does not make sense in some of those other contexts.

Oh yes, you are completely right. I just tried it on a local installation and Suricata did not accept this rule because of this sticky buffer issue. The error also says that the sticky buffer has to be reset with pkt_data before using the content modifier. So the structure of the rule you mentioned before is the better way to go. This makes the whole process a lot easier and clearer to understand. Thanks!