mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	Multiple revisions 431297-431298
........ r431297 | mmichelson | 2015-01-28 11:05:26 -0600 (Wed, 28 Jan 2015) | 17 lines Mitigate possible HTTP injection attacks using CURL() function in Asterisk. CVE-2014-8150 disclosed a vulnerability in libcURL where HTTP request injection can be performed given properly-crafted URLs. Since Asterisk makes use of libcURL, and it is possible that users of Asterisk may get cURL URLs from user input or remote sources, we have made a patch to Asterisk to prevent such HTTP injection attacks from originating from Asterisk. ASTERISK-24676 #close Reported by Matt Jordan Review: https://reviewboard.asterisk.org/r/4364 AST-2015-002 ........ r431298 | mmichelson | 2015-01-28 11:12:49 -0600 (Wed, 28 Jan 2015) | 3 lines Fix compilation error from previous patch. ........ Merged revisions 431297-431298 from http://svn.asterisk.org/svn/asterisk/branches/11 ........ Merged revisions 431299 from http://svn.asterisk.org/svn/asterisk/branches/12 ........ Merged revisions 431301 from http://svn.asterisk.org/svn/asterisk/branches/13 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@431302 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -50,6 +50,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | ||||
| #include "asterisk/app.h" | ||||
| #include "asterisk/utils.h" | ||||
| #include "asterisk/threadstorage.h" | ||||
| #include "asterisk/test.h" | ||||
|  | ||||
| /*** DOCUMENTATION | ||||
| 	<function name="CURL" language="en_US"> | ||||
| @@ -568,6 +569,31 @@ static void curl_instance_cleanup(void *data) | ||||
| AST_THREADSTORAGE_CUSTOM(curl_instance, curl_instance_init, curl_instance_cleanup); | ||||
| AST_THREADSTORAGE(thread_escapebuf); | ||||
|  | ||||
| /*! | ||||
|  * \brief Check for potential HTTP injection risk. | ||||
|  * | ||||
|  * CVE-2014-8150 brought up the fact that HTTP proxies are subject to injection | ||||
|  * attacks. An HTTP URL sent to a proxy contains a carriage-return linefeed combination, | ||||
|  * followed by a complete HTTP request. Proxies will handle this as two separate HTTP | ||||
|  * requests rather than as a malformed URL. | ||||
|  * | ||||
|  * libcURL patched this vulnerability in version 7.40.0, but we have no guarantee that | ||||
|  * Asterisk systems will be using an up-to-date cURL library. Therefore, we implement | ||||
|  * the same fix as libcURL for determining if a URL is vulnerable to an injection attack. | ||||
|  * | ||||
|  * \param url The URL to check for vulnerability | ||||
|  * \retval 0 The URL is not vulnerable | ||||
|  * \retval 1 The URL is vulnerable. | ||||
|  */ | ||||
| static int url_is_vulnerable(const char *url) | ||||
| { | ||||
| 	if (strpbrk(url, "\r\n")) { | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int acf_curl_helper(struct ast_channel *chan, const char *cmd, char *info, char *buf, struct ast_str **input_str, ssize_t len) | ||||
| { | ||||
| 	struct ast_str *escapebuf = ast_str_thread_get(&thread_escapebuf, 16); | ||||
| @@ -605,6 +631,11 @@ static int acf_curl_helper(struct ast_channel *chan, const char *cmd, char *info | ||||
|  | ||||
| 	AST_STANDARD_APP_ARGS(args, info); | ||||
|  | ||||
| 	if (url_is_vulnerable(args.url)) { | ||||
| 		ast_log(LOG_ERROR, "URL '%s' is vulnerable to HTTP injection attacks. Aborting CURL() call.\n", args.url); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (chan) { | ||||
| 		ast_autoservice_start(chan); | ||||
| 	} | ||||
| @@ -763,6 +794,54 @@ static struct ast_custom_function acf_curlopt = { | ||||
| 	.write = acf_curlopt_write, | ||||
| }; | ||||
|  | ||||
| AST_TEST_DEFINE(vulnerable_url) | ||||
| { | ||||
| 	const char *bad_urls [] = { | ||||
| 		"http://example.com\r\nDELETE http://example.com/everything", | ||||
| 		"http://example.com\rDELETE http://example.com/everything", | ||||
| 		"http://example.com\nDELETE http://example.com/everything", | ||||
| 		"\r\nhttp://example.com", | ||||
| 		"\rhttp://example.com", | ||||
| 		"\nhttp://example.com", | ||||
| 		"http://example.com\r\n", | ||||
| 		"http://example.com\r", | ||||
| 		"http://example.com\n", | ||||
| 	}; | ||||
| 	const char *good_urls [] = { | ||||
| 		"http://example.com", | ||||
| 		"http://example.com/%5Cr%5Cn", | ||||
| 	}; | ||||
| 	int i; | ||||
| 	enum ast_test_result_state res = AST_TEST_PASS; | ||||
|  | ||||
| 	switch (cmd) { | ||||
| 	case TEST_INIT: | ||||
| 		info->name = "vulnerable_url"; | ||||
| 		info->category = "/funcs/func_curl/"; | ||||
| 		info->summary = "cURL vulnerable URL test"; | ||||
| 		info->description = | ||||
| 			"Ensure that any combination of '\\r' or '\\n' in a URL invalidates the URL"; | ||||
| 	case TEST_EXECUTE: | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	for (i = 0; i < ARRAY_LEN(bad_urls); ++i) { | ||||
| 		if (!url_is_vulnerable(bad_urls[i])) { | ||||
| 			ast_test_status_update(test, "String '%s' detected as valid when it should be invalid\n", bad_urls[i]); | ||||
| 			res = AST_TEST_FAIL; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	for (i = 0; i < ARRAY_LEN(good_urls); ++i) { | ||||
| 		if (url_is_vulnerable(good_urls[i])) { | ||||
| 			ast_test_status_update(test, "String '%s' detected as invalid when it should be valid\n", good_urls[i]); | ||||
| 			res = AST_TEST_FAIL; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
| static int unload_module(void) | ||||
| { | ||||
| 	int res; | ||||
| @@ -770,6 +849,8 @@ static int unload_module(void) | ||||
| 	res = ast_custom_function_unregister(&acf_curl); | ||||
| 	res |= ast_custom_function_unregister(&acf_curlopt); | ||||
|  | ||||
| 	AST_TEST_UNREGISTER(vulnerable_url); | ||||
|  | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
| @@ -787,6 +868,8 @@ static int load_module(void) | ||||
| 	res = ast_custom_function_register(&acf_curl); | ||||
| 	res |= ast_custom_function_register(&acf_curlopt); | ||||
|  | ||||
| 	AST_TEST_REGISTER(vulnerable_url); | ||||
|  | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user