Skip to content

Instantly share code, notes, and snippets.

@madawei2699
Last active March 7, 2022 05:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save madawei2699/e444cfb398fac58927c745fbad1dbb26 to your computer and use it in GitHub Desktop.
Save madawei2699/e444cfb398fac58927c745fbad1dbb26 to your computer and use it in GitHub Desktop.
samesite strict mode test

SameSite Strict Test

Benefit of SameSite Strict

If the SameSite attribute is set to Strict, then the browser will not include the cookie in any requests that originate from another site. This is the most defensive option, but it can impair the user experience, because if a logged-in user follows a third-party link to a site, then they will appear not to be logged in, and will need to log in again before interacting with the site in the normal way.

If the SameSite attribute is set to Lax, then the browser will include the cookie in requests that originate from another site but only if two conditions are met:

  • The request uses the GET method. Requests with other methods, such as POST, will not include the cookie.
    • Imagine we have a very bad design and all our actions are performed on GET method. The attacker placed link saying "Save puppies" which links to http://oursite.com/users/2981/delete
  • The request resulted from a top-level navigation by the user, such as clicking a link. Other requests, such as those initiated by scripts, will not include the cookie.

Using SameSite cookies in Lax mode does then provide a partial defense against CSRF attacks, because user actions that are targets for CSRF attacks are often implemented using the POST method. Two important caveats here are:

  • Some applications do implement sensitive actions using GET requests.
  • Many applications and frameworks are tolerant of different HTTP methods. In this situation, even if the application itself employs the POST method by design, it will in fact accept requests that are switched to use the GET method.

Obviously, these limited benefits come at a serious UX tradeoff, and so are typically not worth it compared to the already-pretty-good protections offered by samesite=lax.

For the reasons described, it is not recommended to rely solely on SameSite cookies as a defense against CSRF attacks. Used in conjunction with CSRF tokens.

A Way to Resolve Login Problem When Link From External Website

We use a redirect page to break the chain of requests from external websites that allow the browser to send a login cookie.

  • First access http://localhost:8080/cookie and this will set a cookie named access-token which SameSite is Strict.
  • When user access http://localhost:8080/success from external website.
  • Then browser will redirect to http://localhost:8080/success with status code is 307 but without access-token cookie.
  • Then browser will redirect to http://localhost:8080/redirect which status code is 200 but without access-token cookie.
  • Finally browser will redirect to http://localhost:8080/success which status code is 200 but with access-token cookie.

References

# Python 3 server example
from http.server import BaseHTTPRequestHandler, HTTPServer
hostName = "localhost"
serverPort = 8080
class MyServer(BaseHTTPRequestHandler):
def do_GET(self):
path = self.path.replace("http://localhost:8080/", "")
if (self.headers["Referer"] != None and self.headers["Referer"] != 'http://localhost:8080/' and path != '/redirect' and self.headers["Cookie"] == None):
self.send_response(307)
else:
self.send_response(200)
self.send_header("Content-type", "text/html")
if (path == '/cookie'):
self.send_header("Set-Cookie", 'access-token=123; Path=/; SameSite=Strict')
if (self.headers["Referer"] != None and self.headers["Referer"] != 'http://localhost:8080/' and path != '/redirect' and self.headers["Cookie"] == None):
self.send_header("Location", "http://localhost:8080/redirect")
self.end_headers()
if (path == '/redirect'):
self.wfile.write(bytes("<html><head><title>redirect</title><meta http-equiv='refresh' content='0; URL=/success'/></head>", "utf-8"))
self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
self.wfile.write(bytes("<body>", "utf-8"))
self.wfile.write(bytes("<p>This is an redirect path.</p>", "utf-8"))
self.wfile.write(bytes("</body></html>", "utf-8"))
else:
self.wfile.write(bytes("<html><head><title>test</title></head>", "utf-8"))
self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
self.wfile.write(bytes("<body>", "utf-8"))
self.wfile.write(bytes("<p>This is an example web server.</p>", "utf-8"))
self.wfile.write(bytes("</body></html>", "utf-8"))
if __name__ == "__main__":
webServer = HTTPServer((hostName, serverPort), MyServer)
print("Server started http://%s:%s" % (hostName, serverPort))
try:
webServer.serve_forever()
except KeyboardInterrupt:
pass
webServer.server_close()
print("Server stopped.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment