def main(request, response): """Set a cookie via GET params. Usage: `/cookie.py?set={cookie}` The passed-in cookie string should be stringified via JSON.stringify() (in the case of multiple cookie headers sent in an array) and encoded via encodeURIComponent, otherwise `parse_qsl` will split on any semicolons (used by the Request.GET property getter). Note that values returned by Request.GET will decode any percent-encoded sequences sent in a GET param (which may or may not be surprising depending on what you're doing). Note: here we don't use Response.delete_cookie() or similar other methods in this resources directory because there are edge cases that are impossible to express via those APIs, namely a bare (`Path`) or empty Path (`Path=`) attribute. Instead, we pipe through the entire cookie and append `max-age=0` to it. """ headers = setNoCacheAndCORSHeaders(request, response) if b'set' in request.GET: cookie = isomorphic_decode(request.GET[b'set']) cookie = json.loads(cookie) cookies = cookie if isinstance(cookie, list) else [cookie] for c in cookies: set_cookie(headers, c) if b'location' in request.GET: headers.append((b'Location', request.GET[b'location'])) return 302, headers, b'{"redirect": true}' return headers, b'{"success": true}'
def main(request, response): """Respond to `/cookie/set/samesite?{value}` by setting four cookies: 1. `samesite_strict={value};SameSite=Strict;path=/` 2. `samesite_lax={value};SameSite=Lax;path=/` 3. `samesite_none={value};SameSite=None;path=/` 4. `samesite_unspecified={value};path=/` Then navigate to a page that will post a message back to the opener with the set cookies""" headers = setNoCacheAndCORSHeaders(request, response) value = isomorphic_encode(request.url_parts.query) headers.append((b"Content-Type", b"text/html; charset=utf-8")) headers.append(makeCookieHeader(b"samesite_strict", value, {b"SameSite":b"Strict", b"path":b"/"})) headers.append(makeCookieHeader(b"samesite_lax", value, {b"SameSite":b"Lax", b"path":b"/"})) # SameSite=None cookies must be Secure. headers.append(makeCookieHeader(b"samesite_none", value, {b"SameSite":b"None", b"path":b"/", b"Secure": b""})) headers.append(makeCookieHeader(b"samesite_unspecified", value, {b"path":b"/"})) document = b""" <!DOCTYPE html> <script> // A same-site navigation, which should attach all cookies including SameSite ones. // This is necessary because this page may have been reached via a cross-site navigation, so // we might not have access to some SameSite cookies from here. window.location = "../samesite/resources/echo-cookies.html"; </script> """ return headers, document
def main(request, response): """Set or drop a cookie via GET params. Usage: `/cookie.py?set={cookie}` or `/cookie.py?drop={cookie}` The passed-in cookie string should be encoded via encodeURIComponent, otherwise `parse_qsl` will split on any semicolons (used by the Request.GET property getter). Note: here we don't use Response.delete_cookie() or similar other methods in this resources directory because there are edge cases that are impossible to express via those APIs, namely a bare (`Path`) or empty Path (`Path=`) attribute. Instead, we pipe through the entire cookie and append `max-age=0` to it. """ headers = setNoCacheAndCORSHeaders(request, response) try: if b'drop' in request.GET: cookie = request.GET[b'drop'] cookie += b"; max-age=0" if b'set' in request.GET: cookie = request.GET[b'set'] headers.append((b'Set-Cookie', isomorphic_encode(cookie))) return headers, b'{"success": true}' except Exception as e: return 500, headers, bytes({'error': '{}'.format(e)})
def main(request, response): headers = helpers.setNoCacheAndCORSHeaders(request, response) cookies = helpers.readCookies(request) decoded_cookies = { isomorphic_decode(key): isomorphic_decode(val) for key, val in cookies.items() } return headers, json.dumps(decoded_cookies)
def main(request, response): """Respond to `/cookie/drop/secure` by dropping the two cookie set by `setSecureTestCookies()`""" headers = setNoCacheAndCORSHeaders(request, response) # Expire the cookies, and return a JSON-encoded success code. headers.append(makeDropCookie(b"alone_secure", False)) headers.append(makeDropCookie(b"alone_insecure", False)) return headers, b'{"success": true}'
def main(request, response): """Respond to `/cookies/resources/dropSameSiteNone.py by dropping the two cookies set by setSameSiteNone.py""" headers = setNoCacheAndCORSHeaders(request, response) # Expire the cookies, and return a JSON-encoded success code. headers.append(makeDropCookie(b"samesite_none_insecure", False)) headers.append(makeDropCookie(b"samesite_none_secure", True)) return headers, b'{"success": true}'
def main(request, response): """Respond to `/cookie/set/samesite?{value}` by setting the following combination of cookies: 1. `samesite_unsupported={value};SameSite=Unsupported;path=/;Secure` 2. `samesite_unsupported_none={value};SameSite=Unsupported;SameSite=None;path=/;Secure` 3. `samesite_unsupported_lax={value};SameSite=Unsupported;SameSite=Lax;path=/` 4. `samesite_unsupported_strict={value};SameSite=Unsupported;SameSite=Strict;path=/` 5. `samesite_none_unsupported={value};SameSite=None;SameSite=Unsupported;path=/;Secure` 6. `samesite_lax_unsupported={value};SameSite=Lax;SameSite=Unsupported;path=/;Secure` 7. `samesite_strict_unsupported={value};SameSite=Strict;SameSite=Unsupported;path=/;Secure` 8. `samesite_lax_none={value};SameSite=Lax;SameSite=None;path=/;Secure` 9. `samesite_lax_strict={value};SameSite=Lax;SameSite=Strict;path=/` 10. `samesite_strict_lax={value};SameSite=Strict;SameSite=Lax;path=/` Then navigate to a page that will post a message back to the opener with the set cookies""" headers = setNoCacheAndCORSHeaders(request, response) value = isomorphic_encode(request.url_parts.query) headers.append((b"Content-Type", b"text/html; charset=utf-8")) # Unknown value; single attribute headers.append(makeCookieHeader( b"samesite_unsupported", value, {b"SameSite":b"Unsupported", b"path":b"/", b"Secure":b""})) # Multiple attributes; first attribute unknown headers.append(makeCookieHeader( b"samesite_unsupported_none", value, {b"SameSite":b"Unsupported", b"SameSite":b"None", b"path":b"/", b"Secure":b""})) headers.append(makeCookieHeader( b"samesite_unsupported_lax", value, {b"SameSite":b"Unsupported", b"SameSite":b"Lax", b"path":b"/"})) headers.append(makeCookieHeader( b"samesite_unsupported_strict", value, {b"SameSite":b"Unsupported", b"SameSite":b"Strict", b"path":b"/"})) # Multiple attributes; second attribute unknown headers.append(makeCookieHeader( b"samesite_none_unsupported", value, {b"SameSite":b"None", b"SameSite":b"Unsupported", b"path":b"/", b"Secure":b""})) headers.append(makeCookieHeader( b"samesite_lax_unsupported", value, {b"SameSite":b"Lax", b"SameSite":b"Unsupported", b"path":b"/", b"Secure":b""})) headers.append(makeCookieHeader( b"samesite_strict_unsupported", value, {b"SameSite":b"Strict", b"SameSite":b"Unsupported", b"path":b"/", b"Secure":b""})) # Multiple attributes; both known headers.append(makeCookieHeader( b"samesite_lax_none", value, {b"SameSite":b"Lax", b"SameSite":b"None", b"path":b"/", b"Secure":b""})) headers.append(makeCookieHeader( b"samesite_lax_strict", value, {b"SameSite":b"Lax", b"SameSite":b"Strict", b"path":b"/"})) headers.append(makeCookieHeader( b"samesite_strict_lax", value, {b"SameSite":b"Strict", b"SameSite":b"Lax", b"path":b"/"})) document = b""" <!DOCTYPE html> <script> // A same-site navigation, which should attach all cookies including SameSite ones. // This is necessary because this page may have been reached via a cross-site navigation, so // we might not have access to some SameSite cookies from here. window.location = "../samesite/resources/echo-cookies.html"; </script> """ return headers, document
def main(request, response): """Respond to `/cookie/set?{cookie}` by echoing `{cookie}` as a `Set-Cookie` header.""" headers = helpers.setNoCacheAndCORSHeaders(request, response) # Cookies may require whitespace (e.g. in the `Expires` attribute), so the # query string should be decoded. cookie = unquote(request.url_parts.query) headers.append((b"Set-Cookie", isomorphic_encode(cookie))) return headers, b'{"success": true}'
def main(request, response): """Respond to `/cookie/drop?name={name}` by expiring the cookie named `{name}`.""" headers = setNoCacheAndCORSHeaders(request, response) try: # Expire the named cookie, and return a JSON-encoded success code. name = readParameter(request, paramName=u"name", requireValue=True) scheme = request.url_parts.scheme headers.append(makeDropCookie(name, u"https" == scheme)) return headers, b'{"success": true}' except: return 500, headers, b'{"error" : "Empty or missing name parameter."}'
def main(request, response): """Respond to `/cookie/same-site/resources/dropSameSite.py by dropping the four cookies set by setSameSiteCookies.py""" headers = setNoCacheAndCORSHeaders(request, response) # Expire the cookies, and return a JSON-encoded success code. headers.append(makeDropCookie(b"samesite_strict", False)) headers.append(makeDropCookie(b"samesite_lax", False)) headers.append(makeDropCookie(b"samesite_none", False)) headers.append(makeDropCookie(b"samesite_unspecified", False)) return headers, b'{"success": true}'
def main(request, response): """Respond to `/cookies/resources/dropSameSiteMultiAttribute.py by dropping the cookies set by setSameSiteMultiAttribute.py""" headers = setNoCacheAndCORSHeaders(request, response) # Expire the cookies, and return a JSON-encoded success code. headers.append(makeDropCookie(b"samesite_unsupported", True)) headers.append(makeDropCookie(b"samesite_unsupported_none", True)) headers.append(makeDropCookie(b"samesite_unsupported_lax", False)) headers.append(makeDropCookie(b"samesite_unsupported_strict", False)) headers.append(makeDropCookie(b"samesite_none_unsupported", True)) headers.append(makeDropCookie(b"samesite_lax_unsupported", True)) headers.append(makeDropCookie(b"samesite_strict_unsupported", True)) headers.append(makeDropCookie(b"samesite_lax_none", True)) return headers, b'{"success": true}'
def main(request, response): """Respond to `/cookie/imgIfMatch?name={name}&value={value}` with a 404 if the cookie isn't present, and a transparent GIF otherwise.""" headers = helpers.setNoCacheAndCORSHeaders(request, response) name = helpers.readParameter(request, paramName=u"name", requireValue=True) value = helpers.readParameter(request, paramName=u"value", requireValue=True) cookiesWithMatchingNames = request.cookies.get_list(name) for cookie in cookiesWithMatchingNames: if cookie.value == value: # From https://github.com/mathiasbynens/small/blob/master/gif-transparent.gif headers.append((b"Content-Type", b"image/gif")) gif = b"\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\xFF\xFF\xFF\x00\x00\x00\x21\xF9\x04\x01\x00\x00\x00\x00\x2C\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x44\x01\x00\x3B" return headers, gif return 500, headers, b'{"error": {"message": "The cookie\'s value did not match the given value."}}'
def main(request, response): """Simple handler that causes redirection. The request should typically have two query parameters: status - The status to use for the redirection. Defaults to 302. location - The resource to redirect to. """ status = 302 if b"status" in request.GET: try: status = int(request.GET.first(b"status")) except ValueError: pass headers = setNoCacheAndCORSHeaders(request, response) location = request.GET.first(b"location") headers.append((b"Location", location)) return status, headers, b""
def main(request, response): """Respond to `/cookies/resources/setSameSiteNone.py?{value}` by setting two cookies: 1. `samesite_none_insecure={value};SameSite=None;path=/` 2. `samesite_none_secure={value};SameSite=None;Secure;path=/` """ headers = setNoCacheAndCORSHeaders(request, response) value = isomorphic_encode(request.url_parts.query) headers.append( makeCookieHeader(b"samesite_none_insecure", value, { b"SameSite": b"None", b"path": b"/" })) headers.append( makeCookieHeader(b"samesite_none_secure", value, { b"SameSite": b"None", b"Secure": b"", b"path": b"/" })) return headers, b'{"success": true}'
def main(request, response): headers = helpers.setNoCacheAndCORSHeaders(request, response) cookies = helpers.readCookies(request) headers.append((b"Content-Type", b"text/html; charset=utf-8")) tmpl = u""" <!DOCTYPE html> <script> var data = %s; data.type = "COOKIES"; try { data.domcookies = document.cookie; } catch (e) {} if (window.parent != window) { window.parent.postMessage(data, "*"); if (window.top != window.parent) window.top.postMessage(data, "*"); } if (window.opener) window.opener.postMessage(data, "*"); window.addEventListener("message", e => { console.log(e); if (e.data == "reload") window.location.reload(); }); </script> """ decoded_cookies = { isomorphic_decode(key): isomorphic_decode(val) for key, val in cookies.items() } return headers, tmpl % json.dumps(decoded_cookies)