Cookie and Session are to maintain session state on top of the stateless HTTP protocol, so that the server can know which client is currently dealing with. This article discusses the implementation mechanism of Cookie and Session in detail, as well as the security issues involved.
Because the HTTP protocol is stateless, that is, every time a user request arrives at the server, the HTTP server does not know who the user is, whether they have logged in, etc. The reason the server now knows if we are logged in is because the server sets the browser's cookie when logging in! Session is a session between a higher-level server and a browser implemented through cookies.
1. Cookie security risks
Cookies provide a means to attach the current status to HTTP requests. Today's websites also rely on cookies to identify the user's login status:
- The user submits a username and password form, which is usually a POST HTTP request.
- The server verifies the username and password, if it is valid, it returns 200 (OK) and sets the Set-Cookie to authed=true.
- The browser stores this cookie.
- When the browser sends a request, set
Cookie
the field to authenticated=true. - The server receives the second request and knows from the
Cookie
field that the user is logged in. This request is processed according to the permissions of the logged in user.
Where is the problem here?
We know that it is not just browsers that can send HTTP requests. Many HTTP client software (including curl and Node.js) can send arbitrary HTTP requests and set any header fields. If we directly set the Cookie
field to authed=true
and send the HTTP request, wouldn't the server be tricked? This attack is very easy, cookies can be tampered with!
2. Cookie anti-tampering mechanism
The server can generate a signature for each cookie item. Since the user cannot generate a corresponding signature after tampering with the cookie, the server can know that the user has tampered with the cookie. A simple verification process might look like this:
- Configure an unknown string (let's call it Secret) in the server, for example: x$sfz32 .
- When the server needs to set a cookie (such as authed=false), not only the set
authed
valuefalse
, but also a signature is set after the value, and the final set cookie is authed=false|6hTiBl7lVpd1P. - The signature
6hTiBl7lVpd1P
is generated like this: Hash('x$sfz32'+'false') . The value to be set is added to the Secret and then hashed. - The user receives the HTTP response and finds the header field Set-Cookie: authed=false|6hTiBl7lVpd1P .
- When the user sends an HTTP request, the
authed
value is tampered with and the header field Cookie: authed=true|??? is set. Because the user does not know the Secret, the signature cannot be generated, so he can only fill in one at random. - The server received the HTTP request and found Cookie: authed=true|??? . The server starts to verify: Hash('true'+'x$sfz32') , and it will find that the signature provided by the user is incorrect.
By adding a signature to the cookie, the server can know that the cookie has been tampered with. But the story didn't end there.
Because cookies are transmitted in clear text , as long as the server has set authed=true|xxxx once, I don't know if true
the signature is xxxx
, and I can use this signature to deceive the server in the future. Therefore, it is best not to put sensitive data in cookies. Generally speaking, only one Session Id is placed in the Cookie, and the Session is stored on the server side.
-------------------------------------------------------------------------------------------
This article is reproduced from: http://harttle.land/2015/08/10/cookie-session.html