Feature #5775
openhttp.headers - dynamic sticky buffers
Description
This idea is largely influenced by Snort 3.0 introduction of of an optional "field name" to the http_header keyword.
Snort's document can be found here: https://docs.snort.org/rules/options/payload/http/header
This request is to create similar support for suricata, which will allow sticky buffers on any http header without the need to add a new specific keyword. This should apply to both request/response headers and support the HTTP/2 overloading of these buffers.
It would also be important that issues where the header is not present though the rule has specific content negated, be handled correctly (please see https://redmine.openinfosecfoundation.org/issues/2224, https://redmine.openinfosecfoundation.org/issues/2479, and https://redmine.openinfosecfoundation.org/issues/4286). Additionally case would need to be considered/normalized. http.header_names can still be used to enforce order as required.
As an example, lets examine the following HTTP traffic from a Lucy Security Phishing HTTP Response
HTTP/1.1 200 OK Date: Mon, 19 Dec 2022 21:22:19 GMT Server: Lucy Set-Cookie: PHPSESSID=t78cghqvdtds1oblk3p38eerj3; path=/; secure; HttpOnly Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Vary: Accept-Encoding Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: *, x-c373df213d85a7fb58b442bcfb98407c6f0c58ae50ce6a21aef738c4243f7b4c Content-Length: 15244 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/html; charset=UTF-8
I'll key in on the Access-Control-Allow set of headers. Today, if I wanted to write a signature which ensures the value of these headers all start with * and the Access-Control-Allow-Headers matches a specific pattern, while not caring about header order, the following would have to be completed.
http.header; content:"Access-Control-Allow-Origin|3a 20 2a 0d 0a|"; content:"Access-Control-Allow-Methods|3a 20 2a 0d 0a|"; content:"Access-Control-Allow-Headers|3a 20 2a 2c 20|x-"; content:"|0d 0a|"; distance:64; within:2; pcre:"/^Access-Control-Allow-Headers\x3a\x20x-[a-f0-9]{64}\r$/m"
in the proposed, this can be rewritten as
http.header:Access-Control-Allow-Origin; content:"|2a|"; bsize:1; http.header:Access-Control-Allow-Methods; content:"|2a|"; bsize:1; http.header:Access-Control-Allow-Headers; bsize:69; content:"|2a 2c 20|x-"; startswith; pcre:"/^[a-f0-9]{64}/R"
While this is a primitive example, the ability to have sticky buffers on "dynamic" per header basis is a very powerful concept that I'd love to see in Suricata
This logic might also extend to other keywords/protocols, such as TLS and DNS
https://redmine.openinfosecfoundation.org/issues/5234
https://redmine.openinfosecfoundation.org/issues/4227
https://redmine.openinfosecfoundation.org/issues/2448