HTTP/2 preface received instead of an HTTP/1 method
+119:287
+
+HTTP request method is not on allowed methods list or is on disallowed methods list.
+
121:1
Invalid flag set on HTTP/2 frame header
These limits have no effect on how much data is forwarded to file
processing.
+===== allowed_methods and disallowed_methods
+
+When either of these options are set, HTTP inspector will check if the method
+in the HTTP request is allowed and if not raise alert 119:287. You can either
+define a list of allowed methods or a list of disallowed methods. Defining
+both is a configuration error. When a list of disallowed methods is defined,
+any method not present on that list is implicitly allowed. Methods on either
+of these lists are considered known methods and will not raise alert 119:31.
+For example if configured for:
+
+ allowed_methods = "GET,PUT,BLUE"
+
+HTTP inspector will raise 119:287 for POST and RED, no alert 119:31 will
+be raised for BLUE, and 119:31 will be raised for RED.
+If configured for
+
+ disallowed_methods = "POST,RED"
+
+HTTP inspector will raise 119:287 for POST and RED, 119:31 for BLUE, and
+no alert 119:31 will be raised for RED.
+
===== script_detection
Script detection is a feature that enables Snort to more quickly detect and
INF_INVALID_SUBVERSION = 133,
INF_VERSION_0 = 134,
INF_GZIP_FEXTRA = 135,
+ INF_METHOD_NOT_ON_ALLOWED_LIST = 136,
+ INF_METHOD_ON_DISALLOWED_LIST = 137,
INF__MAX_VALUE
};
EVENT_PARTIAL_START = 284,
EVENT_REQ_TOO_LONG = 285,
EVENT_UNEXPECTED_H2_PREFACE = 286,
+ EVENT_DISALLOWED_METHOD = 287,
EVENT__MAX_VALUE
};
"make HTTP/2 request message bodies available for application detection "
"(detection requires AppId)" },
+ { "allowed_methods", Parameter::PT_STRING, nullptr, nullptr,
+ "list of allowed methods" },
+
+ { "disallowed_methods", Parameter::PT_STRING, nullptr, nullptr,
+ "list of disallowed methods" },
+
#ifdef REG_TEST
{ "test_input", Parameter::PT_BOOL, nullptr, "false",
"read HTTP messages from text file" },
return true;
}
+static void store_tokens(Value& val, std::set<std::string>& methods)
+{
+ val.set_first_token();
+ std::string tok;
+ while (val.get_next_csv_token(tok))
+ methods.insert(tok);
+}
+
bool HttpModule::set(const char*, Value& val, SnortConfig*)
{
if (val.is("request_depth"))
{
params->publish_request_body = val.get_bool();
}
+ else if (val.is("allowed_methods"))
+ store_tokens(val, params->allowed_methods);
+ else if (val.is("disallowed_methods"))
+ store_tokens(val, params->disallowed_methods);
#ifdef REG_TEST
else if (val.is("test_input"))
if (strcmp(fqn, "http_inspect"))
return true;
+ if (!params->allowed_methods.empty() && !params->disallowed_methods.empty())
+ ParseError("allowed methods can't be used in conjunction with disallowed methods");
+
if (!params->uri_param.utf8 && params->uri_param.utf8_bare_byte)
{
ParseWarning(WARN_CONF, "Meaningless to do bare byte when not doing UTF-8");
#define HTTP_MODULE_H
#include <bitset>
+#include <set>
#include <string>
#include <unordered_set>
// any custom headers mapped with the their respective Header IDs.
StrCode header_list[HttpEnums::HEAD__MAX_VALUE + HttpEnums::MAX_CUSTOM_HEADERS + 1] = {};
+ std::set<std::string> allowed_methods;
+ std::set<std::string> disallowed_methods;
+
#ifdef REG_TEST
int64_t print_amount = 1200;
}
}
- if (method_id == METH__OTHER)
+ bool known_method = false;
+ assert(method.length() > 0);
+ if (!params->allowed_methods.empty() or !params->disallowed_methods.empty())
+ {
+ string method_str((const char*)method.start(), method.length());
+
+ if (!params->allowed_methods.empty())
+ {
+ const set<string>::iterator it = params->allowed_methods.find(method_str);
+ if (it == params->allowed_methods.end())
+ {
+ add_infraction(INF_METHOD_NOT_ON_ALLOWED_LIST);
+ create_event(EVENT_DISALLOWED_METHOD);
+ }
+ else
+ known_method = true;
+ }
+ else
+ {
+ const set<string>::iterator it = params->disallowed_methods.find(method_str);
+ if (it != params->disallowed_methods.end())
+ {
+ add_infraction(INF_METHOD_ON_DISALLOWED_LIST);
+ create_event(EVENT_DISALLOWED_METHOD);
+ known_method = true;
+ }
+ }
+ }
+
+ if (method_id == METH__OTHER && !known_method)
create_event(EVENT_UNKNOWN_METHOD);
if (uri && uri->get_scheme().length() > LONG_SCHEME_LENGTH)
{ EVENT_PARTIAL_START, "partial start line" },
{ EVENT_REQ_TOO_LONG, "HTTP message request line longer than 63780 bytes" },
{ EVENT_UNEXPECTED_H2_PREFACE, "HTTP/2 preface received instead of an HTTP/1 method" },
+ { EVENT_DISALLOWED_METHOD, "HTTP request method is not on allowed methods list or is on "
+ "disallowed methods list" },
{ 0, nullptr }
};
void Value::get_bits(std::bitset<256ul>&) const {}
void Value::set_first_token() {}
+bool Value::get_next_csv_token(std::string&) { return false; }
bool Value::get_next_token(std::string& ) { return false; }
int DetectionEngine::queue_event(unsigned int, unsigned int) { return 0; }
void ParseError(const char*, ...) {}
void Value::get_bits(std::bitset<256ul>&) const {}
void Value::set_first_token() {}
+bool Value::get_next_csv_token(std::string&) { return false; }
bool Value::get_next_token(std::string& ) { return false; }
int DetectionEngine::queue_event(unsigned int, unsigned int) { return 0; }
LiteralSearch::Handle* LiteralSearch::setup() { return nullptr; }