Skip to content

Commit af2ba25

Browse files
committed
Validate referer URL before using it (Issue #1419)
1 parent c262f9c commit af2ba25

1 file changed

Lines changed: 21 additions & 2 deletions

File tree

cgi-bin/home.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ do_login(void)
9696
{
9797
const char *oauth_uri = getenv("CUPS_OAUTH_SERVER"),
9898
// OAuth authorization server URL
99+
*referer = getenv("HTTP_REFERER"),
100+
// Referer: header
99101
*server_name = getenv("SERVER_NAME"),
100102
// SERVER_NAME value
101103
*server_port = getenv("SERVER_PORT"),
@@ -156,7 +158,9 @@ do_login(void)
156158

157159
// Redirect...
158160
cgiSetCookie("CUPS_OAUTH_STATE", state, /*path*/NULL, /*domain*/NULL, time(NULL) + 300, /*secure*/0);
159-
cgiSetCookie("CUPS_REFERRER", getenv("HTTP_REFERER"), /*path*/NULL, /*domain*/NULL, time(NULL) + 300, /*secure*/0);
161+
162+
if (referer)
163+
cgiSetCookie("CUPS_REFERRER", referer, /*path*/NULL, /*domain*/NULL, time(NULL) + 300, /*secure*/0);
160164

161165
do_redirect(url);
162166

@@ -236,6 +240,8 @@ finish_login(void)
236240
{
237241
const char *oauth_uri = getenv("CUPS_OAUTH_SERVER"),
238242
// OAuth authorization server URL
243+
*referer = getenv("CUPS_REFERER"),
244+
// Referring URL
239245
*server_name = getenv("SERVER_NAME"),
240246
// SERVER_NAME value
241247
*server_port = getenv("SERVER_PORT");
@@ -247,6 +253,11 @@ finish_login(void)
247253
const char *code; // Authorization code
248254
cups_json_t *metadata = NULL; // OAuth metadata
249255
time_t access_expires; // When the bearer token expires
256+
char scheme[32], // Referer scheme
257+
userpass[256], // Referer username:password
258+
host[256], // Referer host
259+
resource[1024]; // Referer resource
260+
int port; // Referer port
250261

251262

252263
// Show any error from authorization...
@@ -300,7 +311,15 @@ finish_login(void)
300311
cgiSetCookie("CUPS_BEARER", bearer, /*path*/NULL, /*domain*/NULL, access_expires, /*secure*/0);
301312

302313
// Redirect...
303-
do_redirect(cgiGetCookie("CUPS_REFERRER"));
314+
if (referer && server_name && server_port)
315+
{
316+
// Validate refererring URL value - must be http: or https:, use the server
317+
// name or localhost addresses, and use the same port...
318+
if (httpSeparateURI(HTTP_URI_CODING_ALL, referer, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK || (strcmp(scheme, "http") && strcmp(scheme, "https")) || (strcasecmp(host, server_name) && strcmp(host, "127.0.0.1") && strcmp(host, "[::1]")) || port != atoi(server_port))
319+
referer = NULL;
320+
}
321+
322+
do_redirect(referer ? referer : "/");
304323

305324
fputs("DEBUG2: finish_login: After redirect.\n", stderr);
306325

0 commit comments

Comments
 (0)