-
-
Save pauloricardomg/7084524 to your computer and use it in GitHub Desktop.
# | |
# Acts as a nginx HTTPS proxy server | |
# enabling CORS only to domains matched by regex | |
# /https?://.*\.mckinsey\.com(:[0-9]+)?)/ | |
# | |
# Based on: | |
# * http://blog.themillhousegroup.com/2013/05/nginx-as-cors-enabled-https-proxy.html | |
# * http://enable-cors.org/server_nginx.html | |
# | |
server { | |
listen 443 default_server ssl; | |
server_name localhost; | |
# Fake certs - fine for development purposes :-) | |
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; | |
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; | |
ssl_session_timeout 5m; | |
location / { | |
proxy_redirect off; | |
proxy_set_header Host $host; | |
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |
# Nginx doesn't support nested If statements, so we | |
# concatenate compound conditions on the $cors variable | |
# and process later | |
# If request comes from allowed subdomain | |
# (*.mckinsey.com) then we enable CORS | |
if ($http_origin ~* (https?://.*\.mckinsey\.com(:[0-9]+)?$)) { | |
set $cors "1"; | |
} | |
# OPTIONS indicates a CORS pre-flight request | |
if ($request_method = 'OPTIONS') { | |
set $cors "${cors}o"; | |
} | |
# Append CORS headers to any request from | |
# allowed CORS domain, except OPTIONS | |
if ($cors = "1") { | |
more_set_headers 'Access-Control-Allow-Origin: $http_origin'; | |
more_set_headers 'Access-Control-Allow-Credentials: true'; | |
proxy_pass http://serverIP:serverPort; | |
} | |
# OPTIONS (pre-flight) request from allowed | |
# CORS domain. return response directly | |
if ($cors = "1o") { | |
more_set_headers 'Access-Control-Allow-Origin: $http_origin'; | |
more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE'; | |
more_set_headers 'Access-Control-Allow-Credentials: true'; | |
more_set_headers 'Access-Control-Allow-Headers: Origin,Content-Type,Accept'; | |
add_header Content-Length 0; | |
add_header Content-Type text/plain; | |
return 204; | |
} | |
# Requests from non-allowed CORS domains | |
proxy_pass http://serverIP:serverPort; | |
} | |
} |
Thank you so much, this was helpful.
@anastasiosyal you are right. The most secure regex will at least look something like
https?:\/\/([a-z0-9-]+\.)*mckinsey\.com(:[0-9]+)?$
Since hostname parts cannot contain anything except alphanumeric characters and dash RFC 952.
Why don't we define $http_origin ?
Access nginx website https://nginx.org/en/docs/varindex.html ,I don't see this variable.
If use https request, the $http_origin it's invalid.
Hey there. Where should I use this code? Please
Not sure why you people are concerned about the regex security when using $http_origin
. This variable will not include any path info so you don't have to worry about ?
and #
.
Ref:
https://nginx.org/en/docs/http/ngx_http_core_module.html#var_http_
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin
Thanks for inspiration. Here's what we use with added exposed headers: https://gist.github.com/iki/1247cd182acd1aa3ee4876acb7263def
Not sure why you people are concerned about the regex security when using
$http_origin
. This variable will not include any path info so you don't have to worry about?
and#
.
Ref:
https://nginx.org/en/docs/http/ngx_http_core_module.html#var_http_
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin
Yeah,I think so!
Thank you Very very Much For Posting this solution. I had been Battling with this for 2 months. But in less than 3min, i was able to fix it with the solution you provided.
Hey there. Where should I use this code? Please
@julioaze in your /etc/nginx/sites-available/default
or somewhere with similar functionality.
Security by regex, will always be weak. Here's another expression that will bypass the 'fixed' version of the regex:
https://badsite.com/#sub.mckinsey.com
There's probably more attack vectors even if you did expand the regex to include the hash exclusion as below
https?:\/\/(.[^?#]*\.)?mckinsey\.com(:[0-9]+)?$