nginx allow access to location only if request came from cognito - amazon-web-services

I'm using AWS Cognito for auth, and have it redirect to a certain path at my nginx website
I want this path should only be reachable if the request comes from after the user logs in via cognito.
How do I block access to the path in nginx if someone just types that path into the address bar?
Let's say for example, the location I want locked down is:
http://localhost:3010/firstPath/
In Chrome devtools I don't see any referrer or anything like that in the request:
Request URL: http://localhost:3010/firstPath/?code=axxxxx-xxxx-xxx-9b18-df2832a401e9&state=N35vxxxxxJGnlJr5YEI5AVfFRPdbghFG
Request Method: GET
Status Code: 200 OK
Remote Address: 127.0.0.1:3010
Referrer Policy: strict-origin-when-cross-origin
Accept-Ranges: bytes
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Date: Thu, 28 Jan 2021 08:52:50 GMT
ETag: W/"868-KJFfIJ4iphNuyGJQRrz3NAqMbz4"
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Powered-By: Express
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: keep-alive
DNT: 1
Host: localhost:3010
Pragma: no-cache
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: cross-site
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36
code: axxxxx-xxxx-xxx-9b18-df2832a401e9
state: N35vxxxxxJGnlJr5Y
In nginx I can block requests that didn't come from AWS ELB to my /health check path, like this:
location /health {
set $block 1;
# Allow all the ELB health check agents.
if ($http_user_agent ~* '^ELB-HealthChecker\/.*$') {
set $block 0;
access_log off;
}
# block invalid requests
if ($block = 1) {
return 444;
}
return 200;
add_header Content-Type text/plain;
}
Is there a way to do similar for this path, based on the request coming from aws cognito?

Related

POST request returning 401 Unauthorised (only in Chrome)

I'm using Django Rest Framework and Vue.js to build a basic web app, and am currently working on the auth. Using axios to send a post request while registering a new user returns 401 in Chrome for some reason, but works in other browsers (Edge) and returns a 201 Created.
The error in chrome is "detail: Invalid Token", but this particular endpoint (registration) doesn't even need auth/token to access.
My frontend is at http://192.168.1.33:8080 and my backend is at http://127.0.0.1:8000
I am trying to POST data to http://127.0.0.1:8000/api/v1/users/auths/
The Network tab in chrome dev tools after trying a request:
Request URL: http://127.0.0.1:8000/api/v1/users/auths/
Request Method: POST
Status Code: 401 Unauthorized
Remote Address: 127.0.0.1:8000
Referrer Policy: strict-origin-when-cross-origin
Access-Control-Allow-Origin: http://192.168.1.33:8080
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 27
Content-Type: application/json
Date: Mon, 06 Dec 2021 12:19:15 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.8.5
Vary: Accept, Origin
WWW-Authenticate: Token
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Authorization: Token acf8b9099de5eba413dea141ce2c06b6cfb03159
Connection: keep-alive
Content-Length: 53
Content-Type: application/json
Host: 127.0.0.1:8000
Origin: http://192.168.1.33:8080
Referer: http://192.168.1.33:8080/
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
The network tab in Edge dev tools after trying the same thing:
Request URL: http://127.0.0.1:8000/api/v1/users/auths/
Request Method: POST
Status Code: 201 Created
Remote Address: 127.0.0.1:8000
Referrer Policy: strict-origin-when-cross-origin
Access-Control-Allow-Origin: http://192.168.1.33:8080
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 89
Content-Type: application/json
Date: Mon, 06 Dec 2021 12:20:25 GMT
Location: http://127.0.0.1:8000/api/v1/users/auths/12/
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.8.5
Vary: Accept, Origin, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Authorization
Connection: keep-alive
Content-Length: 51
Content-Type: application/json
Host: 127.0.0.1:8000
Origin: http://192.168.1.33:8080
Referer: http://192.168.1.33:8080/
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Microsoft Edge";v="96"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.43
The obvious difference is that there is a "WWW-Authenticate: Token" in the Chrome Network tab, which is odd.
CORS headers and all have been set up properly, plus the issue is only in Chrome. Is this some Chrome quirk, or am I missing something?
Why is it that, after spending some two hours on a problem, you only get the answer after you've posted it on a forum? Probably something to do with putting the problem down categorically and formally...
Anyway. Turns out the issue was with there being a random token sitting in Chrome's local storage, which was causing all the trouble with the "invalid" token. I cleared local storage, and it's working now. No clue why I had to do this specifically — I had made sure to clear the cache earlier...

CORS issue working with DJango Simple SSO

I'm using a fork of Django Simple SSO as an authentication mechanism on a Server.
It works great while we use the "standard" way to log in on the server. This means, we just access to the /login path, log in, and then navigate across the restricted paths, etc.
The problem comes when we want to connect to a 3rd server that also relays on SSO auth vía javascript/AJAX without direct access to /login path first.
I've tried to use django-cors-headers but didn't get the expected result.
I'm close to give up so any help is welcome.
The problem
Assume we are logged in on server 1 and auth server and we want a resource on server 2
When the browser is redirected to the Auth Server in order to verify that the browser is logged with a valid user, the cookie header is not transferred.
(See the diagram on button for further details on how Django Simple SSO works)
The headers set by the auth-server on the preflight request are the following:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept-encoding, accept, authorization, cookie, content-type, dnt, origin, user-agent, x-csrftoken, x-grafana-org-id, x-dashboard-id, x-panel-id, x-requested-with
Access-Control-Allow-Methods: DELETE, GET, OPTIONS, PATCH, POST, PUT
Access-Control-Allow-Origin: https://server1-domain
Access-Control-Max-Age: 86400
Connection: keep-alive
Content-Length: 0
Content-Type: text/html; charset=utf-8
Date: Fri, 16 Jul 2021 12:14:54 GMT
Server: nginx
Vary: Origin
The headers on the GET request where the following:
Request/Client:
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: es-ES,es;q=0.9,en-US;q=0.8,en;q=0.7
Connection: keep-alive
Host: auth-server-domain
Origin: https://server1-domain
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
sec-ch-ua-mobile: ?0
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36
x-grafana-org-id: 1
Response/Auth Server:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://server1-domain
Connection: keep-alive
Content-Language: es
Content-Length: 0
Content-Type: text/html; charset=utf-8
Date: Fri, 16 Jul 2021 12:14:54 GMT
Location: /error_unauthorized_page
Referrer-Policy: same-origin
Server: nginx
Vary: Accept-Language, Cookie, Origin
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
I think all the headers are correct, but it's clearly there are some error.
On the cookie side, I have tried to play with the SingleSite property, setting it to None and Lax without any change.
The domain set on the cookie browser's memory is "correct" from my point of view as it is .auth-server-domain (note the dot).
I'm using DJango 3.2.5 and Google Chrome as a web browser.
If you have any idea of why cookie is not being send on the auth-server-domain cors requests, I will really appreciate your comments.
If do you think I have missed any piece of relevant information, feel free to ask!
Thank everyone to reach this point and help me!
Appendix:
A simplified schema of how Simple SSO works:

httpOnly cookies in cross-domain requests not being sent

I'm really really sorry for asking yet another CORS question but I'm stuck and I can't understand why.
I have any API that, on login, responds with a Set-Cookie header which sets a cookie with my user info. This is what that response looks like:
Response from api.somesite.com
Access-Control-Allow-Credentials: true
Connection: keep-alive
Content-Length: 183
Content-Type: text/html; charset=utf-8
Date: Mon, 19 Apr 2021 19:55:02 GMT
Set-Cookie: socialAccesstoken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5MDk3NzQzNjkxNjU1MTY4MCIsInVzZXJuYW1lIjoiY3JlYXRpdmlpaSIsImRpc3BsYXlOYW1lIjoiTGVvIDjvuI_ig6MiLCJ1cmwiOiJodHRwczovL3QuY28vWjNBM01xaFBDbiIsInBob3RvIjoiaHR0cHM6Ly9wYnMudHdpbWcuY29tL3Byb2ZpbGVfaW1hZ2VzLzEzNzExMzQ3MjY0NzI0MTMxODYvZ0Q5Sk5lVU1fbm9ybWFsLmpwZyIsInByb3ZpZGVyIjoidHdpdHRlciIsImlhdCI6MTYxODg2MjEwMiwiZXhwIjoxNzA1MjYyMTAyfQ.Q7yWf-ywoZ-rWOhYseKTt_0V2_AlEMQ-cCL2rlRNm_U; Max-Age=86400; Path=/; Expires=Tue, 20 Apr 2021 19:55:02 GMT; HttpOnly
Vary: Origin
X-Powered-By: Express
The Cookie is set successfully and I can view it in the Application tab for api.somesite.com.
I then try to make a request from a page on the same domain:
Request from somesite.com to api.somesite.com
Response
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: http://somesite.com:8000
Vary: Origin
Access-Control-Allow-Credentials: true
Token-Expired: true
Content-Type: application/json; charset=utf-8
Content-Length: 196
ETag: W/"c4-HQkmHNLuibgvd4gvz0JqjTLKjFU"
Date: Mon, 19 Apr 2021 19:59:18 GMT
Connection: keep-alive
Request
Host: api.somesite.com:3000
Connection: keep-alive
Content-Length: 143
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36
content-type: application/json
Accept: */*
Origin: http://somesite.com:8000
Referer: http://somesite.com:8000/
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Cookie: socialAccesstoken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5MDk3NzQzNjkxNjU1MTY4MCIsInVzZXJuYW1lIjoiY3JlYXRpdmlpaSIsImRpc3BsYXlOYW1lIjoiTGVvIDjvuI_ig6MiLCJ1cmwiOiJodHRwczovL3QuY28vWjNBM01xaFBDbiIsInBob3RvIjoiaHR0cHM6Ly9wYnMudHdpbWcuY29tL3Byb2ZpbGVfaW1hZ2VzLzEzNzExMzQ3MjY0NzI0MTMxODYvZ0Q5Sk5lVU1fbm9ybWFsLmpwZyIsInByb3ZpZGVyIjoidHdpdHRlciIsImlhdCI6MTYxODg2MTQ2MiwiZXhwIjoxNzA1MjYxNDYyfQ.BpmQzWWYuBHLQQh6VpatflBsQUv2A0ahLqt1UgYOq8Q
As you can see the cookie is sent correctly.
But then if I switch my api to api.differentsite.com and make the same requests:
Response from api.differentsite.com
HTTP/1.1 200 OK
X-Powered-By: Express
Vary: Origin
Access-Control-Allow-Credentials: true
Set-Cookie: socialAccesstoken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5MDk3NzQzNjkxNjU1MTY4MCIsInVzZXJuYW1lIjoiY3JlYXRpdmlpaSIsImRpc3BsYXlOYW1lIjoiTGVvIDjvuI_ig6MiLCJ1cmwiOiJodHRwczovL3QuY28vWjNBM01xaFBDbiIsInBob3RvIjoiaHR0cHM6Ly9wYnMudHdpbWcuY29tL3Byb2ZpbGVfaW1hZ2VzLzEzNzExMzQ3MjY0NzI0MTMxODYvZ0Q5Sk5lVU1fbm9ybWFsLmpwZyIsInByb3ZpZGVyIjoidHdpdHRlciIsImlhdCI6MTYxODg2MjYzMSwiZXhwIjoxNzA1MjYyNjMxfQ.MvOLarBw_Mz-h26WvOrOqyE0IaDQEnIqp2xLUiFqAZQ; Max-Age=86400; Path=/; Expires=Tue, 20 Apr 2021 20:03:51 GMT; HttpOnly
Content-Type: text/html; charset=utf-8
Content-Length: 183
Date: Mon, 19 Apr 2021 20:03:51 GMT
Connection: keep-alive
(the cookie is set correctly at api.differentsite.com:3000 according to the Application tab in Chrome)
And then I try to make a request from somesite.com:
Response
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: http://somesite.com:8000
Vary: Origin
Access-Control-Allow-Credentials: true
Content-Type: application/json; charset=utf-8
Content-Length: 147
ETag: W/"93-2hkHY0W/lJkUQBK+JwrKp/OTCro"
Date: Mon, 19 Apr 2021 20:03:26 GMT
Connection: keep-alive
Request
POST /api HTTP/1.1
Host: api.differentsite.com:3000
Connection: keep-alive
Content-Length: 143
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36
content-type: application/json
Accept: */*
Origin: http://somesite.com:8000
Referer: http://somesite.com:8000/
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
There's no cookie sent, so authorisation fails.
Why is this happening? This should work, no?
My request looks like this:
const headers = new Headers();
headers.append("Content-Type", "application/json");
const result = await fetch(endpoint!, {
method: "POST",
headers,
body,
redirect: "follow",
credentials: "include",
}).then((response) => response.json());
I've checked over and over again and I'm certain these settings are correct.
I've followed the advice on this question but they didn't work. I'm unsure what Access-Control-Allow-Headers I should add on my request.
Looks like a night's sleep was all I needed.
The problem was caused by my cookies missing the correct settings. For httpOnly cookies to be sent in cross-domain requests they need to have:
same-site set to none
secure set to true
So I made sure these two values were set on cookies when in production:
sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax',
secure: process.env.NODE_ENV === 'production' ? true : false,
And it started working.
EDIT:
While this is the correct answer, it seems that Safari now blocks third party cookies by default, meaning no cookies will be sent if the client is safari. This can be deactivated in the settings, but it's on by default.

Configuring HAProxy as Google-CDN backend

I'm trying to configure an HAProxy backend to work with Google-CDN
I see that I always get to the HAProxy backend and the cache is always MISS
This is google-cdn requests regarding headers:
https://cloud.google.com/cdn/docs/caching#cacheability
and this is my HAProxy backend configurations (I've tried multiple sets of headers configuration, but never got an HIT):
http-response set-header Cache-Control public;max-age=31536000
http-response set-header Content-Length 260113322
# http-request add-header Cache-Control public;max-age=31533000
# http-request add-header Content-Length 26012101001
when I'm requesting the object in the browser these are the req\res headers:
Response Headers
alt-svc: clear
cache-control: public;max-age=31536000
content-length: 260113322
content-type: application/javascript; charset=utf-8
date: Thu, 05 Sep 2019 07:56:59 GMT
etag: W/"47e80-NwQR7oXLIZF+J1AAVu9L0mv54I4"
status: 200
vary: Accept-Encoding
via: 1.1 google
Request Headers
:authority: sapix-stg.example.net
:method: GET
:path: /bb/client/SX1234/main.js
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
cache-control: no-cache
pragma: no-cache
sec-fetch-mode: navigate
sec-fetch-site: none
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Thanks
Your Cache-Control reaponse header is malformed. The values are separared with a comma (and optional whitespace included by convention) -- not a semicolon.
http-response set-header Cache-Control "public, max-age=31536000"
The quotes are absorbed by the HAProxy parser. Also valid:
(no space)
http-response set-header Cache-Control public,max-age=31536000
(space escaped)
http-response set-header Cache-Control public,\ max-age=31536000
There should normally be no need to add Content-Length in the proxy. If your origin server isn't automatically setting either Content-Length or Transfer-Encoding in the response, then your server should be fixed, upgraded, or replaced.
It might be because your response contains "Vary" header. HAPoxy says that they don't cache that type of responses.

simple javascript file keeps returning 301 with cloudfront

I'm using cloudfront for a simple javascript asset that is the following:
https://d1syjrf5lltxmn.cloudfront.net/Content/JavaScript/jquery-migrate-1.2.1.min.js
I've got the Origin Domain name and path set to
www.siliconvalley-codecamp.com
Origin type is custom origin, policy i sMatch Viewer, view policy is http and https. Problem is when it hit this (over and over) it keeps returning a 301 and doing another request from my origin server.
I can't figure out why it keeps doing the 301's. I've read others having issues but can not find a solution.
GET https://d1syjrf5lltxmn.cloudfront.net/Content/JavaScript/jquery-migrate- 1.2.1.min.js HTTP/1.1
Host: d1syjrf5lltxmn.cloudfront.net
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
and the return is:
HTTP/1.1 301 Moved Permanently
Content-Type: text/html; charset=UTF-8
Content-Length: 208
Connection: keep-alive
Location: https://www.siliconvalley-codecamp.com/Content/JavaScript/jquery-migrate-1.2.1.min.js
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Fri, 23 Jan 2015 04:18:21 GMT
Age: 10575
X-Cache: Hit from cloudfront
Via: 1.1 f86dab587205f74a0e6f36b42207dec2.cloudfront.net (CloudFront)
X-Amz-Cf-Id: 8h4R0WTOl1wg8LDafMoeAkcvOr1G8ujfAVMgz84Uy_BVE8QlxTbTrQ==
<head><title>Document Moved</title></head>
<body><h1>Object Moved</h1>This document may be found here</body>
Origin server setup: