diff options
| author | liuwentan <[email protected]> | 2024-01-05 18:02:06 +0800 |
|---|---|---|
| committer | liuwentan <[email protected]> | 2024-01-05 18:02:06 +0800 |
| commit | d60a54627d116fbba171c371b86a2b8e3a1acc5d (patch) | |
| tree | 8e261e67c5a0cb90d41ac1ec166b3670fed1ad73 | |
| parent | b446f5cc666495e1ed6cb7064bfb0e6df6dfc3b8 (diff) | |
[HTTP_DECODER]bugfix for http malformed packet
| -rw-r--r-- | src/http_decoder/http_decoder.c | 4 | ||||
| -rw-r--r-- | src/http_decoder/http_decoder_half.c | 45 | ||||
| -rw-r--r-- | src/http_decoder/http_decoder_string.c | 2 | ||||
| -rw-r--r-- | test/http_decoder/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | test/http_decoder/http_pcap/http_get_malformed.pcap | bin | 0 -> 16158 bytes | |||
| -rw-r--r-- | test/http_decoder/http_pcap/http_header_value_empty.pcap | bin | 0 -> 2129 bytes | |||
| -rw-r--r-- | test/http_decoder/http_pcap/http_post_no_host.pcap | bin | 0 -> 123982 bytes | |||
| -rw-r--r-- | test/http_decoder/test_result_json/http_get_malformed.json | 38 | ||||
| -rw-r--r-- | test/http_decoder/test_result_json/http_header_value_empty.json | 30 | ||||
| -rw-r--r-- | test/http_decoder/test_result_json/http_post_no_host.json | 1 |
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 Binary files differnew file mode 100644 index 0000000..cfe16d9 --- /dev/null +++ b/test/http_decoder/http_pcap/http_get_malformed.pcap diff --git a/test/http_decoder/http_pcap/http_header_value_empty.pcap b/test/http_decoder/http_pcap/http_header_value_empty.pcap Binary files differnew file mode 100644 index 0000000..138f905 --- /dev/null +++ b/test/http_decoder/http_pcap/http_header_value_empty.pcap diff --git a/test/http_decoder/http_pcap/http_post_no_host.pcap b/test/http_decoder/http_pcap/http_post_no_host.pcap Binary files differnew file mode 100644 index 0000000..0dca059 --- /dev/null +++ b/test/http_decoder/http_pcap/http_post_no_host.pcap 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 |
