From 0427ecb14a9a75adf7cad36eea43521b66eae115 Mon Sep 17 00:00:00 2001 From: Raphael Tholl <48417580+RapTho@users.noreply.github.com> Date: Thu, 17 Dec 2020 12:05:54 +0100 Subject: [PATCH] Reformulations --- 6-data-storage/01-cookie/article.md | 88 ++++++++++++++--------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/6-data-storage/01-cookie/article.md b/6-data-storage/01-cookie/article.md index 4c35fa88..d0619048 100644 --- a/6-data-storage/01-cookie/article.md +++ b/6-data-storage/01-cookie/article.md @@ -1,13 +1,13 @@ # Cookies, document.cookie -Cookies are small strings of data that are stored directly in the browser. They are a part of HTTP protocol, defined by [RFC 6265](https://tools.ietf.org/html/rfc6265) specification. +Cookies are small strings of data that are stored directly in the browser. They are a part of the HTTP protocol, defined by the [RFC 6265](https://tools.ietf.org/html/rfc6265) specification. -Cookies are usually set by a web-server using response `Set-Cookie` HTTP-header. Then the browser automatically adds them to (almost) every request to the same domain using `Cookie` HTTP-header. +Cookies are usually set by a web-server using the response `Set-Cookie` HTTP-header. Then, the browser automatically adds them to (almost) every request to the same domain using the `Cookie` HTTP-header. One of the most widespread use cases is authentication: -1. Upon sign in, the server uses `Set-Cookie` HTTP-header in the response to set a cookie with a unique "session identifier". -2. Next time when the request is sent to the same domain, the browser sends the cookie over the net using `Cookie` HTTP-header. +1. Upon sign in, the server uses the `Set-Cookie` HTTP-header in the response to set a cookie with a unique "session identifier". +2. Next time when the request is sent to the same domain, the browser sends the cookie over the net using the `Cookie` HTTP-header. 3. So the server knows who made the request. We can also access cookies from the browser, using `document.cookie` property. @@ -50,9 +50,9 @@ document.cookie = "user=John"; // update only cookie named 'user' alert(document.cookie); // show all cookies ``` -If you run it, then probably you'll see multiple cookies. That's because `document.cookie=` operation does not overwrite all cookies. It only sets the mentioned cookie `user`. +If you run it, then probably you'll see multiple cookies. That's because the `document.cookie=` operation does not overwrite all cookies. It only sets the mentioned cookie `user`. -Technically, name and value can have any characters, to keep the valid formatting they should be escaped using a built-in `encodeURIComponent` function: +Technically, name and value can have any characters. To keep the valid formatting, they should be escaped using a built-in `encodeURIComponent` function: ```js run // special characters (spaces), need encoding @@ -69,7 +69,7 @@ alert(document.cookie); // ...; my%20name=John%20Smith ```warn header="Limitations" There are few limitations: - The `name=value` pair, after `encodeURIComponent`, should not exceed 4KB. So we can't store anything huge in a cookie. -- The total number of cookies per domain is limited to around 20+, the exact limit depends on a browser. +- The total number of cookies per domain is limited to around 20+, the exact limit depends on the browser. ``` Cookies have several options, many of them are important and should be set. @@ -84,7 +84,7 @@ document.cookie = "user=John; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT" - **`path=/mypath`** -The url path prefix, the cookie will be accessible for pages under that path. Must be absolute. By default, it's the current path. +The url path prefix must be absolute. It makes the cookie accessible for pages under that path. By default, it's the current path. If a cookie is set with `path=/admin`, it's visible at pages `/admin` and `/admin/something`, but not at `/home` or `/adminpage`. @@ -94,7 +94,7 @@ Usually, we should set `path` to the root: `path=/` to make the cookie accessibl - **`domain=site.com`** -A domain where the cookie is accessible. In practice though, there are limitations. We can't set any domain. +A domain defines where the cookie is accessible. In practice though, there are limitations. We can't set any domain. By default, a cookie is accessible only at the domain that set it. So, if the cookie was set by `site.com`, we won't get it at `other.com`. @@ -112,7 +112,7 @@ alert(document.cookie); // no user It's a safety restriction, to allow us to store sensitive data in cookies, that should be available only on one site. -...But if we'd like to allow subdomains like `forum.site.com` get a cookie, that's possible. When setting a cookie at `site.com`, we should explicitly set `domain` option to the root domain: `domain=site.com`: +...But if we'd like to allow subdomains like `forum.site.com` to get a cookie, that's possible. When setting a cookie at `site.com`, we should explicitly set the `domain` option to the root domain: `domain=site.com`: ```js // at site.com @@ -125,21 +125,21 @@ document.cookie = "user=John; domain=site.com" alert(document.cookie); // has cookie user=John ``` -For historical reasons, `domain=.site.com` (a dot before `site.com`) also works the same way, allowing access to the cookie from subdomains. That's an old notation, should be used if we need to support very old browsers. +For historical reasons, `domain=.site.com` (a dot before `site.com`) also works the same way, allowing access to the cookie from subdomains. That's an old notation and should be used if we need to support very old browsers. -So, `domain` option allows to make a cookie accessible at subdomains. +So, the `domain` option allows to make a cookie accessible at subdomains. ## expires, max-age By default, if a cookie doesn't have one of these options, it disappears when the browser is closed. Such cookies are called "session cookies" -To let cookies survive browser close, we can set either `expires` or `max-age` option. +To let cookies survive a browser close, we can set either the `expires` or `max-age` option. - **`expires=Tue, 19 Jan 2038 03:14:07 GMT`** -Cookie expiration date, when the browser will delete it automatically. +The cookie expiration date defines the time, when the browser will automatically delete it. -The date must be exactly in this format, in GMT timezone. We can use `date.toUTCString` to get it. For instance, we can set the cookie to expire in 1 day: +The date must be exactly in this format, in the GMT timezone. We can use `date.toUTCString` to get it. For instance, we can set the cookie to expire in 1 day: ```js // +1 day from now @@ -152,12 +152,12 @@ If we set `expires` to a date in the past, the cookie is deleted. - **`max-age=3600`** -An alternative to `expires`, specifies the cookie expiration in seconds from the current moment. +Is an alternative to `expires` and specifies the cookie's expiration in seconds from the current moment. -If zero or negative, then the cookie is deleted: +If set to zero or a negative value, the cookie is deleted: ```js -// cookie will die +1 hour from now +// cookie will die in +1 hour from now document.cookie = "user=John; max-age=3600"; // delete cookie (let it expire right now) @@ -174,11 +174,11 @@ The cookie should be transferred only over HTTPS. That is, cookies are domain-based, they do not distinguish between the protocols. -With this option, if a cookie is set by `https://site.com`, then it doesn't appear when the same site is accessed by HTTP, as `http://site.com`. So if a cookie has sensitive content that should never be sent over unencrypted HTTP, then the flag is the right thing. +With this option, if a cookie is set by `https://site.com`, then it doesn't appear when the same site is accessed by HTTP, as `http://site.com`. So if a cookie has sensitive content that should never be sent over unencrypted HTTP, the `secure` flag is the right thing. ```js // assuming we're on https:// now -// set the cookie secure (only accessible if over HTTPS) +// set the cookie to be secure (only accessible over HTTPS) document.cookie = "user=John; secure"; ``` @@ -198,11 +198,11 @@ The browser sends cookies every time you visit the site `bank.com`, even if the ![](cookie-xsrf.svg) -That's called a "Cross-Site Request Forgery" (in short, XSRF) attack. +That's a so-called "Cross-Site Request Forgery" (in short, XSRF) attack. -Real banks are protected from it of course. All forms generated by `bank.com` have a special field, so called "XSRF protection token", that an evil page can't generate or extract from a remote page (it can submit a form there, but can't get the data back). And the site `bank.com` checks for such token in every form it receives. +Real banks are protected from it of course. All forms generated by `bank.com` have a special field, a so-called "XSRF protection token", that an evil page can't generate or extract from a remote page. It can submit a form there, but can't get the data back. Additionally, the site `bank.com` checks for such token in every form it receives. -But such protection takes time to implement: we need to ensure that every form has the token field, and we must also check all requests. +Such a protection takes time to implement though. We need to ensure that every form has the required token field, and we must also check all requests. ### Enter cookie samesite option @@ -216,7 +216,7 @@ A cookie with `samesite=strict` is never sent if the user comes from outside the In other words, whether a user follows a link from their mail or submits a form from `evil.com`, or does any operation that originates from another domain, the cookie is not sent. -If authentication cookies have `samesite` option, then XSRF attack has no chances to succeed, because a submission from `evil.com` comes without cookies. So `bank.com` will not recognize the user and will not proceed with the payment. +If authentication cookies have the `samesite` option, then a XSRF attack has no chances to succeed, because a submission from `evil.com` comes without cookies. So `bank.com` will not recognize the user and will not proceed with the payment. The protection is quite reliable. Only operations that come from `bank.com` will send the `samesite` cookie, e.g. a form submission from another page at `bank.com`. @@ -224,11 +224,11 @@ Although, there's a small inconvenience. When a user follows a legitimate link to `bank.com`, like from their own notes, they'll be surprised that `bank.com` does not recognize them. Indeed, `samesite=strict` cookies are not sent in that case. -We could work around that by using two cookies: one for "general recognition", only for the purposes of saying: "Hello, John", and the other one for data-changing operations with `samesite=strict`. Then a person coming from outside of the site will see a welcome, but payments must be initiated from the bank website, for the second cookie to be sent. +We could work around that by using two cookies: one for "general recognition", only for the purposes of saying: "Hello, John", and the other one for data-changing operations with `samesite=strict`. Then, a person coming from outside of the site will see a welcome, but payments must be initiated from the bank's website, for the second cookie to be sent. - **`samesite=lax`** -A more relaxed approach that also protects from XSRF and doesn't break user experience. +A more relaxed approach that also protects from XSRF and doesn't break the user experience. Lax mode, just like `strict`, forbids the browser to send cookies when coming from outside the site, but adds an exception. @@ -237,13 +237,13 @@ A `samesite=lax` cookie is sent if both of these conditions are true: The full list of safe HTTP methods is in the [RFC7231 specification](https://tools.ietf.org/html/rfc7231). Basically, these are the methods that should be used for reading, but not writing the data. They must not perform any data-changing operations. Following a link is always GET, the safe method. -2. The operation performs top-level navigation (changes URL in the browser address bar). +2. The operation performs a top-level navigation (changes URL in the browser address bar). That's usually true, but if the navigation is performed in an `