http_uri and http_raw_uri

These two sticky buffers, http_uri and http_raw_uri, look for data in HTTP request URIs. The http_uri buffer contains the full normalized URI whereas the http_raw_uri contains the unnormalized URI.

Snort 3 also parses HTTP URIs into six individual components and makes them available as optional selectors to these two buffers. Those six components are path, query, fragment, host, port, and scheme.

The following HTTP request line contains an absolute URI with all six components, and they are broken down below it:

GET https://www.samplehost.com:287/basic/example/of/path?with-query=value#and-fragment HTTP/1.1\r\n
  1. path -> /basic/example/of/path
  2. query -> with-query=value
  3. fragment -> #and-fragment
  4. host -> www.samplehost.com
  5. port -> 287
  6. scheme -> https

The contents of the general URI buffer and each individual component depend on request URI type. There are four main URI types that Snort can parse. These include asterisk URIs, which contain just a '*' character, absolute URI URIs, which contain all six components (if they're all present), absolute path URIs, which contain the path, query, and fragment (which is not often sent over the network), and lastly authority URIs, which contain the host and port.

Specifying an optional URI selector is done with a colon after http_uri or http_raw_uri followed by the selector name.

http_uri

As mentioned above, http_uri sticky buffer searches proceeding payload options in the normalized URI. Snort parses an HTTP request, normalizes anything in the URI that needs normalization, and then places the end-result in the http_uri buffer. This normalization does things like decode percent-encoded values (e.g., "%41%41" -> "AA"), replace backslashes with forward slashes, replace plus characters with spaces, remove path directory traversals, simplify paths (e.g., "/nothing/../to/././././see//////detour/to/nowhere/../.././../example" -> "/very/easy/example"), and more.

There is not an exhaustive list, and some are disabled by default, but the full list can be found in the http_inspect documentation.

Note: Any data in URIs that are not "unnormalized" will of course be left intact and included in the http_uri buffer as-is.

Format:

http_uri[:{scheme|host|port|path|query|fragment}];

Examples:

http_uri;
content:"/basic/example/of/path?query=value",fast_pattern,nocase;
http_uri;
content:"/basic/example/of/path",fast_pattern,nocase;
http_uri:query;
content:"query=value",nocase;

http_raw_uri

The http_raw_uri sticky buffer searches proceeding content matches in the unnormalized URI. Testing against this buffer is often useful when one wants to explicitly look for things like percent-encoded data and directory traversal attempts.

Consider the following raw absolute path URI:

/%63%68%6F%63%6F%6C%61%74%65/%63%61%6B%65

Snort will normalize this data and put the percent-decoded values in the http_uri buffer. However, the http_raw_uri buffer will still contain the URI in its raw form, allowing us to check for this percent-encoded string.

Format:

http_raw_uri[:{scheme|host|port|path|query|fragment}];

Examples:

http_raw_uri;
content:"/%63%68%6F%63%6F%6C%61%74%65/%63%61%6B%65";
http_raw_uri;
content:"../";