classtype:bad-unknown; sid:30; rev:1;)
Request Keywords:
- * :ref:`http.uri`
- * :ref:`http.uri.raw`
- * :ref:`http.method`
- * :ref:`http.request_line`
- * :ref:`http.request_body`
- * :ref:`http.user_agent`
- * :ref:`http.host`
+ * :ref:`file.name`
* :ref:`http.accept`
- * :ref:`http.accept_lang`
* :ref:`http.accept_enc`
+ * :ref:`http.accept_lang`
+ * :ref:`http.host`
+ * :ref:`http.host.raw`
+ * :ref:`http.method`
* :ref:`http.referer`
- * :ref:`file.name`
+ * :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.stat_msg`
- * :ref:`http.stat_code`
- * :ref:`http.response_line`
+ * :ref:`http.location`
* :ref:`http.response_body`
+ * :ref:`http.response_header`
+ * :ref:`http.response_line`
* :ref:`http.server`
- * :ref:`http.location`
+ * :ref:`http.stat_code`
+ * :ref:`http.stat_msg`
Request or Response Keywords:
* :ref:`file.data`
- * :ref:`http.content_type`
* :ref:`http.content_len`
- * :ref:`http.start`
- * :ref:`http.protocol`
- * :ref:`http.header_names`
+ * :ref:`http.content_type`
+ * :ref:`http.cookie`
* :ref:`http.header`
* :ref:`http.header.raw`
- * :ref:`http.cookie`
-
-.. _http.method:
+ * :ref:`http.header_names`
+ * :ref:`http.protocol`
+ * :ref:`http.start`
-http.method
------------
+.. _file.name:
-The ``http.method`` keyword matches on the method/verb used in an HTTP request.
-HTTP request methods can be any of the following:
+file.name
+---------
-* GET
-* POST
-* HEAD
-* OPTIONS
-* PUT
-* DELETE
-* TRACE
-* CONNECT
-* PATCH
+The ``file.name`` keyword can be used with HTTP requests.
-It is possible to use any of the :doc:`payload-keywords` with the ``http.method`` keyword.
+It is possible to use any of the :doc:`payload-keywords` with the
+``file.name`` keyword.
Example HTTP Request::
- GET /index.html HTTP/1.1
+ GET /picture.jpg 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;)
-
-.. _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.
+ 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;)
-It is possible to use any of the :doc:`payload-keywords` with both ``http.uri``
-keywords.
+.. note:: Additional information can be found at :doc:`file-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 ``/``.
+.. _http.accept:
-Normalization Example::
+http.accept
+-----------
- GET //index.html HTTP/1.1
- User-Agent: Mozilla/5.0
- Host: suricata.io
+The ``http.accept`` keyword is used to match on the Accept field that
+can be present in HTTP request headers.
-In this case :example-rule-emphasis:`//index.html` would be normalized to
-:example-rule-emphasis:`/index.html`.
+It is possible to use any of the :doc:`payload-keywords` with the
+``http.accept`` keyword.
-Normalized HTTP Request Example::
+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 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`)
+ 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;)
-Abnormal HTTP Request Example::
+.. note:: ``http.accept`` does not include the leading space or trailing \\r\\n
- GET //index.html HTTP/1.1
- User-Agent: Mozilla/5.0
- Host: suricata.io
+.. _http.accept_enc:
-.. container:: example-rule
+http.accept_enc
+---------------
- 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;)
+The ``http.accept_enc`` keyword is used to match on the Accept-Encoding field
+that can be present in HTTP request headers.
-.. note:: The ``http.uri.raw`` keyword/buffer does not allow for spaces.
+It is possible to use any of the :doc:`payload-keywords` with the
+``http.accept_enc`` keyword.
-Example Request::
+Example HTTP Request::
- GET /example spaces HTTP/1.1
+ GET /index.html HTTP/1.1
User-Agent: Mozilla/5.0
+ Accept-Encoding: gzip, deflate
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`
+.. container:: example-rule
-Reference: `https://redmine.openinfosecfoundation.org/issues/2881 <https://redmine.openinfosecfoundation.org/issues/2881>`_
+ 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;)
-.. _urilen:
+.. note:: ``http.accept_enc`` does not include the leading space or trailing
+ \\r\\n
-urilen
-------
+.. _http.accept_lang:
-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*.
+http.accept_lang
+----------------
-urilen uses an :ref:`unsigned 64-bit integer <rules-integer-keywords>`.
+The ``http.accept_lang`` keyword is used to match on the Accept-Language field
+that can be present in HTTP request headers.
-The ``urilen`` keyword does not require a content match on the :ref:`http.uri`
-buffer or the :ref:`http.uri.raw` buffer.
+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 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:"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;)
- 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;)
+.. note:: ``http.accept_lang`` does not include the leading space or
+ trailing \\r\\n
-.. _http.protocol:
+.. _http.connection:
-http.protocol
--------------
+http.connection
+---------------
-The ``http.protocol`` keyword is used to match on the protocol field that is
-contained in HTTP requests and responses.
+The ``http.connection`` keyword is used to match on the Connection field that
+can be present in HTTP request headers.
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
+``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 Protocol Example"; \
- flow:established,to_server; :example-rule-options:`http.protocol; \
- content:"HTTP/1.1";` bsize:9; classtype:bad-unknown; sid:50; rev:1;)
+ 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;)
-.. _http.request_line:
+.. note:: ``http.connection`` does not include the leading space or trailing
+ \\r\\n
-http.request_line
------------------
+.. _http.host:
-The ``http.request_line`` keyword is used to match on the entire contents of
-the HTTP request line.
+http.host
+---------
-Example HTTP Request::
+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
+ 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 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;)
+ 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:: ``http.request_line`` does not include the trailing \\r\\n
+.. note:: The ``nocase`` keyword is no longer allowed since the host names
+ are normalized to contain only lowercase letters.
-.. _http.header:
+.. 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`.
-http.header
------------
+.. note:: ``http.host`` does not include the leading space or trailing \\r\\n
-Matching on HTTP headers has two options in Suricata, the ``http.header``
-and the ``http.header.raw``.
+.. 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.
-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.
+.. note:: If a request contains multiple "Host" headers, the values will be
+ concatenated in the ``http.host`` and ``http.host.raw``
+ buffers, in the order seen from top to bottom, with a comma and space
+ (", ") between each of them.
-Normalization Example::
+Example Duplicate Host Header Request::
GET /index.html HTTP/1.1
- User-Agent: Mozilla/5.0 \r\n
+ User-Agent: Chrome/2.0
+ Cookie: PHPSESSION=123
Host: suricata.io
+ Host: oisf.net
-Would be normalized to :example-rule-emphasis:`Mozilla/5.0\\r\\n`
+.. container:: example-rule
-Example HTTP Request::
+ alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Two Host Example"; \
+ flow:established,to_server; :example-rule-options:`http.host; \
+ content:"suricata.io, oisf.net";` classtype:bad-unknown; sid:125; rev:1;)
- GET /index.html HTTP/1.1
- User-Agent: Mozilla/5.0
- Host: suricata.io
+.. _http.host.raw:
-.. container:: example-rule
+http.host.raw
+-------------
- 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;)
+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`)
- 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;)
+Example HTTP Request::
- 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;)
+ GET /index.html HTTP/1.1
+ User-Agent: Mozilla/5.0
+ Host: SuRiCaTa.Io:8445
-.. note:: There are headers that will not be included in the ``http.header``
- buffer, specifically the :ref:`http.cookie` buffer.
+.. container:: example-rule
-.. note:: 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>`_
+ 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;)
-.. _http.header.raw:
+.. note:: ``http.host.raw`` does not include the leading space or trailing \\r\\n
-http.header.raw
----------------
+.. 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.
-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`)
+.. note:: If a request contains multiple "Host" headers, the values will be
+ concatenated in the ``http.host`` and ``http.host.raw`` buffers, in the
+ order seen from top to bottom, with a comma and space (", ") between each
+ of them.
-Abnormal HTTP Header Example::
+Example Duplicate Host Header Request::
GET /index.html HTTP/1.1
- User-Agent: Mozilla/5.0
- User-Agent: Chrome
+ User-Agent: Chrome/2.0
+ Cookie: PHPSESSION=123
Host: suricata.io
+ Host: oisf.net
.. 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;)
+ alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Two Host Example"; \
+ flow:established,to_server; :example-rule-options:`http.host.raw; \
+ content:"suricata.io, oisf.net";` classtype:bad-unknown; sid:125; rev:1;)
-.. _http.cookie:
+.. _http.method:
-http.cookie
+http.method
-----------
-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.
+The ``http.method`` keyword matches on the method/verb used in an HTTP request.
+HTTP request methods can be any of the following:
-.. 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.
+* GET
+* POST
+* HEAD
+* OPTIONS
+* PUT
+* DELETE
+* TRACE
+* CONNECT
+* PATCH
-.. note:: ``http.cookie`` does not include the leading space or trailing \\r\\n
+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
- 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;)
+ 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.user_agent:
+.. _http.referer:
-http.user_agent
----------------
+http.referer
+------------
-The ``http.user_agent`` keyword is used to match on the User-Agent field that
+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.user_agent`` keyword.
+``http.referer`` keyword.
Example HTTP Request::
- GET /index.html HTTP/1.1
- User-Agent: Mozilla/5.0
- Cookie: PHPSESSION=123
+ GET / HTTP/1.1
Host: suricata.io
+ Referer: https://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;)
+ 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.user_agent`` does not include the leading space or trailing
+.. note:: ``http.referer`` 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`.
+.. _http.request_body:
-.. note:: If a request contains multiple "User-Agent" headers, the values will
- be concatenated in the ``http.user_agent`` buffer, in the order seen from
- top to bottom, with a comma and space (", ") between each of them.
+http.request_body
+-----------------
-Example Duplicate User-Agent Header Request::
+The ``http.request_body`` keyword is used to match on the HTTP request body
+that can be present in an HTTP request.
- GET /index.html HTTP/1.1
- User-Agent: Mozilla/5.0
- User-Agent: Chrome/2.0
- Cookie: PHPSESSION=123
+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 User-Agent Example"; \
- flow:established,to_server; :example-rule-options:`http.user_agent; \
- content:"Mozilla/5.0, Chrome/2.0";` bsize:23; classtype:bad-unknown; sid:90; \
- rev:1;)
+ 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;)
-.. _http.accept:
+.. 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.
-http.accept
------------
+.. 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``.
-The ``http.accept`` keyword is used to match on the Accept field that
-can be present in HTTP request headers.
+.. _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.accept`` keyword.
+``http.request_header`` keyword.
-Example HTTP Request::
+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
- 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
+ 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;)
-.. _http.accept_enc:
+.. note:: ``http.request_header`` does not include the trailing \\r\\n
-http.accept_enc
----------------
+.. _http.request_line:
-The ``http.accept_enc`` keyword is used to match on the Accept-Encoding field
-that can be present in HTTP request headers.
+http.request_line
+-----------------
-It is possible to use any of the :doc:`payload-keywords` with the
-``http.accept_enc`` keyword.
+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
- 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;)
+ 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.accept_enc`` does not include the leading space or trailing
- \\r\\n
+.. note:: ``http.request_line`` does not include the trailing \\r\\n
-.. _http.accept_lang:
+.. _rules-http-uri-normalization:
-http.accept_lang
-----------------
+.. _http.uri:
-The ``http.accept_lang`` keyword is used to match on the Accept-Language field
-that can be present in HTTP request headers.
+http.uri
+--------
-It is possible to use any of the :doc:`payload-keywords` with the
-``http.accept_lang`` keyword.
+Matching on the HTTP URI buffer has two options in Suricata, the ``http.uri``
+and the ``http.uri.raw`` sticky buffers.
-Example HTTP Request::
+It is possible to use any of the :doc:`payload-keywords` with both ``http.uri``
+keywords.
- 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
-
-.. _http.connection:
+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 ``/``.
-http.connection
----------------
+Normalization Example::
-The ``http.connection`` keyword is used to match on the Connection field that
-can be present in HTTP request headers.
+ GET //index.html HTTP/1.1
+ User-Agent: Mozilla/5.0
+ Host: suricata.io
-It is possible to use any of the :doc:`payload-keywords` with the
-``http.connection`` keyword.
+In this case :example-rule-emphasis:`//index.html` would be normalized to
+:example-rule-emphasis:`/index.html`.
-Example HTTP Request::
+Normalized HTTP Request Example::
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;)
+ 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;)
-.. note:: ``http.connection`` does not include the leading space or trailing
- \\r\\n
+.. _http.uri.raw:
-.. _http.content_type:
+http.uri.raw
+------------
-http.content_type
------------------
+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`)
-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.
+Abnormal HTTP Request Example::
-It is possible to use any of the :doc:`payload-keywords` with the
-``http.content_type`` keyword.
+ GET //index.html HTTP/1.1
+ User-Agent: Mozilla/5.0
+ Host: suricata.io
-Example HTTP Request::
+.. container:: example-rule
- POST /suricata.php HTTP/1.1
- Content-Type: multipart/form-data; boundary=---------------123
- Host: suricata.io
- Content-Length: 100
- Connection: Keep-Alive
+ 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;)
-Example HTTP Response::
+.. note:: The ``http.uri.raw`` keyword/buffer does not allow for spaces.
- HTTP/1.1 200 OK
- Content-Type: text/html
- Server: nginx/0.8.54
- Connection: Close
+Example Request::
-.. container:: example-rule
+ GET /example spaces HTTP/1.1
+ User-Agent: Mozilla/5.0
+ Host: suricata.io
- 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;)
+``http.uri.raw`` would be populated with :example-rule-header:`/example`
- 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;)
+:ref:`http.protocol` would be populated with :example-rule-header:`spaces HTTP/1.1`
-.. note:: ``http.content_type`` does not include the leading space or trailing
- \\r\\n
+Reference: `https://redmine.openinfosecfoundation.org/issues/2881 <https://redmine.openinfosecfoundation.org/issues/2881>`_
-.. _http.content_len:
+.. _http.user_agent:
-http.content_len
-----------------
+http.user_agent
+---------------
-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.
+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.content_len`` keyword.
+``http.user_agent`` keyword.
Example HTTP Request::
- POST /suricata.php HTTP/1.1
- Content-Type: multipart/form-data; boundary=---------------123
+ GET /index.html HTTP/1.1
+ User-Agent: Mozilla/5.0
+ Cookie: PHPSESSION=123
Host: suricata.io
- Content-Length: 100
- Connection: Keep-Alive
-Example HTTP Response::
+.. container:: example-rule
- HTTP/1.1 200 OK
- Content-Type: text/html
- Server: nginx/0.8.54
- Connection: Close
- Content-Length: 20
+ 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;)
-.. container:: example-rule
+.. note:: ``http.user_agent`` does not include the leading space or trailing
+ \\r\\n
- 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;)
+.. note:: Using the ``http.user_agent`` generally provides better performance
+ than using :ref:`http.header`.
- 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;)
+.. note:: If a request contains multiple "User-Agent" headers, the values will
+ be concatenated in the ``http.user_agent`` buffer, in the order seen from
+ top to bottom, with a comma and space (", ") between each of them.
-To do numeric evaluation of the content length, :ref:`byte_test` can be used.
+Example Duplicate User-Agent Header Request::
-If we want to match on an HTTP request content length equal to and greater
-than 100 we could use the following signature.
+ GET /index.html HTTP/1.1
+ User-Agent: Mozilla/5.0
+ User-Agent: Chrome/2.0
+ Cookie: PHPSESSION=123
+ Host: suricata.io
.. 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;)
+ 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, Chrome/2.0";` bsize:23; classtype:bad-unknown; sid:90; \
+ rev:1;)
-.. note:: ``http.content_len`` does not include the leading space or trailing
- \\r\\n
+.. _urilen:
-.. _http.referer:
+urilen
+------
-http.referer
-------------
+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*.
-The ``http.referer`` keyword is used to match on the Referer field that
-can be present in HTTP request headers.
+urilen uses an :ref:`unsigned 64-bit integer <rules-integer-keywords>`.
-It is possible to use any of the :doc:`payload-keywords` with the
-``http.referer`` keyword.
+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 / HTTP/1.1
+ GET /index.html HTTP/1.1
+ User-Agent: Mozilla/5.0
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;)
+ 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;)
-.. note:: ``http.referer`` does not include the leading space or trailing
- \\r\\n
+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.
-.. _http.start:
+The following signatures would all alert on the example request above as well
+and show the different ``urilen`` options.
-http.start
-----------
+.. container:: example-rule
-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.
+ 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;)
-It is possible to use any of the :doc:`payload-keywords` with the
-``http.start`` keyword.
+ 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;)
-Example HTTP Request::
+ 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;)
- GET / HTTP/1.1
- Host: suricata.io
- Connection: Keep-Alive
+.. _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 $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;)
+ 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.start`` contains the normalized headers and is terminated by
- an extra \\r\\n to indicate the end of the headers.
+.. note:: ``http.location`` does not include the leading space or trailing \\r\\n
-.. _http.header_names:
+.. _http.response_body:
-http.header_names
------------------
+http.response_body
+------------------
-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 headers
-presence, absence and/or header order. Use ``flow:to_server`` or
-``flow:to_client`` to force inspection of the request or response respectively.
+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.header_names`` keyword.
-
-Example HTTP Request::
-
- GET / HTTP/1.1
- Host: suricata.io
- Connection: Keep-Alive
+``http.response_body`` keyword.
Example HTTP Response::
Content-Type: text/html
Server: nginx/0.8.54
-Examples to match exactly on header order:
+ Server response body
.. 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 Response Body \
+ Example"; flow:established,to_client; :example-rule-options:`http.response_body; \
+ content:"Server response body";` classtype:bad-unknown; sid:120; 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;)
+.. note:: ``http.response_body`` will match on gzip decoded data just like
+ :ref:`file.data` does.
-Examples to match on header existence:
+.. 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.
-.. container:: example-rule
+.. 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``.
- 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;)
+.. _http.response_header:
- 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;)
+http.response_header
+--------------------
-Examples to match on header absence:
+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 $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 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;)
- 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;)
+.. _http.response_line:
-Example to check for the ``User-Agent`` header and that the ``Host`` header is
-after ``User-Agent`` but not necessarily directly after.
+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 $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;)
+ 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.header_names`` starts with a \\r\\n and ends with an extra \\r\\n.
+.. note:: ``http.response_line`` does not include the trailing \\r\\n
-.. _http.request_body:
+.. _http.server:
-http.request_body
------------------
+http.server
+-----------
-The ``http.request_body`` keyword is used to match on the HTTP request body
-that can be present in an HTTP request.
+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.request_body`` keyword.
-
-Example HTTP Request::
+``http.server`` keyword.
- POST /suricata.php HTTP/1.1
- Content-Type: application/x-www-form-urlencoded
- Host: suricata.io
- Content-Length: 23
- Connection: Keep-Alive
+Example HTTP Response::
- Suricata request body
+ 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 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.
+ 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.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``.
+.. note:: ``http.server`` does not include the leading space or trailing \\r\\n
.. _http.stat_code:
.. note:: ``http.stat_msg`` will always be empty when used with HTTP/2
-.. _http.response_line:
+.. _file.data:
-http.response_line
-------------------
+file.data
+---------
-The ``http.response_line`` keyword is used to match on the entire HTTP
-response line.
+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
-``http.response_line`` keyword.
+``file.data`` keyword.
Example HTTP Response::
Content-Type: text/html
Server: nginx/0.8.54
-.. container:: example-rule
+ Server response body
- 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;)
+.. container:: example-rule
-.. note:: ``http.response_line`` does not include the trailing \\r\\n
+ 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;)
-.. _http.response_body:
+The body of an HTTP response can be very large, therefore the response body is
+inspected in definable chunks.
-http.response_body
-------------------
+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.
-The ``http.response_body`` keyword is used to match on the HTTP response body.
+.. 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:
-It is possible to use any of the :doc:`payload-keywords` with the
-``http.response_body`` keyword.
+ ::
-Example HTTP Response::
+ # 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
- HTTP/1.1 200 OK
- Content-Type: text/html
- Server: nginx/0.8.54
+.. 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``.
- Server response body
+.. note:: If an HTTP body is using gzip or deflate, ``file.data`` will match on
+ the decompressed data.
-.. container:: example-rule
+.. 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.
- 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:: Additional information can be found at :doc:`file-keywords`
-.. note:: ``http.response_body`` will match on gzip decoded data just like
- :ref:`file.data` does.
+.. note:: ``file.data`` supports multiple buffer matching, see
+ :doc:`multi-buffer-matching`.
-.. 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.
+.. _http.content_len:
-.. 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.content_len
+----------------
-.. _http.server:
+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.
-http.server
------------
+It is possible to use any of the :doc:`payload-keywords` with the
+``http.content_len`` keyword.
-The ``http.server`` keyword is used to match on the HTTP response server
-header contents.
+Example HTTP Request::
-It is possible to use any of the :doc:`payload-keywords` with the
-``http.server`` keyword.
+ 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 $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;)
+ 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;)
-.. note:: ``http.server`` does not include the leading space or trailing \\r\\n
+ 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;)
-.. _http.location:
+To do numeric evaluation of the content length, :ref:`byte_test` can be used.
-http.location
--------------
+If we want to match on an HTTP request content length equal to and greater
+than 100 we could use the following signature.
-The ``http.location`` keyword is used to match on the HTTP response location
-header contents.
+.. container:: example-rule
-It is possible to use any of the :doc:`payload-keywords` with the
-``http.location`` keyword.
+ 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;)
-Example HTTP Response::
-
- HTTP/1.1 200 OK
- Content-Type: text/html
- Server: nginx/0.8.54
- Location: suricata.io
+.. note:: ``http.content_len`` does not include the leading space or trailing
+ \\r\\n
-.. container:: example-rule
+.. _http.content_type:
- 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;)
+http.content_type
+-----------------
-.. note:: ``http.location`` does not include the leading space or trailing \\r\\n
+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.
-.. _http.host:
+It is possible to use any of the :doc:`payload-keywords` with the
+``http.content_type`` keyword.
-http.host
----------
+Example HTTP Request::
-Matching on the HTTP host name has two options in Suricata, the ``http.host``
-and the ``http.host.raw`` sticky buffers.
+ POST /suricata.php HTTP/1.1
+ Content-Type: multipart/form-data; boundary=---------------123
+ Host: suricata.io
+ Content-Length: 100
+ Connection: Keep-Alive
-It is possible to use any of the :doc:`payload-keywords` with both ``http.host``
-keywords.
+Example HTTP Response::
-.. note:: The ``http.host`` keyword normalizes the host header contents. If a
- host name has uppercase characters, those would be changed to lowercase.
+ HTTP/1.1 200 OK
+ Content-Type: text/html
+ Server: nginx/0.8.54
+ Connection: Close
-Normalization Example::
+.. container:: example-rule
- GET /index.html HTTP/1.1
- User-Agent: Mozilla/5.0
- Host: SuRiCaTa.Io
+ 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;)
-In the above example the host buffer would contain `suricata.io`.
+ 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;)
-.. container:: example-rule
+.. note:: ``http.content_type`` does not include the leading space or trailing
+ \\r\\n
- 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;)
+.. _http.cookie:
-.. note:: The ``nocase`` keyword is no longer allowed since the host names
- are normalized to contain only lowercase letters.
+http.cookie
+-----------
-.. 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`.
+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.
-.. note:: ``http.host`` does not include the leading space or trailing \\r\\n
+It is possible to use any of the :doc:`payload-keywords` with both ``http.header``
+keywords.
-.. 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:: 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:: If a request contains multiple "Host" headers, the values will be
- concatenated in the ``http.host`` and ``http.host.raw``
- buffers, in the order seen from top to bottom, with a comma and space
- (", ") between each of them.
+.. note:: ``http.cookie`` does not include the leading space or trailing \\r\\n
-Example Duplicate Host Header Request::
+Example HTTP Request::
GET /index.html HTTP/1.1
- User-Agent: Chrome/2.0
+ User-Agent: Mozilla/5.0
Cookie: PHPSESSION=123
Host: suricata.io
- Host: oisf.net
.. container:: example-rule
- alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Two Host Example"; \
- flow:established,to_server; :example-rule-options:`http.host; \
- content:"suricata.io, oisf.net";` classtype:bad-unknown; sid:125; rev:1;)
-
-.. _http.host.raw:
+ 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;)
-http.host.raw
--------------
+.. _http.header:
-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`)
+http.header
+-----------
-Example HTTP Request::
+Matching on HTTP headers has two options in Suricata, the ``http.header``
+and the ``http.header.raw``.
- GET /index.html HTTP/1.1
- User-Agent: Mozilla/5.0
- Host: SuRiCaTa.Io:8445
+It is possible to use any of the :doc:`payload-keywords` with both
+``http.header`` keywords.
-.. container:: example-rule
+The ``http.header`` keyword normalizes the header contents. For example if
+header contents contain trailing white-space or tab characters, those would be
+removed.
- 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;)
+To match on non-normalized header data, use the :ref:`http.header.raw` keyword.
-.. note:: ``http.host.raw`` does not include the leading space or trailing \\r\\n
+Normalization Example::
-.. 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.
+ GET /index.html HTTP/1.1
+ User-Agent: Mozilla/5.0 \r\n
+ Host: suricata.io
-.. note:: If a request contains multiple "Host" headers, the values will be
- concatenated in the ``http.host`` and ``http.host.raw`` buffers, in the
- order seen from top to bottom, with a comma and space (", ") between each
- of them.
+Would be normalized to :example-rule-emphasis:`Mozilla/5.0\\r\\n`
-Example Duplicate Host Header Request::
+Example HTTP Request::
GET /index.html HTTP/1.1
- User-Agent: Chrome/2.0
- Cookie: PHPSESSION=123
+ User-Agent: Mozilla/5.0
Host: suricata.io
- Host: oisf.net
.. container:: example-rule
- alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Two Host Example"; \
- flow:established,to_server; :example-rule-options:`http.host.raw; \
- content:"suricata.io, oisf.net";` classtype:bad-unknown; sid:125; rev:1;)
+ 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;)
-.. _http.request_header:
+ 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;)
-http.request_header
--------------------
+ 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;)
-The ``http.request_header`` keyword is used to match on the name and value
-of a HTTP/1 or HTTP/2 request.
+.. note:: There are headers that will not be included in the ``http.header``
+ buffer, specifically the :ref:`http.cookie` buffer.
-It is possible to use any of the :doc:`payload-keywords` with the
-``http.request_header`` keyword.
+.. note:: 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>`_
-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.
+.. _http.header.raw:
-To detect if an HTTP/2 header name contains a ":" (colon), the keyword
-:ref:`http2.header_name` can be used.
+http.header.raw
+---------------
-Example HTTP/1 Request::
+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 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
+ 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;)
-.. _http.response_header:
+.. _http.header_names:
-http.response_header
---------------------
+http.header_names
+-----------------
-The ``http.response_header`` keyword is used to match on the name and value
-of an HTTP/1 or HTTP/2 request.
+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.response_header`` keyword.
+``http.header_names`` 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.
+Example HTTP Request::
-To detect if an HTTP/2 header name contains a ":" (colon), the keyword
-:ref:`http2.header_name` can be used.
+ 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
- Location: suricata.io
+
+Examples to match exactly on header order:
.. 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;)
+ 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;)
-.. _file.data:
+ 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;)
-file.data
----------
+Examples to match on header existence:
-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.
+.. container:: example-rule
-It is possible to use any of the :doc:`payload-keywords` with the
-``file.data`` keyword.
+ 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;)
-Example HTTP Response::
+ 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;)
- HTTP/1.1 200 OK
- Content-Type: text/html
- Server: nginx/0.8.54
+Examples to match on header absence:
- Server response body
+.. 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 $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;)
+ 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;)
-The body of an HTTP response can be very large, therefore the response body is
-inspected in definable chunks.
+.. note:: ``http.header_names`` starts with a \\r\\n and ends with an extra \\r\\n.
-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.
+.. _http.protocol:
-.. 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:
+http.protocol
+-------------
- ::
+The ``http.protocol`` keyword is used to match on the protocol field that is
+contained in HTTP requests and responses.
- # 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
+It is possible to use any of the :doc:`payload-keywords` with the
+``http.protocol`` keyword.
-.. 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:: ``http.protocol`` does not include the leading space or trailing \\r\\n
-.. note:: If an HTTP body is using gzip or deflate, ``file.data`` will match on
- the decompressed data.
+Example HTTP Request::
-.. 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.
+ GET /index.html HTTP/1.1
+ User-Agent: Mozilla/5.0
+ Host: suricata.io
-.. note:: Additional information can be found at :doc:`file-keywords`
+.. container:: example-rule
-.. note:: ``file.data`` supports multiple buffer matching, see
- :doc:`multi-buffer-matching`.
+ 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;)
-.. _file.name:
+.. _http.start:
-file.name
----------
+http.start
+----------
-The ``file.name`` keyword can be used with HTTP requests.
+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
-``file.name`` keyword.
+``http.start`` keyword.
Example HTTP Request::
- GET /picture.jpg HTTP/1.1
- User-Agent: Mozilla/5.0
+ 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 $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;)
+ 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;)
-.. note:: Additional information can be found at :doc:`file-keywords`
\ No newline at end of file
+ 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.
\ No newline at end of file