Commit 06486a2f60 for asterisk.org
commit 06486a2f606d69a24aca96c102d7e8260e48e1f2
Author: George Joseph <gjoseph@sangoma.com>
Date: Thu Jan 15 11:46:21 2026 -0700
http.c: Change httpstatus to default disabled and sanitize output.
To address potential security issues, the httpstatus page is now disabled
by default and the echoed query string and cookie output is html-escaped.
Resolves: #GHSA-v6hp-wh3r-cwxh
UpgradeNote: To prevent possible security issues, the `/httpstatus` page
served by the internal web server is now disabled by default. To explicitly
enable it, set `enable_status=yes` in http.conf.
diff --git a/configs/samples/http.conf.sample b/configs/samples/http.conf.sample
index 1920a1c920..bd9794c5a9 100644
--- a/configs/samples/http.conf.sample
+++ b/configs/samples/http.conf.sample
@@ -69,9 +69,9 @@ bindaddr=127.0.0.1
;
; Whether Asterisk should serve a status page showing the running
; configuration of this built-in HTTP server.
-; Default is yes.
+; Default is no.
;
-;enable_status=no
+;enable_status=yes
;
; Redirect one URI to another. This is how you would set a
; default page.
diff --git a/main/http.c b/main/http.c
index 38aa5654c8..9d7ae3d6aa 100644
--- a/main/http.c
+++ b/main/http.c
@@ -381,6 +381,34 @@ out403:
return 0;
}
+static void str_append_escaped(struct ast_str **str, const char *in)
+{
+ const char *cur = in;
+
+ while(*cur) {
+ switch (*cur) {
+ case '<':
+ ast_str_append(str, 0, "<");
+ break;
+ case '>':
+ ast_str_append(str, 0, ">");
+ break;
+ case '&':
+ ast_str_append(str, 0, "&");
+ break;
+ case '"':
+ ast_str_append(str, 0, """);
+ break;
+ default:
+ ast_str_append(str, 0, "%c", *cur);
+ break;
+ }
+ cur++;
+ }
+
+ return;
+}
+
static int httpstatus_callback(struct ast_tcptls_session_instance *ser,
const struct ast_http_uri *urih, const char *uri,
enum ast_http_method method, struct ast_variable *get_vars,
@@ -419,13 +447,21 @@ static int httpstatus_callback(struct ast_tcptls_session_instance *ser,
}
ast_str_append(&out, 0, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
for (v = get_vars; v; v = v->next) {
- ast_str_append(&out, 0, "<tr><td><i>Submitted GET Variable '%s'</i></td><td>%s</td></tr>\r\n", v->name, v->value);
+ ast_str_append(&out, 0, "<tr><td><i>Submitted GET Variable '");
+ str_append_escaped(&out, v->name);
+ ast_str_append(&out, 0, "'</i></td><td>");
+ str_append_escaped(&out, v->value);
+ ast_str_append(&out, 0, "</td></tr>\r\n");
}
ast_str_append(&out, 0, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
cookies = ast_http_get_cookies(headers);
for (v = cookies; v; v = v->next) {
- ast_str_append(&out, 0, "<tr><td><i>Cookie '%s'</i></td><td>%s</td></tr>\r\n", v->name, v->value);
+ ast_str_append(&out, 0, "<tr><td><i>Cookie '");
+ str_append_escaped(&out, v->name);
+ ast_str_append(&out, 0, "'</i></td><td>");
+ str_append_escaped(&out, v->value);
+ ast_str_append(&out, 0, "</td></tr>\r\n");
}
ast_variables_destroy(cookies);
@@ -2444,7 +2480,7 @@ static int __ast_http_load(int reload)
struct ast_variable *v;
int enabled = 0;
int new_static_uri_enabled = 0;
- int new_status_uri_enabled = 1; /* Default to enabled for BC */
+ int new_status_uri_enabled = 0;
char newprefix[MAX_PREFIX] = "";
char server_name[MAX_SERVER_NAME_LENGTH];
struct http_uri_redirect *redirect;