Skip to content

Commit

Permalink
Merge pull request #25 from curityio/feature/cors-fix
Browse files Browse the repository at this point in the history
Same domain CORS fix
  • Loading branch information
gary-archer committed Oct 7, 2022
2 parents 42c60b8 + 28bfbb5 commit 55e4956
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 18 deletions.
48 changes: 30 additions & 18 deletions src/oauth_proxy_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "oauth_proxy.h"

/* Forward declarations of implementation functions */
static ngx_flag_t is_data_changing_command(ngx_http_request_t *request);
static ngx_str_t *get_header(ngx_http_request_t *request, const char *name);
static ngx_int_t verify_web_origin(const oauth_proxy_configuration_t *config, const ngx_str_t *web_origin);
static ngx_int_t apply_csrf_checks(ngx_http_request_t *request, const oauth_proxy_configuration_t *config, const ngx_str_t *web_origin);
Expand Down Expand Up @@ -72,27 +73,27 @@ ngx_int_t oauth_proxy_handler_main(ngx_http_request_t *request)
}

/* Verify the web origin, which is sent by all modern browsers */
web_origin = get_header(request, "origin");
if (web_origin == NULL)
{
ret_code = NGX_HTTP_UNAUTHORIZED;
ngx_log_error(NGX_LOG_WARN, request->connection->log, 0, "The request did not have an origin header");
return write_error_response(request, ret_code, module_location_config);
}

ret_code = verify_web_origin(module_location_config, web_origin);
if (ret_code != NGX_OK)
{
ret_code = NGX_HTTP_UNAUTHORIZED;
ngx_log_error(NGX_LOG_WARN, request->connection->log, 0, "The request was from an untrusted web origin");
return write_error_response(request, ret_code, module_location_config);
if (module_location_config->cors_enabled || is_data_changing_command(request))
{
web_origin = get_header(request, "origin");
if (web_origin == NULL)
{
ret_code = NGX_HTTP_UNAUTHORIZED;
ngx_log_error(NGX_LOG_WARN, request->connection->log, 0, "The request did not have an origin header");
return write_error_response(request, ret_code, module_location_config);
}

ret_code = verify_web_origin(module_location_config, web_origin);
if (ret_code != NGX_OK)
{
ret_code = NGX_HTTP_UNAUTHORIZED;
ngx_log_error(NGX_LOG_WARN, request->connection->log, 0, "The request was from an untrusted web origin");
return write_error_response(request, ret_code, module_location_config);
}
}

/* For data changing commands, apply double submit cookie checks in line with OWASP best practices */
if (request->method == NGX_HTTP_POST ||
request->method == NGX_HTTP_PUT ||
request->method == NGX_HTTP_PATCH ||
request->method == NGX_HTTP_DELETE)
if (is_data_changing_command(request))
{
ret_code = apply_csrf_checks(request, module_location_config, web_origin);
if (ret_code != NGX_OK)
Expand Down Expand Up @@ -133,6 +134,17 @@ ngx_int_t oauth_proxy_handler_main(ngx_http_request_t *request)
return NGX_OK;
}

/*
* CORS and CSRF checks work differently for this type of command
*/
static ngx_flag_t is_data_changing_command(ngx_http_request_t *request)
{
return request->method == NGX_HTTP_POST ||
request->method == NGX_HTTP_PUT ||
request->method == NGX_HTTP_PATCH ||
request->method == NGX_HTTP_DELETE ? 1 : 0;
}

/*
* Return the authorization header if it exists
*/
Expand Down
33 changes: 33 additions & 0 deletions t/http_get.t
Original file line number Diff line number Diff line change
Expand Up @@ -319,3 +319,36 @@ No AT cookie was found in the incoming request
--- response_body_like chomp
{"code":"unauthorized","message":"Access denied due to missing or invalid credentials"}
=== TEST HTTP_GET_11: Same origin GET with a valid cookie returns 200 and an Authorization header
#########################################################################################################
# Ensure that GET requests work as expected when same domain hosting is used and no origin header is sent
#########################################################################################################
--- config
location /t {
oauth_proxy on;
oauth_proxy_cookie_name_prefix "example";
oauth_proxy_encryption_key "4e4636356d65563e4c73233847503e3b21436e6f7629724950526f4b5e2e4e50";
oauth_proxy_trusted_web_origin "https://www.example.com";
oauth_proxy_cors_enabled off;
proxy_pass http://localhost:1984/target;
}
location /target {
add_header 'authorization' $http_authorization;
return 200;
}
--- request
GET /t
--- more_headers eval
my $data;
$data .= "cookie: example-at=" . $main::at_opaque_cookie . "\n";
$data;
--- error_code: 200
--- response_headers eval
"authorization: Bearer " . $main::at_opaque;

0 comments on commit 55e4956

Please sign in to comment.