HTTP Keywords
=============

.. role:: example-rule-action
.. role:: example-rule-header
.. role:: example-rule-options
.. role:: example-rule-emphasis

Using the HTTP specific sticky buffers (see :ref:`rules-modifiers`) provides a
way to efficiently inspect the specific fields of HTTP protocol communications.
After specifying a sticky buffer in a rule it should be followed by one or
more :doc:`payload-keywords` or using :ref:`pcre`.

HTTP Primer
-----------
HTTP is considered a client-server or request-response protocol. A client
requests resources from a server and a server responds to the request.

In versions of HTTP prior to version 2 a client request could look like:

Example HTTP Request::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Host: suricata.io

Example signature that would alert on the above request.

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Request Example"; \
  flow:established,to_server; :example-rule-options:`http.method; \
  content:"GET"; http.uri; content:"/index.html"; bsize:11; http.protocol; \
  content:"HTTP/1.1"; bsize:8; http.user_agent; content:"Mozilla/5.0"; bsize:11; \
  http.host; content:"suricata.io"; bsize:11;` classtype:bad-unknown; sid:25; rev:1;)

In versions of HTTP prior to version 2 a server response could look like:

Example HTTP Response::

  HTTP/1.1 200 OK
  Content-Type: text/html
  Content-Length: 258
  Date: Thu, 14 Dec 2023 20:22:41 GMT
  Server: nginx/0.8.54
  Connection: Close

Example signature that would alert on the above response.

.. container:: example-rule

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Stat Code Example"; \
  flow:established,to_client; :example-rule-options:`http.stat_code; \
  content:"200"; bsize:8; http.content_type; content:"text/html"; bsize:9;` \
  classtype:bad-unknown; sid:30; rev:1;)

Request Keywords:
 * :ref:`file.name`
 * :ref:`http.accept`
 * :ref:`http.accept_enc`
 * :ref:`http.accept_lang`
 * :ref:`http.host`
 * :ref:`http.host.raw`
 * :ref:`http.method`
 * :ref:`http.referer`
 * :ref:`http.request_body`
 * :ref:`http.request_header`
 * :ref:`http.request_line`
 * :ref:`http.uri`
 * :ref:`http.uri.raw` 
 * :ref:`http.user_agent`
 * :ref:`urilen`

Response Keywords:
 * :ref:`http.location`
 * :ref:`http.response_body`
 * :ref:`http.response_header`
 * :ref:`http.response_line`
 * :ref:`http.server`
 * :ref:`http.stat_code`
 * :ref:`http.stat_msg`

Request or Response Keywords:
 * :ref:`file.data`
 * :ref:`http.connection`
 * :ref:`http.content_len`
 * :ref:`http.content_type`
 * :ref:`http.cookie`
 * :ref:`http.header`
 * :ref:`http.header.raw`
 * :ref:`http.header_names`
 * :ref:`http.protocol`
 * :ref:`http.start`

.. _http.normalization:

Normalization
-------------

There are times when Suricata performs formatting/normalization changes to
traffic that is seen.

Duplicate Header Names
~~~~~~~~~~~~~~~~~~~~~~

If there are multiple values for the same header name, they are concatenated
with a comma and space (", ") between each value. More information can be
found in RFC 2616 `<https://www.rfc-editor.org/rfc/rfc2616.html#section-4.2>`_

In the example below, notice that the User-Agent header, regardless of the 
letter casing is evaluated as the same header. The normalized header evaluation
leads to the concatenated header values as described in the RFC above.

Example Duplicate HTTP Header::

  GET / HTTP/1.1
  Host: suricata.io
  User-Agent: Mozilla/5.0
  User-agent: Chrome/121.0.0

.. container:: example-rule

  alert http $HOME_NET -> $EXTERNAL_NET (msg:"Example Duplicate Header"; \
  flow:established,to_server; :example-rule-options:`http.user_agent; \
  content:"Mozilla/5.0, Chrome/121.0.0";` classtype:bad-unknown; sid:103; \
  rev:1;)

.. _file.name:

file.name
---------

The ``file.name`` keyword can be used with HTTP requests.

It is possible to use any of the :doc:`payload-keywords` with the
``file.name`` keyword.

Example HTTP Request::

  GET /picture.jpg HTTP/1.1
  User-Agent: Mozilla/5.0
  Host: suricata.io

.. container:: example-rule

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP file.name Example"; \
  flow:established,to_client; :example-rule-options:`file.name; \
  content:"picture.jpg";` classtype:bad-unknown; sid:129; rev:1;)

.. note:: Additional information can be found at :doc:`file-keywords`

.. _http.accept:

http.accept
-----------

The ``http.accept`` keyword is used to match on the Accept field that
can be present in HTTP request headers.

It is possible to use any of the :doc:`payload-keywords` with the
``http.accept`` keyword.

Example HTTP Request::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Accept: */*
  Host: suricata.io

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Accept Example"; \
  flow:established,to_server; :example-rule-options:`http.accept; \
  content:"*/*";` bsize:3; classtype:bad-unknown; sid:91; rev:1;)

.. note:: ``http.accept`` does not include the leading space or trailing \\r\\n

.. note:: ``http.accept`` can have additional formatting/normalization applied
  to buffer contents, see :ref:`http.normalization` for additional details.

.. _http.accept_enc:

http.accept_enc
---------------

The ``http.accept_enc`` keyword is used to match on the Accept-Encoding field
that can be present in HTTP request headers.

It is possible to use any of the :doc:`payload-keywords` with the
``http.accept_enc`` keyword.

Example HTTP Request::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Accept-Encoding: gzip, deflate
  Host: suricata.io

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Accept-Encoding Example"; \
  flow:established,to_server; :example-rule-options:`http.accept_enc; \
  content:"gzip, deflate";` bsize:13; classtype:bad-unknown; sid:92; rev:1;)

.. note:: ``http.accept_enc`` does not include the leading space or trailing
   \\r\\n

.. note:: ``http.accept_enc`` can have additional formatting/normalization applied
  to buffer contents, see :ref:`http.normalization` for additional details.

.. _http.accept_lang:

http.accept_lang
----------------

The ``http.accept_lang`` keyword is used to match on the Accept-Language field
that can be present in HTTP request headers.

It is possible to use any of the :doc:`payload-keywords` with the
``http.accept_lang`` keyword.

Example HTTP Request::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Accept-Language: en-US
  Host: suricata.io

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Accept-Encoding Example"; \
  flow:established,to_server; :example-rule-options:`http.accept_lang; \
  content:"en-US";` bsize:5; classtype:bad-unknown; sid:93; rev:1;)

.. note:: ``http.accept_lang`` does not include the leading space or
  trailing \\r\\n

.. note:: ``http.accept_lang`` can have additional formatting/normalization applied
  to buffer contents, see :ref:`http.normalization` for additional details.

.. _http.host:

http.host
---------

Matching on the HTTP host name has two options in Suricata, the ``http.host``
and the ``http.host.raw`` sticky buffers.

It is possible to use any of the :doc:`payload-keywords` with both ``http.host``
keywords.

.. note:: The ``http.host`` keyword normalizes the host header contents. If a
  host name has uppercase characters, those would be changed to lowercase.

Normalization Example::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Host: SuRiCaTa.Io

In the above example the host buffer would contain `suricata.io`.

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Host Example"; \
  flow:established,to_server; :example-rule-options:`http.host; \
  content:"suricata.io";` bsize:11; classtype:bad-unknown; sid:123; rev:1;)

.. note:: The ``nocase`` keyword is no longer allowed since the host names
  are normalized to contain only lowercase letters.

.. note:: ``http.host`` does not contain the port associated with the host
  (i.e. suricata.io:1234). To match on the host and port or negate a host
  and port use :ref:`http.host.raw`.

.. note:: ``http.host`` does not include the leading space or trailing \\r\\n

.. note:: The ``http.host`` and ``http.host.raw`` buffers are populated
  from either the URI (if the full URI is present in the request like
  in a proxy request) or the HTTP Host header. If both are present, the
  URI is used.

.. note:: ``http.host`` can have additional formatting/normalization applied
  to buffer contents, see :ref:`http.normalization` for additional details.

.. _http.host.raw:

http.host.raw
-------------

The ``http.host.raw`` buffer matches on HTTP host content but does not have
any normalization performed on the buffer contents (see :ref:`http.host`)

Example HTTP Request::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Host: SuRiCaTa.Io:8445

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Host Raw Example"; \
  flow:established,to_server; :example-rule-options:`http.host.raw; \
  content:"SuRiCaTa.Io|3a|8445";` bsize:16; classtype:bad-unknown; sid:124; rev:1;)

.. note:: ``http.host.raw`` does not include the leading space or trailing \\r\\n

.. note:: The ``http.host`` and ``http.host.raw`` buffers are populated
  from either the URI (if the full URI is present in the request like
  in a proxy request) or the HTTP Host header. If both are present, the
  URI is used.

.. note:: ``http.host.raw`` can have additional formatting/normalization applied
  to buffer contents, see :ref:`http.normalization` for additional details.

.. _http.method:

http.method
-----------

The ``http.method`` keyword matches on the method/verb used in an HTTP request.
HTTP request methods can be any of the following:

* GET
* POST
* HEAD
* OPTIONS
* PUT
* DELETE
* TRACE
* CONNECT
* PATCH

It is possible to use any of the :doc:`payload-keywords` with the ``http.method`` keyword.

Example HTTP Request::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Host: suricata.io

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Request Example"; \
  flow:established,to_server; :example-rule-options:`http.method; \
  content:"GET";` classtype:bad-unknown; sid:2; rev:1;)

.. _http.referer:

http.referer
------------

The ``http.referer`` keyword is used to match on the Referer field that
can be present in HTTP request headers.

It is possible to use any of the :doc:`payload-keywords` with the
``http.referer`` keyword.

Example HTTP Request::

  GET / HTTP/1.1
  Host: suricata.io
  Referer: https://suricata.io

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Referer Example"; \
  flow:established,to_server; :example-rule-options:`http.referer; \
  content:"http|3a 2f 2f|suricata.io";` bsize:19; classtype:bad-unknown; \
  sid:200; rev:1;)

.. note:: ``http.referer`` does not include the leading space or trailing
   \\r\\n

.. note:: ``http.referer`` can have additional formatting/normalization applied
  to buffer contents, see :ref:`http.normalization` for additional details.

.. _http.request_body:

http.request_body
-----------------

The ``http.request_body`` keyword is used to match on the HTTP request body
that can be present in an HTTP request.

It is possible to use any of the :doc:`payload-keywords` with the
``http.request_body`` keyword.

Example HTTP Request::

  POST /suricata.php HTTP/1.1
  Content-Type: application/x-www-form-urlencoded
  Host: suricata.io
  Content-Length: 23
  Connection: Keep-Alive

  Suricata request body

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Request Body Example"; \
  flow:established,to_server; :example-rule-options:`http.request_body; \
  content:"Suricata request body";` classtype:bad-unknown; sid:115; rev:1;)

.. note:: How much of the request/client body is inspected is controlled
  in the :ref:`libhtp configuration section
  <suricata-yaml-configure-libhtp>` via the ``request-body-limit``
  setting.

.. note:: ``http.request_body`` replaces the previous keyword name,
  ``http_client_body``. ``http_client_body`` can still be used but it is
  recommended that rules be converted to use ``http.request_body``.

.. _http.request_header:

http.request_header
-------------------

The ``http.request_header`` keyword is used to match on the name and value
of a HTTP/1 or HTTP/2 request.

It is possible to use any of the :doc:`payload-keywords` with the
``http.request_header`` keyword.

For HTTP/2, the header name and value get concatenated by ": " (colon and space).
The colon and space are commonly noted with the hexadecimal format `|3a 20|`
within signatures.

To detect if an HTTP/2 header name contains a ":" (colon), the keyword
:ref:`http2.header_name` can be used.

Example HTTP/1 Request::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Host: suricata.io

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Request Example"; \
  flow:established,to_server; :example-rule-options:`http.request_header; \
  content:"Host|3a 20|suricata.io";` classtype:bad-unknown; sid:126; rev:1;)

.. note:: ``http.request_header`` does not include the trailing \\r\\n

.. _http.request_line:

http.request_line
-----------------

The ``http.request_line`` keyword is used to match on the entire contents of
the HTTP request line.

Example HTTP Request::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Host: suricata.io

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Request Example"; \
  flow:established,to_server; :example-rule-options:`http.request_line; \
  content:"GET /index.html HTTP/1.1";` bsize:24; classtype:bad-unknown; \
  sid:60; rev:1;)

.. note:: ``http.request_line`` does not include the trailing \\r\\n

.. _rules-http-uri-normalization:

.. _http.uri:

http.uri
--------

Matching on the HTTP URI buffer has two options in Suricata, the ``http.uri``
and the ``http.uri.raw`` sticky buffers.

It is possible to use any of the :doc:`payload-keywords` with both ``http.uri``
keywords.

The ``http.uri`` keyword normalizes the URI buffer. For example, if a URI has two
leading ``//``, Suricata will normalize the URI to a single leading ``/``.

Normalization Example::

  GET //index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Host: suricata.io

In this case :example-rule-emphasis:`//index.html` would be normalized to
:example-rule-emphasis:`/index.html`.

Normalized HTTP Request Example::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Host: suricata.io

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP URI Example"; \
  flow:established,to_server; :example-rule-options:`http.uri; \
  content:"/index.html";` bsize:11; classtype:bad-unknown; sid:3; rev:1;)

.. _http.uri.raw:

http.uri.raw
------------

The ``http.uri.raw`` buffer matches on HTTP URI content but does not
have any normalization performed on the buffer contents.
(see :ref:`rules-http-uri-normalization`)

Abnormal HTTP Request Example::

  GET //index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Host: suricata.io

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP URI Raw Example"; \
  flow:established,to_server; :example-rule-options:`http.uri.raw; \
  content:"//index.html";` bsize:12; classtype:bad-unknown; sid:4; rev:1;)

.. note:: The ``http.uri.raw`` keyword/buffer does not allow for spaces.

Example Request::

  GET /example spaces HTTP/1.1
  User-Agent: Mozilla/5.0
  Host: suricata.io

``http.uri.raw`` would be populated with :example-rule-header:`/example`

:ref:`http.protocol` would be populated with :example-rule-header:`spaces HTTP/1.1`

Reference: `https://redmine.openinfosecfoundation.org/issues/2881 <https://redmine.openinfosecfoundation.org/issues/2881>`_

.. _http.user_agent:

http.user_agent
---------------

The ``http.user_agent`` keyword is used to match on the User-Agent field that
can be present in HTTP request headers.

It is possible to use any of the :doc:`payload-keywords` with the
``http.user_agent`` keyword.

Example HTTP Request::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Cookie: PHPSESSION=123
  Host: suricata.io

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP User-Agent Example"; \
  flow:established,to_server; :example-rule-options:`http.user_agent; \
  content:"Mozilla/5.0";` bsize:11; classtype:bad-unknown; sid:90; rev:1;)

.. note:: ``http.user_agent`` does not include the leading space or trailing
   \\r\\n

.. note:: Using the ``http.user_agent`` generally provides better performance
   than using :ref:`http.header`.

.. note:: ``http.user_agent`` can have additional formatting/normalization
  applied to buffer contents, see :ref:`http.normalization` for additional
  details.

.. _urilen:

urilen
------

The ``urilen`` keyword is used to match on the length of the normalized request
URI. It is possible to use the ``<`` and ``>`` operators, which
indicate respectively *less than* and *larger than*.

urilen uses an :ref:`unsigned 64-bit integer <rules-integer-keywords>`.

The ``urilen`` keyword does not require a content match on the :ref:`http.uri`
buffer or the :ref:`http.uri.raw` buffer.

Example HTTP Request::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Host: suricata.io

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Request"; \
  flow:established,to_server; :example-rule-options:`urilen:11;` \
  http.method; content:"GET"; classtype:bad-unknown; sid:40; rev:1;)

The above signature would match on any HTTP GET request that has a URI
length of 11, regardless of the content or structure of the URI.

The following signatures would all alert on the example request above as well
and show the different ``urilen`` options.

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"urilen greater than 10"; \
  flow:established,to_server; :example-rule-options:`urilen:>10;` \
  classtype:bad-unknown; sid:41; rev:1;)

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"urilen less than 12"; \
  flow:established,to_server; :example-rule-options:`urilen:<12;` \
  classtype:bad-unknown; sid:42; rev:1;)

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"urilen greater/less than \
  example"; flow:established,to_server; :example-rule-options:`urilen:10<>12;` \
  classtype:bad-unknown; sid:43; rev:1;)

.. _http.location:

http.location
-------------

The ``http.location`` keyword is used to match on the HTTP response location
header contents.

It is possible to use any of the :doc:`payload-keywords` with the
``http.location`` keyword.

Example HTTP Response::

  HTTP/1.1 200 OK
  Content-Type: text/html
  Server: nginx/0.8.54
  Location: suricata.io

.. container:: example-rule

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Location Example"; \
  flow:established,to_client; :example-rule-options:`http.location; \
  content:"suricata.io";` bsize:11; classtype:bad-unknown; sid:122; rev:1;)

.. note:: ``http.location`` does not include the leading space or trailing \\r\\n

.. note:: ``http.location`` can have additional formatting/normalization applied
  to buffer contents, see :ref:`http.normalization` for additional details.

.. _http.response_body:

http.response_body
------------------

The ``http.response_body`` keyword is used to match on the HTTP response body.

It is possible to use any of the :doc:`payload-keywords` with the
``http.response_body`` keyword.

Example HTTP Response::

  HTTP/1.1 200 OK
  Content-Type: text/html
  Server: nginx/0.8.54

  Server response body

.. container:: example-rule

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Response Body \
  Example"; flow:established,to_client; :example-rule-options:`http.response_body; \
  content:"Server response body";` classtype:bad-unknown; sid:120; rev:1;)

.. note:: ``http.response_body`` will match on gzip decoded data just like
  :ref:`file.data` does.

.. note:: How much of the response/server body is inspected is controlled
  in your :ref:`libhtp configuration section
  <suricata-yaml-configure-libhtp>` via the ``response-body-limit``
  setting.

.. note:: ``http.response_body`` replaces the previous keyword name,
  ``http_server_body``. ``http_server_body`` can still be used but it is
  recommended that rules be converted to use ``http.response_body``.

.. _http.response_header:

http.response_header
--------------------

The ``http.response_header`` keyword is used to match on the name and value
of an HTTP/1 or HTTP/2 request.

It is possible to use any of the :doc:`payload-keywords` with the
``http.response_header`` keyword.

For HTTP/2, the header name and value get concatenated by ": " (colon and space).
The colon and space are commonly noted with the hexadecimal format `|3a 20|`
within signatures.

To detect if an HTTP/2 header name contains a ":" (colon), the keyword
:ref:`http2.header_name` can be used.

Example HTTP Response::

  HTTP/1.1 200 OK
  Content-Type: text/html
  Server: nginx/0.8.54
  Location: suricata.io

.. container:: example-rule

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Response Example"; \
  flow:established,to_client; :example-rule-options:`http.response_header; \
  content:"Location|3a 20|suricata.io";` classtype:bad-unknown; sid:127; rev:1;)

.. _http.response_line:

http.response_line
------------------

The ``http.response_line`` keyword is used to match on the entire HTTP
response line.

It is possible to use any of the :doc:`payload-keywords` with the
``http.response_line`` keyword.

Example HTTP Response::

  HTTP/1.1 200 OK
  Content-Type: text/html
  Server: nginx/0.8.54

.. container:: example-rule

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Response Line \
  Example"; flow:established,to_client; :example-rule-options:`http.response_line; \
  content:"HTTP/1.1 200 OK";` classtype:bad-unknown; sid:119; rev:1;)

.. note:: ``http.response_line`` does not include the trailing \\r\\n

.. _http.server:

http.server
-----------

The ``http.server`` keyword is used to match on the HTTP response server
header contents.

It is possible to use any of the :doc:`payload-keywords` with the
``http.server`` keyword.

Example HTTP Response::

  HTTP/1.1 200 OK
  Content-Type: text/html
  Server: nginx/0.8.54

.. container:: example-rule

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Server Example"; flow:established,to_client; :example-rule-options:`http.server; \
  content:"nginx/0.8.54";` bsize:12; classtype:bad-unknown; sid:121; rev:1;)

.. note:: ``http.server`` does not include the leading space or trailing \\r\\n

.. note:: ``http.server`` can have additional formatting/normalization
  applied to buffer contents, see :ref:`http.normalization` for additional
  details.

.. _http.stat_code:

http.stat_code
--------------

The ``http.stat_code`` keyword is used to match on the HTTP status code
that can be present in an HTTP response.

It is possible to use any of the :doc:`payload-keywords` with the
``http.stat_code`` keyword.

Example HTTP Response::

  HTTP/1.1 200 OK
  Content-Type: text/html
  Server: nginx/0.8.54

.. container:: example-rule

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Stat Code Response \
  Example"; flow:established,to_client; :example-rule-options:`http.stat_code; \
  content:"200";` classtype:bad-unknown; sid:117; rev:1;)

.. note:: ``http.stat_code`` does not include the leading or trailing space

.. _http.stat_msg:

http.stat_msg
-------------

The ``http.stat_msg`` keyword is used to match on the HTTP status message
that can be present in an HTTP response.

For HTTP/2, an empty buffer is returned by Suricata.
See rfc 7540 section 8.1.2.4. about Response Pseudo-Header Fields.

It is possible to use any of the :doc:`payload-keywords` with the
``http.stat_msg`` keyword.

Example HTTP Response::

  HTTP/1.1 200 OK
  Content-Type: text/html
  Server: nginx/0.8.54

.. container:: example-rule

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Stat Message Response \
  Example"; flow:established,to_client; :example-rule-options:`http.stat_msg; \
  content:"OK";` classtype:bad-unknown; sid:118; rev:1;)

.. note:: ``http.stat_msg`` does not include the leading space or trailing \\r\\n

.. note:: ``http.stat_msg`` will always be empty when used with HTTP/2

.. _file.data:

file.data
---------

With ``file.data``, the HTTP response body is inspected, just like
with ``http.response_body``. ``file.data`` also works for HTTP request
body and can be used in protocols other than HTTP.

It is possible to use any of the :doc:`payload-keywords` with the
``file.data`` keyword.

Example HTTP Response::

  HTTP/1.1 200 OK
  Content-Type: text/html
  Server: nginx/0.8.54

  Server response body

.. container:: example-rule

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP file.data Example"; \
  flow:established,to_client; :example-rule-options:`file.data; \
  content:"Server response body";` classtype:bad-unknown; sid:128; rev:1;)

The body of an HTTP response can be very large, therefore the response body is
inspected in definable chunks.

How much of the response/server body is inspected is controlled
in the :ref:`libhtp configuration section
<suricata-yaml-configure-libhtp>` via the ``response-body-limit``
setting.

.. note:: If the HTTP body is a flash file compressed with 'deflate' or 'lzma',
  it can be decompressed and ``file.data`` can match on the decompressed data.
  Flash decompression must be enabled under 'libhtp' configuration:

  ::

    # Decompress SWF files.
    # 2 types: 'deflate', 'lzma', 'both' will decompress deflate and lzma
    # compress-depth:
    # Specifies the maximum amount of data to decompress,
    # set 0 for unlimited.
    # decompress-depth:
    # Specifies the maximum amount of decompressed data to obtain,
    # set 0 for unlimited.
    swf-decompression:
      enabled: yes
      type: both
      compress-depth: 0
      decompress-depth: 0

.. note:: ``file.data`` replaces the previous keyword name, ``file_data``.
  ``file_data`` can still be used but it is recommended that rules be converted
  to use ``file.data``.

.. note:: If an HTTP body is using gzip or deflate, ``file.data`` will match on
  the decompressed data.

.. note:: Negated matching is affected by the chunked inspection. E.g.
   'content:!"<html";' could not match on the first chunk, but would
   then possibly match on the 2nd. To avoid this, use a depth setting.
   The depth setting takes the body size into account. Assuming that
   the ``response-body-minimal-inspect-size`` is bigger than 1k,
   'content:!"<html"; depth:1024;' can only match if the pattern '<html'
   is absent from the first inspected chunk.

.. note:: Additional information can be found at :doc:`file-keywords`

.. note:: ``file.data`` supports multiple buffer matching, see
  :doc:`multi-buffer-matching`.

.. _http.connection:

http.connection
---------------

The ``http.connection`` keyword is used to match on the Connection field that
can be present in HTTP request or response headers.

It is possible to use any of the :doc:`payload-keywords` with the
``http.connection`` keyword.

Example HTTP Request::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Accept-Language: en-US
  Host: suricata.io
  Connection: Keep-Alive

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Connection Example"; \
  flow:established,to_server; :example-rule-options:`http.connection; \
  content:"Keep-Alive";` bsize:10; classtype:bad-unknown; sid:94; rev:1;)

.. note:: ``http.connection`` does not include the leading space or trailing
   \\r\\n

.. note:: ``http.connection`` can have additional formatting/normalization
  applied to buffer contents, see :ref:`http.normalization` for additional
  details.

.. _http.content_len:

http.content_len
----------------

The ``http.content_len`` keyword is used to match on the Content-Length field that
can be present in HTTP request or response headers. Use ``flow:to_server`` or
``flow:to_client`` to force inspection of the request or response respectively.

It is possible to use any of the :doc:`payload-keywords` with the
``http.content_len`` keyword.

Example HTTP Request::

  POST /suricata.php HTTP/1.1
  Content-Type: multipart/form-data; boundary=---------------123
  Host: suricata.io
  Content-Length: 100
  Connection: Keep-Alive

Example HTTP Response::

  HTTP/1.1 200 OK
  Content-Type: text/html
  Server: nginx/0.8.54
  Connection: Close
  Content-Length: 20

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Content-Length Request \
  Example"; flow:established,to_server; :example-rule-options:`http.content_len; \
  content:"100";` bsize:3; classtype:bad-unknown; sid:97; rev:1;)

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Content-Length Response \
  Example"; flow:established,to_client; :example-rule-options:`http.content_len; \
  content:"20";` bsize:2; classtype:bad-unknown; sid:98; rev:1;)

To do numeric evaluation of the content length, :ref:`byte_test` can be used.

If we want to match on an HTTP request content length equal to and greater
than 100 we could use the following signature.

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Content-Length Request \
  Byte Test Example"; flow:established,to_server; \
  :example-rule-options:`http.content_len; byte_test:0,>=,100,0,string,dec;` \
  classtype:bad-unknown; sid:99; rev:1;)

.. note:: ``http.content_len`` does not include the leading space or trailing
   \\r\\n

.. _http.content_type:

http.content_type
-----------------

The ``http.content_type`` keyword is used to match on the Content-Type field that
can be present in HTTP request or response headers. Use ``flow:to_server`` or
``flow:to_client`` to force inspection of the request or response respectively.

It is possible to use any of the :doc:`payload-keywords` with the
``http.content_type`` keyword.

Example HTTP Request::

  POST /suricata.php HTTP/1.1
  Content-Type: multipart/form-data; boundary=---------------123
  Host: suricata.io
  Content-Length: 100
  Connection: Keep-Alive

Example HTTP Response::

  HTTP/1.1 200 OK
  Content-Type: text/html
  Server: nginx/0.8.54
  Connection: Close

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Content-Type Request \
  Example"; flow:established,to_server; :example-rule-options:`http.content_type; \
  content:"multipart/form-data|3b 20|";` startswith; classtype:bad-unknown; \
  sid:95; rev:1;)

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Content-Type Response \
  Example"; flow:established,to_client; :example-rule-options:`http.content_type; \
  content:"text/html";` bsize:9; classtype:bad-unknown; sid:96; rev:1;)

.. note:: ``http.content_type`` does not include the leading space or trailing
   \\r\\n

.. note:: ``http.content_type`` can have additional formatting/normalization
  applied to buffer contents, see :ref:`http.normalization` for additional
  details.

.. _http.cookie:

http.cookie
-----------

The ``http.cookie`` keyword is used to match on the cookie field that can be
present in HTTP request (Cookie) or HTTP response (Set-Cookie) headers.

It is possible to use any of the :doc:`payload-keywords` with both ``http.header``
keywords.

Example HTTP Request::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Cookie: PHPSESSION=123
  Host: suricata.io

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Cookie Example"; \
  flow:established,to_server; :example-rule-emphasis:`http.cookie; \
  content:"PHPSESSIONID=123";` bsize:14; classtype:bad-unknown; sid:80; rev:1;)

.. note:: Cookies are passed in HTTP headers but Suricata extracts the cookie
  data to ``http.cookie`` and will not match cookie content put in the
  :ref:`http.header` sticky buffer.

.. note:: ``http.cookie`` does not include the leading space or trailing \\r\\n

.. note:: ``http.cookie`` can have additional formatting/normalization
  applied to buffer contents, see :ref:`http.normalization` for additional
  details.

.. _http.header:

http.header
-----------

Matching on HTTP headers has two options in Suricata, the ``http.header``
and the ``http.header.raw``.

It is possible to use any of the :doc:`payload-keywords` with both
``http.header`` keywords.

The ``http.header`` keyword normalizes the header contents. For example if
header contents contain trailing white-space or tab characters, those would be
removed.

To match on non-normalized header data, use the :ref:`http.header.raw` keyword.

Normalization Example::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0     \r\n
  Host: suricata.io

Would be normalized to :example-rule-emphasis:`Mozilla/5.0\\r\\n`

Example HTTP Request::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Host: suricata.io

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Header Example 1"; \
  flow:established,to_server; :example-rule-options:`http.header; \
  content:"User-Agent|3a 20|Mozilla/5.0|0d 0a|";` classtype:bad-unknown; \
  sid:70; rev:1;)

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Header Example 2"; \
  flow:established,to_server; :example-rule-options:`http.header; \
  content:"Host|3a 20|suricata.io|0d 0a|";` classtype:bad-unknown; \
  sid:71; rev:1;)

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Header Example 3"; \
  flow:established,to_server; :example-rule-options:`http.header; \
  content:"User-Agent|3a 20|Mozilla/5.0|0d 0a|"; startswith; \
  content:"Host|3a 20|suricata.io|0d 0a|";` classtype:bad-unknown; \
  sid:72; rev:1;)

.. note:: There are headers that will not be included in the ``http.header``
  buffer, specifically the :ref:`http.cookie` buffer.

.. note:: ``http.header`` can have additional formatting/normalization applied
  to buffer contents, see :ref:`http.normalization` for additional details.

.. _http.header.raw:

http.header.raw
---------------

The ``http.header.raw`` buffer matches on HTTP header content but does not have
any normalization performed on the buffer contents (see :ref:`http.header`)

Abnormal HTTP Header Example::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  User-Agent: Chrome
  Host: suricata.io

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Header Raw Example"; \
  flow:established,to_server; :example-rule-options:`http.header.raw; \
  content:"User-Agent|3a 20|Mozilla/5.0|0d 0a|"; \
  content:"User-Agent|3a 20|Chrome|0d 0a|";` classtype:bad-unknown; sid:73; rev:1;)

.. note:: ``http.header.raw`` can have additional formatting applied to buffer
  contents, see :ref:`http.normalization` for additional details.

.. _http.header_names:

http.header_names
-----------------

The ``http.header_names`` keyword is used to match on the names of the headers
in an HTTP request or response. This is useful for checking for a header's
presence, absence and/or header order. Use ``flow:to_server`` or
``flow:to_client`` to force inspection of the request or response respectively.

It is possible to use any of the :doc:`payload-keywords` with the
``http.header_names`` keyword.

Example HTTP Request::

  GET / HTTP/1.1
  Host: suricata.io
  Connection: Keep-Alive

Example HTTP Response::

  HTTP/1.1 200 OK
  Content-Type: text/html
  Server: nginx/0.8.54

Examples to match exactly on header order:

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Header Names Request \
  Example"; flow:established,to_server; :example-rule-options:`http.header_names; \
  content:"|0d 0a|Host|0d 0a|Connection|0d 0a 0d 0a|";` bsize:22; \
  classtype:bad-unknown; sid:110; rev:1;)

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Header Names Response \
  Example"; flow:established,to_client; :example-rule-options:`http.header_names; \
  content:"|0d 0a|Content-Type|0d 0a|Server|0d 0a 0d a0|";` bsize:26; \
  classtype:bad-unknown; sid:111; rev:1;)

Examples to match on header existence:

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Header Names Request \
  Example 2"; flow:established,to_server; :example-rule-options:`http.header_names; \
  content:"|0d 0a|Host|0d 0a|";` classtype:bad-unknown; sid:112; rev:1;)

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Header Names Response \
  Example 2"; flow:established,to_client; :example-rule-options:`http.header_names; \
  content:"|0d 0a|Content-Type|0d 0a|";` classtype:bad-unknown; sid:113; rev:1;)

Examples to match on header absence:

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Header Names Request \
  Example 3"; flow:established,to_server; :example-rule-options:`http.header_names; \
  content:!"|0d 0a|User-Agent|0d 0a|";` classtype:bad-unknown; sid:114; rev:1;)

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Header Names Response \
  Example 3"; flow:established,to_client; :example-rule-options:`http.header_names; \
  content:!"|0d 0a|Date|0d 0a|";` classtype:bad-unknown; sid:115; rev:1;)

Example to check for the ``User-Agent`` header and that the ``Host`` header is
after ``User-Agent`` but not necessarily directly after.

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Header Names Request \
  Example 4"; flow:established,to_server; :example-rule-options:`http.header_names; \
  content:"|0d 0a|Host|0d 0a|";` content:"User-Agent|0d 0a|"; distance:-2; \
  classtype:bad-unknown; sid:114; rev:1;)

.. note:: ``http.header_names`` starts with a \\r\\n and ends with an extra \\r\\n.

.. note:: ``http.header_names`` can have additional formatting/normalization applied
  to buffer contents, see :ref:`http.normalization` for additional details.

.. _http.protocol:

http.protocol
-------------

The ``http.protocol`` keyword is used to match on the protocol field that is
contained in HTTP requests and responses.

For HTTP/2, the constant string "HTTP/2" is used.
See rfc 7540 section 8.1.2.4. about Response Pseudo-Header Fields.

It is possible to use any of the :doc:`payload-keywords` with the
``http.protocol`` keyword.

.. note:: ``http.protocol`` does not include the leading space or trailing \\r\\n

Example HTTP Request::

  GET /index.html HTTP/1.1
  User-Agent: Mozilla/5.0
  Host: suricata.io

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Protocol Example"; \
  flow:established,to_server; :example-rule-options:`http.protocol; \
  content:"HTTP/1.1";` bsize:9; classtype:bad-unknown; sid:50; rev:1;)

.. _http.start:

http.start
----------

The ``http.start`` keyword is used to match on the start of an HTTP request
or response. This will contain the request/response line plus the request/response
headers. Use ``flow:to_server`` or ``flow:to_client`` to force inspection of the
request or response respectively.

It is possible to use any of the :doc:`payload-keywords` with the
``http.start`` keyword.

Example HTTP Request::

  GET / HTTP/1.1
  Host: suricata.io
  Connection: Keep-Alive

Example HTTP Response::

  HTTP/1.1 200 OK
  Content-Type: text/html
  Server: nginx/0.8.54

.. container:: example-rule

  alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Start Request \
  Example"; flow:established,to_server; :example-rule-options:`http.start; \
  content:"POST / HTTP/1.1|0d 0a|Host|0d 0a|Connection|0d 0a 0d 0a|";` \
  classtype:bad-unknown; sid:101; rev:1;)

  alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Start Response \
  Example"; flow:established,to_client; :example-rule-options:`http.start; \
  content:"HTTP/1.1 200 OK|0d 0a|Content-Type|0d 0a|Server|0d 0a 0d a0|";` \
  classtype:bad-unknown; sid:102; rev:1;)

.. note:: ``http.start`` contains the normalized headers and is terminated by
  an extra \\r\\n to indicate the end of the headers.
