Skip to content

Commit e561fa7

Browse files
committed
parse http requests with invalid header
1 parent 32f0081 commit e561fa7

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

process/http.cpp

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ void copy_str(char *dst, ssize_t size, const char *begin, const char *end)
180180
}
181181

182182
memcpy(dst, begin, len);
183-
183+
184184
if (len >= 1 && dst[len - 1] == '\n') {
185185
len--;
186186
}
@@ -201,7 +201,11 @@ bool HTTPPlugin::is_request(const char *data, int payload_len)
201201
}
202202
memcpy(chars, data, 4);
203203
chars[4] = 0;
204-
return valid_http_method(chars);
204+
205+
// 'valid_http_method' can quicky confirm valid http methods.
206+
// 'invalid_http_method' is slower but can check if it is http request even
207+
// if the method is invalid.
208+
return valid_http_method(chars) || invalid_http_method(data, payload_len);
205209
}
206210

207211
bool HTTPPlugin::is_response(const char *data, int payload_len)
@@ -521,6 +525,42 @@ bool HTTPPlugin::valid_http_method(const char *method) const
521525
!strcmp(method, "PATC"));
522526
}
523527

528+
/**
529+
* @brief Check if the payload is http request even with invalid method.
530+
*
531+
* @param [in] payload Packet payload data.
532+
* @param payload_len Length packet payload.
533+
* @return True if the packet is http request.
534+
*/
535+
bool HTTPPlugin::invalid_http_method(const char *data, int payload_len) const
536+
{
537+
// METHOD URI HTTP/VERSION
538+
// | | |
539+
// | | +---- uri_end
540+
// | +---- method_end
541+
// +---- data
542+
543+
// check if there is space in the first HTTP_MAX_METHOD_LENGTH chars
544+
int len = std::min(payload_len, HTTP_MAX_METHOD_LENGTH);
545+
auto method_end = static_cast<const char *>(memchr(data, ' ', len));
546+
if (method_end == nullptr)
547+
return false;
548+
549+
payload_len -= method_end - data - 1;
550+
if (payload_len <= 0)
551+
return false;
552+
553+
auto uri_end = static_cast<const char *>(memchr(method_end + 1, ' ', payload_len));
554+
if (method_end == nullptr)
555+
return false;
556+
557+
payload_len -= uri_end - method_end;
558+
if (payload_len <= 4)
559+
return false;
560+
561+
return memcmp(uri_end + 1, "HTTP", 4) == 0;
562+
}
563+
524564
/**
525565
* \brief Add new extension http request header into flow record.
526566
* \param [in] data Packet payload data.

process/http.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ namespace ipxp {
6565

6666
#define HTTP_UNIREC_TEMPLATE "HTTP_REQUEST_METHOD,HTTP_REQUEST_HOST,HTTP_REQUEST_URL,HTTP_REQUEST_AGENT,HTTP_REQUEST_REFERER,HTTP_RESPONSE_STATUS_CODE,HTTP_RESPONSE_CONTENT_TYPE"
6767

68+
// maximum supported length for http method (includes the null terminating char)
69+
#define HTTP_MAX_METHOD_LENGTH 16
70+
6871
UR_FIELDS (
6972
string HTTP_REQUEST_METHOD,
7073
string HTTP_REQUEST_HOST,
@@ -87,7 +90,7 @@ struct RecordExtHTTP : public RecordExt {
8790
bool req;
8891
bool resp;
8992

90-
char method[10];
93+
char method[HTTP_MAX_METHOD_LENGTH];
9194
char host[64];
9295
char uri[128];
9396
char user_agent[128];
@@ -228,6 +231,7 @@ class HTTPPlugin : public ProcessPlugin
228231
void add_ext_http_request(const char *data, int payload_len, Flow &flow);
229232
void add_ext_http_response(const char *data, int payload_len, Flow &flow);
230233
bool valid_http_method(const char *method) const;
234+
bool invalid_http_method(const char *payload, int payload_len) const;
231235

232236
RecordExtHTTP *recPrealloc;/**< Preallocated extension. */
233237
bool flow_flush; /**< Tell storage plugin to flush current Flow. */

0 commit comments

Comments
 (0)