diff --git a/scripts/base/protocols/http/main.bro b/scripts/base/protocols/http/main.bro index 21b4fb6113..ec8a5ffad8 100644 --- a/scripts/base/protocols/http/main.bro +++ b/scripts/base/protocols/http/main.bro @@ -94,6 +94,17 @@ export { "XROXY-CONNECTION", "PROXY-CONNECTION", } &redef; + + ## A list of HTTP methods. Other methods will generate a weird. + const http_methods: set[string] = { + "GET", "POST", "HEAD", "OPTIONS", + "PUT", "DELETE", "TRACE", "CONNECT", + # HTTP methods for distributed authoring: + "PROPFIND", "PROPPATCH", "MKCOL", + "COPY", "MOVE", "LOCK", "UNLOCK", + "POLL", "REPORT", "SUBSCRIBE", "BMOVE", + "SEARCH" + } &redef; ## Event that can be handled to access the HTTP record as it is sent on ## to the logging framework. @@ -180,6 +191,9 @@ event http_request(c: connection, method: string, original_URI: string, c$http$method = method; c$http$uri = unescaped_URI; + + if ( !(method in http_methods) ) + event conn_weird("unknown_HTTP_method", c, method); } event http_reply(c: connection, version: string, code: count, reason: string) &priority=5 diff --git a/src/HTTP.cc b/src/HTTP.cc index 9d9f01be64..0748ca55a7 100644 --- a/src/HTTP.cc +++ b/src/HTTP.cc @@ -1118,36 +1118,18 @@ const char* HTTP_Analyzer::PrefixWordMatch(const char* line, int HTTP_Analyzer::HTTP_RequestLine(const char* line, const char* end_of_line) { - const char* rest = 0; - static const char* http_methods[] = { - "GET", "POST", "HEAD", - - "OPTIONS", "PUT", "DELETE", "TRACE", "CONNECT", - - // HTTP methods for distributed authoring. - "PROPFIND", "PROPPATCH", "MKCOL", "DELETE", "PUT", - "COPY", "MOVE", "LOCK", "UNLOCK", - "POLL", "REPORT", "SUBSCRIBE", "BMOVE", - - "SEARCH", - - 0, - }; - - int i; - for ( i = 0; http_methods[i]; ++i ) - if ( (rest = PrefixWordMatch(line, end_of_line, http_methods[i])) != 0 ) - break; - - if ( ! http_methods[i] ) - { - // Weird("HTTP_unknown_method"); - if ( RequestExpected() ) - HTTP_Event("unknown_HTTP_method", new_string_val(line, end_of_line)); - return 0; - } - - request_method = new StringVal(http_methods[i]); + const char* request_method_str; + int request_method_len; + const char* rest; + get_word(strlen(line), line, request_method_len, request_method_str); + + request_method = new StringVal(request_method_len, request_method_str); + if ( (rest = PrefixWordMatch(line, end_of_line, (const char*) request_method->AsString()->Bytes() )) == 0) + { + // Most likely a DPD failure - this is pretty noisy for me, so leaving commented for now + // reporter->InternalError("HTTP RequestLine failed"); + return 0; + } if ( ! ParseRequest(rest, end_of_line) ) reporter->InternalError("HTTP ParseRequest failed");