Make sure to check the origin header against the authorized list for all requests.

This commit is contained in:
Wesley Miaw
2020-07-01 12:32:02 -07:00
parent 72339c2e0c
commit dbc6d3d9a7

View File

@@ -625,7 +625,7 @@ static int origin_matches(const char *origin, const char *candidate) {
if (origin_len < candidate_len) if (origin_len < candidate_len)
return 0; return 0;
fprintf(stderr, "comparing %s to %s len %lld\n", origin, candidate, candidate_len); fprintf(stderr, "comparing %s to %s len %zu\n", origin, candidate, candidate_len);
return strncmp(origin, candidate, candidate_len - 1) == 0; return strncmp(origin, candidate, candidate_len - 1) == 0;
} }
@@ -712,9 +712,8 @@ static int is_allowed_origin(DIALServer* ds, char * origin, const char * app_nam
#define RUN_URI "/run" #define RUN_URI "/run"
#define HIDE_URI "/hide" #define HIDE_URI "/hide"
static void *options_response(DIALServer *ds, struct mg_connection *conn, char *host_header, char *origin_header, const char* app_name, const char* methods) static void *options_response(DIALServer *ds, struct mg_connection *conn, char *origin_header, const char* app_name, const char* methods)
{ {
if (host_header && is_allowed_origin(ds, origin_header, app_name)) {
mg_printf( mg_printf(
conn, conn,
"HTTP/1.1 204 No Content\r\n" "HTTP/1.1 204 No Content\r\n"
@@ -727,9 +726,6 @@ static void *options_response(DIALServer *ds, struct mg_connection *conn, char *
origin_header); origin_header);
return "done"; return "done";
} }
mg_send_http_error(conn, 403, "Forbidden", "Forbidden");
return "done";
}
static void *request_handler(enum mg_event event, struct mg_connection *conn, static void *request_handler(enum mg_event event, struct mg_connection *conn,
const struct mg_request_info *request_info) { const struct mg_request_info *request_info) {
@@ -761,20 +757,22 @@ static void *request_handler(enum mg_event event, struct mg_connection *conn,
} }
strncpy(app_name, request_info->uri + strlen(APPS_URI), appname_len); strncpy(app_name, request_info->uri + strlen(APPS_URI), appname_len);
// Check authorized origins.
if (origin_header && !is_allowed_origin(ds, origin_header, app_name)) {
mg_send_http_error(conn, 403, "Forbidden", "Forbidden");
return "done";
}
// Return OPTIONS.
if (!strcmp(request_info->request_method, "OPTIONS")) { if (!strcmp(request_info->request_method, "OPTIONS")) {
return options_response(ds, conn, host_header, origin_header, app_name, "DELETE, OPTIONS"); return options_response(ds, conn, origin_header, app_name, "DELETE, OPTIONS");
} }
// DELETE non-empty app name // DELETE non-empty app name
if (app_name[0] != '\0' if (app_name[0] != '\0'
&& !strcmp(request_info->request_method, "DELETE")) && !strcmp(request_info->request_method, "DELETE"))
{ {
if (host_header && is_allowed_origin(ds, origin_header, app_name)) {
handle_app_stop(conn, request_info, app_name, origin_header); handle_app_stop(conn, request_info, app_name, origin_header);
} else {
mg_send_http_error(conn, 403, "Forbidden", "Forbidden");
return "done";
}
} else { } else {
mg_send_http_error(conn, 501, "Not Implemented", mg_send_http_error(conn, 501, "Not Implemented",
"Not Implemented"); "Not Implemented");
@@ -788,18 +786,20 @@ static void *request_handler(enum mg_event event, struct mg_connection *conn,
const char *app_name; const char *app_name;
app_name = request_info->uri + strlen(APPS_URI); app_name = request_info->uri + strlen(APPS_URI);
// Check authorized origins.
if (origin_header && !is_allowed_origin(ds, origin_header, app_name)) {
mg_send_http_error(conn, 403, "Forbidden", "Forbidden");
return "done";
}
// Return OPTIONS.
if (!strcmp(request_info->request_method, "OPTIONS")) { if (!strcmp(request_info->request_method, "OPTIONS")) {
return options_response(ds, conn, host_header, origin_header, app_name, "GET, POST, OPTIONS"); return options_response(ds, conn, origin_header, app_name, "GET, POST, OPTIONS");
} }
// start app // start app
if (!strcmp(request_info->request_method, "POST")) { if (!strcmp(request_info->request_method, "POST")) {
if (host_header && is_allowed_origin(ds, origin_header, app_name)) {
handle_app_start(conn, request_info, app_name, origin_header); handle_app_start(conn, request_info, app_name, origin_header);
} else {
mg_send_http_error(conn, 403, "Forbidden", "Forbidden");
return "done";
}
// get app status // get app status
} else if (!strcmp(request_info->request_method, "GET")) { } else if (!strcmp(request_info->request_method, "GET")) {
handle_app_status(conn, request_info, app_name, origin_header); handle_app_status(conn, request_info, app_name, origin_header);
@@ -819,10 +819,18 @@ static void *request_handler(enum mg_event event, struct mg_connection *conn,
} }
strncpy(app_name, request_info->uri + strlen(APPS_URI), appname_len); strncpy(app_name, request_info->uri + strlen(APPS_URI), appname_len);
if (!strcmp(request_info->request_method, "OPTIONS")) { // Check authorized origins.
return options_response(ds, conn, host_header, origin_header, app_name, "POST, OPTIONS"); if (origin_header && !is_allowed_origin(ds, origin_header, app_name)) {
mg_send_http_error(conn, 403, "Forbidden", "Forbidden");
return "done";
} }
// Return OPTIONS.
if (!strcmp(request_info->request_method, "OPTIONS")) {
return options_response(ds, conn, origin_header, app_name, "POST, OPTIONS");
}
// hide app
if (app_name[0] != '\0' && !strcmp(request_info->request_method, "POST")) { if (app_name[0] != '\0' && !strcmp(request_info->request_method, "POST")) {
handle_app_hide(conn, request_info, app_name, origin_header); handle_app_hide(conn, request_info, app_name, origin_header);
} else { } else {
@@ -840,11 +848,20 @@ static void *request_handler(enum mg_event event, struct mg_connection *conn,
if (app_name == NULL) { if (app_name == NULL) {
mg_send_http_error(conn, 500, "Internal Error", "Internal Error"); mg_send_http_error(conn, 500, "Internal Error", "Internal Error");
} else { } else {
// Check authorized origins (still applicable via loopback).
if (origin_header && !is_allowed_origin(ds, origin_header, app_name)) {
mg_send_http_error(conn, 403, "Forbidden", "Forbidden");
return "done";
}
// Return OPTIONS.
if (!strcmp(request_info->request_method, "OPTIONS")) { if (!strcmp(request_info->request_method, "OPTIONS")) {
void *ret = options_response(ds, conn, host_header, origin_header, app_name, "POST, OPTIONS"); void *ret = options_response(ds, conn, origin_header, app_name, "POST, OPTIONS");
free(app_name); free(app_name);
return ret; return ret;
} }
// deliver data payload
int use_payload = strcmp(request_info->request_method, "POST") ? 0 : 1; int use_payload = strcmp(request_info->request_method, "POST") ? 0 : 1;
handle_dial_data(conn, request_info, app_name, origin_header, handle_dial_data(conn, request_info, app_name, origin_header,
use_payload); use_payload);