summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorliuwentan <[email protected]>2024-01-05 18:02:06 +0800
committerliuwentan <[email protected]>2024-01-05 18:02:06 +0800
commitd60a54627d116fbba171c371b86a2b8e3a1acc5d (patch)
tree8e261e67c5a0cb90d41ac1ec166b3670fed1ad73
parentb446f5cc666495e1ed6cb7064bfb0e6df6dfc3b8 (diff)
[HTTP_DECODER]bugfix for http malformed packet
-rw-r--r--src/http_decoder/http_decoder.c4
-rw-r--r--src/http_decoder/http_decoder_half.c45
-rw-r--r--src/http_decoder/http_decoder_string.c2
-rw-r--r--test/http_decoder/CMakeLists.txt11
-rw-r--r--test/http_decoder/http_pcap/http_get_malformed.pcapbin0 -> 16158 bytes
-rw-r--r--test/http_decoder/http_pcap/http_header_value_empty.pcapbin0 -> 2129 bytes
-rw-r--r--test/http_decoder/http_pcap/http_post_no_host.pcapbin0 -> 123982 bytes
-rw-r--r--test/http_decoder/test_result_json/http_get_malformed.json38
-rw-r--r--test/http_decoder/test_result_json/http_header_value_empty.json30
-rw-r--r--test/http_decoder/test_result_json/http_post_no_host.json1
10 files changed, 123 insertions, 8 deletions
diff --git a/src/http_decoder/http_decoder.c b/src/http_decoder/http_decoder.c
index 6a531f4..3d39eba 100644
--- a/src/http_decoder/http_decoder.c
+++ b/src/http_decoder/http_decoder.c
@@ -330,13 +330,12 @@ http_decoder_result_queue_free(struct http_decoder_result_queue *queue)
static int
http_protocol_identify(const char *data, size_t data_len)
{
- enum llhttp_type type = HTTP_BOTH;
llhttp_t parser;
llhttp_settings_t settings;
enum llhttp_errno error;
llhttp_settings_init(&settings);
- llhttp_init(&parser, type, &settings);
+ llhttp_init(&parser, HTTP_BOTH, &settings);
error = llhttp_execute(&parser, data, data_len);
if (error != HPE_OK) {
@@ -371,6 +370,7 @@ int http_decoder_entry(struct session *sess, int events,
}
const char *payload = session_get0_current_payload(sess, &payload_len);
+
if (events & SESS_EV_OPENING) {
if (queue != NULL) {
fprintf(stderr,
diff --git a/src/http_decoder/http_decoder_half.c b/src/http_decoder/http_decoder_half.c
index 294fcd2..9e24a8b 100644
--- a/src/http_decoder/http_decoder_half.c
+++ b/src/http_decoder/http_decoder_half.c
@@ -45,6 +45,7 @@ struct http_decoder_half {
void *http_ev_ctx;
};
+// #define HTTP_DECODER_DEBUG
#ifdef HTTP_DECODER_DEBUG
static void printf_debug_info(const char *desc, const char *at, size_t length)
{
@@ -204,6 +205,10 @@ on_method(llhttp_t *http, const char *at, size_t length)
{
printf_debug_info("on_method", at, length);
+ if (0 == length) {
+ return 0;
+ }
+
struct http_decoder_half *half =
container_of(http, struct http_decoder_half, parser);
assert(half);
@@ -250,6 +255,10 @@ on_uri(llhttp_t *http, const char *at, size_t length)
{
printf_debug_info("on_uri", at, length);
+ if (0 == length) {
+ return 0;
+ }
+
struct http_decoder_half *half =
container_of(http, struct http_decoder_half, parser);
assert(half);
@@ -290,6 +299,10 @@ on_version(llhttp_t *http, const char *at, size_t length)
{
printf_debug_info("on_version", at, length);
+ if (0 == length) {
+ return 0;
+ }
+
struct http_decoder_half *half =
container_of(http, struct http_decoder_half, parser);
assert(half);
@@ -313,7 +326,7 @@ on_version(llhttp_t *http, const char *at, size_t length)
static int
on_version_complete(llhttp_t *http)
{
- printf_debug_info("on_version_complete", NULL, 0);
+ printf_debug_info("on_version_complete", NULL, 0);
struct http_decoder_half *half =
container_of(http, struct http_decoder_half, parser);
@@ -346,6 +359,10 @@ on_status(llhttp_t *http, const char *at, size_t length)
{
printf_debug_info("on_status", at, length);
+ if (0 == length) {
+ return 0;
+ }
+
struct http_decoder_half *half =
container_of(http, struct http_decoder_half, parser);
assert(half);
@@ -390,6 +407,10 @@ on_status_complete(llhttp_t *http)
static int
on_header_field(llhttp_t *http, const char *at, size_t length)
{
+ if (0 == length) {
+ return 0;
+ }
+
printf_debug_info("on_header_field", at, length);
struct http_decoder_half *half =
@@ -430,6 +451,10 @@ on_header_field_complete(llhttp_t *http)
static int
on_header_value(llhttp_t *http, const char *at, size_t length)
{
+ if (0 == length) {
+ return 0;
+ }
+
printf_debug_info("on_header_value", at, length);
struct http_decoder_half *half =
@@ -543,6 +568,10 @@ on_headers_complete(llhttp_t *http)
static int
on_body(llhttp_t *http, const char *at, size_t length)
{
+ if (0 == length) {
+ return 0;
+ }
+
printf_debug_info("on_body", at, length);
struct http_decoder_half *half =
@@ -613,9 +642,8 @@ http_decoder_half_init(struct http_decoder_half *half,
return;
}
- enum llhttp_type type = HTTP_BOTH; // HTTP_BOTH | HTTP_REQUEST | HTTP_RESPONSE
llhttp_settings_init(&half->settings);
- llhttp_init(&half->parser, type, &half->settings);
+ llhttp_init(&half->parser, HTTP_BOTH, &half->settings);
half->settings.on_message_begin = on_message_begin;
half->settings.on_message_complete = on_message_complete;
@@ -689,17 +717,24 @@ http_decoder_half_parse(struct http_decoder_half *half, void *http_ev_ctx,
switch (half->error) {
case HPE_OK:
break;
+ case HPE_PAUSED:
+ llhttp_resume(&half->parser);
+ break;
case HPE_PAUSED_UPGRADE:
llhttp_resume_after_upgrade(&half->parser);
+ ret = 0;
break;
default:
+ llhttp_init(&half->parser, HTTP_BOTH, &half->settings);
ret = -1;
break;
}
if (ret < 0) {
- fprintf(stderr, "llhttp_execute parse error: %s %s\n",
- llhttp_errno_name(half->error), half->parser.reason);
+ fprintf(stderr,
+ "llhttp_execute parse error: %s in position:%s err_reason:%s\n",
+ llhttp_errno_name(half->error), llhttp_get_error_pos(&half->parser),
+ half->parser.reason);
return -1;
}
diff --git a/src/http_decoder/http_decoder_string.c b/src/http_decoder/http_decoder_string.c
index b4fba34..d6c53af 100644
--- a/src/http_decoder/http_decoder_string.c
+++ b/src/http_decoder/http_decoder_string.c
@@ -128,7 +128,7 @@ http_decoder_string_commit(struct http_decoder_string *rstr)
// not overwrite rstr->cache.str
break;
default:
- abort();
+ //abort();
break;
}
diff --git a/test/http_decoder/CMakeLists.txt b/test/http_decoder/CMakeLists.txt
index 453b4e6..0ac3a23 100644
--- a/test/http_decoder/CMakeLists.txt
+++ b/test/http_decoder/CMakeLists.txt
@@ -88,6 +88,15 @@ add_test(NAME HTTP_HEADERS_EXCEED_MAXIMUM_TEST COMMAND ${TEST_MAIN} ${CMAKE_CURR
add_test(NAME HTTP_CONNECT_FLOOD_TEST COMMAND ${TEST_MAIN} ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_connect_flood.json
-f "find ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/ -name http_connect_flood.pcap|sort -V" WORKING_DIRECTORY ${TEST_RUN_DIR})
+add_test(NAME HTTP_GET_MALFORMED_TEST COMMAND ${TEST_MAIN} ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_get_malformed.json
+ -f "find ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/ -name http_get_malformed.pcap|sort -V" WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+# add_test(NAME HTTP_POST_NO_HOST_TEST COMMAND ${TEST_MAIN} ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_post_no_host.json
+# -f "find ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/ -name http_post_no_host.pcap|sort -V" WORKING_DIRECTORY ${TEST_RUN_DIR})
+
+add_test(NAME HTTP_HEADER_VALUE_EMPTY_TEST COMMAND ${TEST_MAIN} ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/http_header_value_empty.json
+ -f "find ${CMAKE_CURRENT_SOURCE_DIR}/http_pcap/ -name http_header_value_empty.pcap|sort -V" WORKING_DIRECTORY ${TEST_RUN_DIR})
+
set_tests_properties(HTTP_GET_SINGLE_TRANS_TEST
HTTP_GET_MULTI_TRANS_TEST
HTTP_GET_REQ_PIPELINE_TEST
@@ -106,4 +115,6 @@ set_tests_properties(HTTP_GET_SINGLE_TRANS_TEST
HTTP_POST_MULTIPART_FORM_DATA_TEST
HTTP_HEADERS_EXCEED_MAXIMUM_TEST
HTTP_CONNECT_FLOOD_TEST
+ HTTP_GET_MALFORMED_TEST
+ HTTP_HEADER_VALUE_EMPTY_TEST
PROPERTIES FIXTURES_REQUIRED TestFixture) \ No newline at end of file
diff --git a/test/http_decoder/http_pcap/http_get_malformed.pcap b/test/http_decoder/http_pcap/http_get_malformed.pcap
new file mode 100644
index 0000000..cfe16d9
--- /dev/null
+++ b/test/http_decoder/http_pcap/http_get_malformed.pcap
Binary files differ
diff --git a/test/http_decoder/http_pcap/http_header_value_empty.pcap b/test/http_decoder/http_pcap/http_header_value_empty.pcap
new file mode 100644
index 0000000..138f905
--- /dev/null
+++ b/test/http_decoder/http_pcap/http_header_value_empty.pcap
Binary files differ
diff --git a/test/http_decoder/http_pcap/http_post_no_host.pcap b/test/http_decoder/http_pcap/http_post_no_host.pcap
new file mode 100644
index 0000000..0dca059
--- /dev/null
+++ b/test/http_decoder/http_pcap/http_post_no_host.pcap
Binary files differ
diff --git a/test/http_decoder/test_result_json/http_get_malformed.json b/test/http_decoder/test_result_json/http_get_malformed.json
new file mode 100644
index 0000000..2cae230
--- /dev/null
+++ b/test/http_decoder/test_result_json/http_get_malformed.json
@@ -0,0 +1,38 @@
+[
+ {
+ "Tuple4": "192.168.140.10.49160>5.8.88.25.80",
+ "Host": "5.8.88.25",
+ "Connection": "keep-alive",
+ "Upgrade-Insecure-Requests": "1",
+ "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
+ "Accept-Language": "en-US;q=0.6,en;q=0.4",
+ "Accept-Encoding": "gzip, deflate",
+ "name": "HTTP_DECODER_RESULT_1"
+ },
+ {
+ "Tuple4": "192.168.4.2.37788>104.197.3.80.80",
+ "method": "GET",
+ "uri": "/",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "Host": "connectivity-check.ubuntu.com",
+ "Accept": "*/*",
+ "Connection": "close",
+ "name": "HTTP_DECODER_RESULT_2"
+ },
+ {
+ "Tuple4": "192.168.4.2.37788>104.197.3.80.80",
+ "res_version": "1.1",
+ "res_status": "No Content",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 204,
+ "Date": "Wed, 12 Sep 2018 19:49:21 GMT",
+ "Server": "Apache/2.4.18 (Ubuntu)",
+ "X-NetworkManager-Status": "online",
+ "Connection": "close",
+ "name": "HTTP_DECODER_RESULT_3"
+ }
+] \ No newline at end of file
diff --git a/test/http_decoder/test_result_json/http_header_value_empty.json b/test/http_decoder/test_result_json/http_header_value_empty.json
new file mode 100644
index 0000000..3310002
--- /dev/null
+++ b/test/http_decoder/test_result_json/http_header_value_empty.json
@@ -0,0 +1,30 @@
+[
+ {
+ "Tuple4": "192.168.131.33.47164>192.168.204.67.4445",
+ "method": "POST",
+ "uri": "http://:4445/RPC2",
+ "req_version": "1.1",
+ "major_version": 1,
+ "minor_version": 1,
+ "User-Agent": "ulxmlrpcpp/1.7.5",
+ "Connection": "Close",
+ "Content-Type": "text/xml",
+ "Date": "Sat Sep 7 10:04:57 2019",
+ "Content-Length": "468",
+ "name": "HTTP_DECODER_RESULT_1"
+ },
+ {
+ "Tuple4": "192.168.131.33.47164>192.168.204.67.4445",
+ "res_version": "1.1",
+ "res_status": "OK",
+ "major_version": 1,
+ "minor_version": 1,
+ "status_code": 200,
+ "Connection": "Close",
+ "Content-Type": "text/xml",
+ "Transfer-Encoding": "chunked",
+ "X-Powered-By": "ulxmlrpcpp/1.7.4",
+ "Date": "Sat Sep 7 01:09:08 2019",
+ "name": "HTTP_DECODER_RESULT_2"
+ }
+] \ No newline at end of file
diff --git a/test/http_decoder/test_result_json/http_post_no_host.json b/test/http_decoder/test_result_json/http_post_no_host.json
new file mode 100644
index 0000000..0637a08
--- /dev/null
+++ b/test/http_decoder/test_result_json/http_post_no_host.json
@@ -0,0 +1 @@
+[] \ No newline at end of file