How do websites keep you logged in - javascript

Quick Question: When you login to your account on a website what does it do to keep you logged in so you don't login again and again when you visit another page?

Cookies and Session are some of the traditional ways that authentication details are stored in browser. However through these approaches server has to keep track of logged in users and their cookies to validate. So there is some server operation in managing logged in users. However there's a new approach known as JSON Web Token aka JWT. Here server will generate an user specific token and sends into browser client on logging moment. Browser will store this token in HTML5 Local Storage or Session Storage and will be sending this token with every request! So here for every refresh browser code can check for the availability of this token in Local Storage or Session Storage. Advantage of this approach is that the server doesn't have to keep track of issued token and is able to extract data from token if needed. This JWT is widely used in authenticating Web applications developed using advanced Javascript frameworks : Angularjs or Reactjs(with supporting libraries)

Browsers will keep you logged in by using some sort of browser storage. (for example cookies or localStorage or...). This data is called session data.
Html pages are stateless, that means when you refresh a page, all data that came from the server previously, are removed, and have to be requested again.
Now to request a protected page, there has to be a way to tell the server that you are the user that is logged-in a few minutes ago! This is done by storing some encrypted data in browser, usually in cookies.
Browsers are designed in a way that automatically send a specific page's all cookies to server when the page is opened. Server has the exact encrypted data in files or database and compares it with browsers data. if they match, server will allow protected content to get viewed by user, so will send the requested content as response.
you can simply test this by clearing your browser cache after login and then refresh, you will see that you are logged out, and not allowed to see protected page.

It is all about sessions.
Source
In computer science, in particular networking, a session is a
semi-permanent interactive information interchange, also known as a
dialogue, a conversation or a meeting, between two or more
communicating devices, or between a computer and user
Web server session management
...
Hypertext Transfer Protocol (HTTP) is stateless: a client computer
running a web browser must establish a new Transmission Control
Protocol (TCP) network connection to the web server with each new HTTP
GET or POST request. The web server, therefore, cannot rely on an
established TCP network connection for longer than a single HTTP GET
or POST operation. Session management is the technique used by the web
developer to make the stateless HTTP protocol support session state.
For example, once a user has been authenticated to the web server, the
user's next HTTP request (GET or POST) should not cause the web server
to ask for the user's account and password again. For a discussion of
the methods used to accomplish this see HTTP cookie and Session ID
In situations where multiple web servers must share knowledge of
session state (as is typical in a cluster environment) session
information must be shared between the cluster nodes that are running
web server software. Methods for sharing session state between nodes
in a cluster include: multicasting session information to member nodes
(see JGroups for one example of this technique), sharing session
information with a partner node using distributed shared memory or
memory virtualization, sharing session information between nodes using
network sockets, storing session information on a shared file system
such as a distributed file system or a global file system, or storing
the session information outside the cluster in a database.
If session information is considered transient, volatile data that is
not required for non-repudiation of transactions and does not contain
data that is subject to compliance auditing then any method of storing session information
can be used. However, if session information is subject to audit
compliance, consideration should be given to the method used for
session storage, replication, and clustering.
In a service-oriented architecture, Simple Object Access Protocol or
SOAP messages constructed with Extensible Markup Language (XML)
messages can be used by consumer applications to cause web servers to
create sessions.
In raw php (most well known frameworks has session management middleware, so you shouldn't worry about it) if you want to manage a session, you have to include
session_start();
procedure on top of your pages. When you do this, you are creating a 24 minutes (1440 seconds) session (by default).
You can modify it to any integer from your php.ini file.
All session data in php stored in $_SESSION global. Hence, it is an array, so you can set session variables (aanything you want) like,
$_SESSION['user_name'] = 'ernesto';
$_SESSION['foo'] = 'bar';
...
At any time of your application, you can remove $_SESSION variables,
session_unset();
Assume, you've already set variables above,
print_r($_SESSION);
will print empty array as you've removed variables by unset procedure.
If you want completely to destroy a session,
session_destroy();
will do it for you.

use cookie you can learn: Cookie or Session you can learn Session

Related

Is it dangerous using HTTP Basic Authentication and storing usename/password in local storage for future requests? (without XSS)

I'm developing an app in React and Spring Boot + Spring Security. Right now, I've added HTTP Basic Auth for user authentication. The user inputs username and password in a login form, and I send them (of course over HTTPS) to my backend. If the user is authenticated, I send back success, and the frontend saves the credentials into local storage for future requests (i.e. no session server-side). Then whenever I navigate to a "secured" route in React, I check the local storage, and then use the credentials for my secured requests. When the user needs to logout, the app removes the credentials from local storage.
It's a very trivial security implementation, but unless I have XSS vulnerability, or there is downgrade to HTTP (for my domain, not possible - HSTS preloading), I don't think it's vulnerable. But the main problem I see with it is that I can't for example logout users remotely, which might come in handy at some point. Have I found myself in a dead-end? Is HTTP Basic Auth just not meant for stateless authentication with SPAs?
First, I would suggest not doing that. As you said, a downgrade to HTTP will expose credentials and a XSS vulnerability will make it possible for the attacker to steal the credentials of your users.
However, if you insist to store credentials in localStorage then you should ensure several things:
Credentials should be encrypted in localStorage, and your application (server side) will decrypt them and only then "use the credentials for your secured requests".
This way, a downgrade to HTTP will expose the traffic but the credentials are transferred after encryption.
Be extra-sensitive for XSS vulnerabilities and sanitize any user input (best practice regardless, but now the stakes are high). Stealing a session is different from stealing users' credentials where an attacker can steal all of your users' passwords over time, and execute a massive attack coming as legitimate requests from your users. This is in contrast to sessions with a timeout.
The localStorage is only accessible via scripts coming in through your own domain, so you're safe as long as the only frontend code running is your own.
But if any other code is executed, via injection or if you share the domain with someone else, they will be able to access the localStorage data.
For the second part of your question, logging out users remotely. You can implement it in a different way:
Upon a successful login, generate a completely random string unrelated to user credentials and store that in the database, along with an expiry date. Then, pass that string to be stored in localStorage.
From then on, so long as that local storage credential matches the database one and the timeout has not expired, you automatically consider them logged in.
This way, there is no risk concerning the exposure of the user's credentials from localStorage. However, with this temporary unique string essentially functioning as a sessionID, you will still to need to be aware of and take precautions against the risks associated with session hijacking.
Now, to end a user's session remotely, you can update the expiry date of that entry in the DB.

Do I have to store tokens in cookies or localstorage or session?

I am using React SPA, Express, Express-session, Passport, and JWT.
I'm confused about some of the different client-side storage options to store tokens: Cookies, Session, and JWT / Passport.
Do tokens have to be stored in cookies, even if I can store them in req.sessionID?
Many websites use cookies to store shopping cart tokens. So far I have stored shopping cart data based on the session ID without adding any cookies.
So when users visit my website, I will match it with their
req.sessionID and then retrieve the data in the database like shopping carts and user session.
Do I need to store cookies? I can access it via req.sessionID to get the data needed.
And the second
I have made authentication using a passport-google-oauth20.After I successfully login, the data is saved into the session. and to send it to the client I have to send it via the URL query ?token='sdsaxas'.
in this case I get a lot of difference of opinion. someone saved it
into local storage and someone saved it into cookies by converting it to a token using JWT.
jwt.sign(
payload,
keys.jwt.secretOrPrivateKey,
{
expiresIn:keys.jwt.expiresIn // < i dont know what is this expired for cookies or localstorage ?
}, (err, token) => {
res.redirect(keys.origin.url + "?token=" + token);
});
Can I indeed store everything related to the session by using sessionID (without cookies or localstorage)?
Only by doing fetch once or every page refresh and retrieving the data and then saved into redux because I use React SPA.
This answer is based on the stateless approach and therefore it doesn't talk about the traditional session management
You have asked two altogether different questions:
Shopping cart - which is more related to business functionality
OAuth 2 & JWT - which is related to security and authentication
As a user of an ecommerce website, I'd expect that any item I add to my shopping cart from my mobile device while commuting to my workplace, should be available in the cart when I login to the website from my PC after reaching home. Therefore, the cart data should be saved in the back-end DB and linked to my user account.
When it comes to authentication using OAuth 2.0, the JWT access token and / or refresh token need to be stored somewhere in the client device, so that once the user authenticates himself by providing login credentials, he doesn't need to provide his credentials again to navigate through the website. In this context, the browser local storage, session storage and cookies are all valid options. However, note that here the cookie is not linked to any session on the server side. In other words, the cookie doesn't store any session id. The cookie is merely used as a storage for access token which is passed to the server with every http request and the server then validates the token using the digital signature to ensure that it is not tampered and it is not expired.
Although all three storage options for access and / or refresh tokens are popular, cookie seems to be the most secured option when used in the correct way.
To understand this better, I recommend you read this and this along with the OAuth 2.0 specification.
Update On 16-Feb-2019
I said earlier that cookie seems to be the most secured options. I'd like to further clarify the point here.
The reason I think browser localStorage and sessionStorage do not provide enough security for storing auth tokens are as follows:
If XSS occurs, the malicious script can easily read the tokens from there and send them to a remote server. There on-wards the remote server or attacker would have no problem in impersonating the victim user.
localStorage and sessionStorage are not shared across sub-domains. So, if we have two SPA running on different sub-domains, we won't get the SSO functionality because the token stored by one app won't be available to the other app within the organization. There are some solutions using iframe, but those look more like workarounds rather than a good solution. And when the response header X-Frame-Options is used to avoid clickjacking attacks with iframe, any solution with iframe is out of question.
These risks can, however, be mitigated by using a fingerprint (as mentioned in OWASP JWT Cheat Sheet) which again in turn requires a cookie.
The idea of fingerprint is, generate a cryptographically strong random string of bytes. The Base64 string of the raw string will then be stored in a HttpOnly, Secure, SameSite cookie with name prefix __Secure-. Proper values for Domain and Path attributes should be used as per business requirement. A SHA256 hash of the string will also be passed in a claim of JWT. Thus even if an XSS attack sends the JWT access token to an attacker controlled remote server, it cannot send the original string in cookie and as a result the server can reject the request based on the absence of the cookie. The cookie being HttpOnly cannot be read by XSS scripts.
Therefore, even when we use localStorage and sessionStorage, we have to use a cookie to make it secured. On top of that, we add the sub-domain restriction as mentioned above.
Now, the only concern about using a cookie to store JWT is, CSRF attack. Since we use SameSite cookie, CSRF is mitigated because cross-site requests (AJAX or just through hyperlinks) are not possible. If the site is used in any old browser or some other not so popular browsers that do not support SameSite cookie, we can still mitigate CSRF by additionally using a CSRF cookie with a cryptographically strong random value such that every AJAX request reads the cookie value and add the cookie value in a custom HTTP header (except GET and HEAD requests which are not supposed to do any state modifications). Since CSRF cannot read anything due to same origin policy and it is based on exploiting the unsafe HTTP methods like POST, PUT and DELETE, this CSRF cookie will mitigate the CSRF risk. This approach of using CSRF cookie is used by all modern SPA frameworks. The Angular approach is mentioned here.
Also, since the cookie is httpOnly and Secured, XSS script cannot read it. Thus XSS is also mitigated.
It may be also worth mentioning that XSS and script injection can be further mitigated by using appropriate content-security-policy response header.
Other CSRF mitigation approaches
State Variable (Auth0 uses it) - The client will generate and pass with every request a cryptographically strong random nonce which the server will echo back along with its response allowing the client to validate the nonce. It's explained in Auth0 doc.
Always check the referer header and accept requests only when referer is a trusted domain. If referer header is absent or a non-whitelisted domain, simply reject the request. When using SSL/TLS referrer is usually present. Landing pages (that is mostly informational and not containing login form or any secured content) may be little relaxed ​and allow requests with missing referer header.
TRACE HTTP method should be blocked in the server as this can be used to read the httpOnly cookie.
Also, set the header Strict-Transport-Security: max-age=; includeSubDomains​ to allow only secured connections to prevent any man-in-the-middle overwrite the CSRF cookies from a sub-domain.
LocalStorage/SessionStorage is vulnerable to XXS attacks. Access Token can be read by JavaScript.
Cookies, with httpOnly, secure and SameSite=strict flags, are more secure. Access Token and its payload can not be accessed by JavaScript.
BUT, if there is an XSS vulnerability, the attacker would be able to send requests as the authenticated user anyway because the malicious script does not need to read the cookie value, cookies could be sent by the browser automatically.
This statement is true but the risks are different.
With cookies, the access token is still hidden, attackers could only carry out “onsite” attacks. The malicious scripts injected into the web app could be limited, or it might not be very easy to change/inject more scripts. Users or web apps might need to be targeted first by attackers. These conditions limit the scale of the attack.
With localStorage, attackers can read the access token and carry out attacks remotely. They can even share the token with other attackers and cause more serious damage. If attackers manage to inject malicious scripts in CDNs, let’s say google fonts API, attackers would be able to siphon access token and URLs from all websites that use the comprised CDN, and easily find new targets. Websites that use localStorage are more easily to become targets.
For the sake of arguments
A pen-testing might flag your use of localStorage for sensitive data as a risk.
If it was ok for JavaScript to read access token from localStorage from an XSS attack, why do you think the httpOnly flag is still recommended by everyone.
Recommendation from OWASP
Do not store session identifiers in local storage as the data is always accessible by JavaScript. Cookies can mitigate this risk using the httpOnly flag.
https://medium.com/#coolgk/localstorage-vs-cookie-for-jwt-access-token-war-in-short-943fb23239ca
HTTP is a stateless protocol. Read that answer for more detail, but essentially that means that HTTP servers, such as your web server, do not store any information about clients beyond the lifetime of one request. This is a problem for web apps because it means you can't remember which user is logged in.
Cookies were invented as the solution to this. Cookies are textual data that the client and server send back and forth on every request. They allow you to effectively maintain application state data, by having the client and server agree on what they remember each time they communicate.
This means, fundamentally, you cannot have a session without a cookie. There must be a cookie that stores at least the session ID, so that you can find out which user is currently logged into your app by looking up the session. This is what express-session does: the documentation for the main session method explicitly notes that the session ID is stored in a cookie.
so my question is do I need to store cookies?because I can access it via req.sessionID to get the data needed.
You don't need to store cookies. express-session will do this for you. Your application as a whole does need to store a cookie; without it, you wouldn't have a req.sessionID to look up.
According to my experience, just store token in localStorage.
localStorage:
it can store information up tp 5MB. You do not need to ask user's permission to store token in localStorage.
The only concern is that whether the target device support localStorage api.
Check here: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
It is widely supported. But according to my experience, if you have an ios app, and there is a html page in this app which ask the user to store token (also called webview), the localStorage api cannot be recognized and throw an error.
The solution is simply i just put token in url and transfer it every time. In webview, url is not visible.
Cookie:
It is a very old style to store info locally. Storage in cookie is relatively small and you need to ask user's permission in order to store token in cookie.
Cookies are sent with every request, so they can worsen performance (especially for mobile data connections). Modern APIs for client storage are the Web storage API (localStorage and sessionStorage) and IndexedDB.
(https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies)
Do not store token in sessionStorage or redux.
Data stored in sessionStorage will be lost if the tab is closed. If a user accidentally closed a tab, the token is lost and the server will not be able to identify the current user.
Token stored in redux is not different to be stored in other js files. redux store is just another js file. information stored in redux get lost for every page refresh.
In conclusion,
most of the time, token is stored in localStorage if using a modern style. In certain scenarios, you can store token in cookie and may be put in url sometimes. But never store in session.
Hope it helps.

Where to store a JWT token properly and safely in a web based application?

I'm familiar with Web Storage APIs and cookies but I can't figure what is the most secure way to store an authentication token. I'm wondering if this might break any third-party libraries.
I'd like to have an exhaustive list of available methods to do so, with the pros and cons of each and the best way above all, if any.
Where to Store Your JWTs
With token-based authentication, you are given the choice of where to store the JWT. We strongly recommend that you store your tokens in local storage/session storage or a cookie.
Web Storage (local storage/session storage)
Commonly, the JWT is placed in the browsers local storage and this works well for most use cases.
When logging in a user with a username and password, the response body contains the access_token JWT. Then you need to handle this response in the client side code. This token can then be stored in localStorage or sessionStorage.
Click here for an example using sessionStorage
Both localStorage and sessionStorage both extend Storage. The only difference between them is the persistance of the data:
localStorage - data persists until explicitly deleted. Changes made are saved and available for all current and future visits to the site.
sessionStorage - Changes made are saved and available for the current page, as well as future visits to the site on the same window. Once the window is closed, the storage is deleted.
Web Storage Disadvantages
Unlike cookies, local storage is sandboxed to a specific domain and its data cannot be accessed by any other domain including sub-domains.
Web Storage is accessible through JavaScript on the same domain so any JavaScript running on your site will have access to web storage, and because of this can be vulnerable to cross-site scripting (XSS) attacks.
The developer must ensure that the JWT is always sent over HTTPS and never HTTP.
Using Cookies
You can also use cookies to store the JWT. The exact way to set a cookie depends on the client side language you are using.
There are different options to control the lifetime of a cookie:
Cookies can be destroyed after the browser is closed (session cookies).
Implement a server side check (typically done for you by the web framework in use), and you could implement expiration or sliding window expiration.
Cookies can be persistent (not destroyed after the browser is closed) with an expiration.
Cookies can be read by both the JavaScript and the server side code or only server side if the httpOnly flag is set.
Cookie Disadvantages
The max size of a cookie is only 4kb so that may be problematic if you have many claims attached to the token.
Cookies can be vulnerable cross-site request forgery (CSRF or XSRF) attacks. This type of attack occurs when a malicious web site causes a user’s web browser to perform an unwanted action on a trusted site where the user is currently authenticated. This is an exploit of how the browser handles cookies. Using a web app framework’s CSRF protection makes cookies a secure option for storing a JWT. CSRF can also be partially prevented by checking the HTTP Referer and Origin header.
Can be difficult to implement if the application requires cross-domain access. Cookies have additional properties (Domain/Path) that can be modified to allow you to specify where the cookie is allowed to be sent.
Original article: https://auth0.com/docs/security/store-tokens#how-to-implement
JWTs should never be stored in your localStorage
In fact, they shouldn't even be stored in your cookies, unless you are able to implement very strict CSRF protection
Checkout this for motivation
JWT as an id_token is like your user credentials
JWT as an access_token is like your session token
The most secure option is in-memory. Checkout this for a deep dive

Best practice to send auth token from one website to another?

I have one website, where a user will login to his/her account, they will then be redirected to another website where they should be logged in automatically. Both website have access to the same database. A user will get authenticated with a token, but how do I pass that along to the other website.
Depending on the server technology there are various choices.
You don't tell what platform (windows, linux) is your server on and what web server (Apache, IIS) you use, which web technology you use (ASP.NET, PHP, Ruby, node.js) or framework you use (laravel, symfony, wordpress, ruby on rails). So it's pretty difficult to be precise.
Anyways.
For example on IIS you can choose to store session state in these ways:
InProc mode, which stores session state in memory on the Web server. This is the default.
SQLServer mode stores session state in a SQL Server database. This ensures that session state is preserved if the Web application is restarted and also makes session state available to multiple Web servers in a Web farm.
more...
For Apache/PHP running on Linux you can rsync the session folder across machines, or store the session state on the database.
As a last resort you can have a protected websocket that connects the web servers and allows both to query the other about session tokens.
what should be clear is that the session ID available to the client (cookie, local storage or whatever) is NOT the session state used by the webserver. Those are two different things.
What you want is called SSO (Single Sign-On).
To be clear: you have to move information directly between the servers without the aid of the client. This is important for security reasons and should not be confused with the session ID available to the client.
Furthermore, there's the problem of cross-domain. This only applies if the domains (URLs) of the two servers are different. For security reasons you cannot send cookies of one domain to the other. Or access the local storage of another domain from a page that has been loaded on the other. In other words, when you set the session ID in a cookie or local storage under one domain, it won't be accessible on the other domain.
But there's a way around the domain boundary, shown below.
In your case the database is probably the best option. You can do as follows.
on login on either side you store the session ID and a timestamp in a SQL table that points to both user's login data (one for the first server, the other for the second -- just in case you use heterogenous web technologies such as ASP.NET and PHP);
when you redirect the client from one domain (server) to the other, you have to ensure the session ID is passed along (without cookies or local storage) -- you can do that easily by putting the session ID into the query string of the URL, such as this:
www.otherdomain.com/landing_page.html?sid=75UFNE784324jEJIRO4234782394JKR
on the landing page of the other server you can now take that session ID, query it against the SQL table and retrieve the login information for that server.
I hope this helps you out a bit, it's maybe a bit confusing because it's a generic explanation without concrete code. But with a bit of attention you should be able to do it!

What are cookies and sessions, and how do they relate to each other?

I am trying to understand cookies and sessions professionally.
I know that when a browser connects to a server, the server "asks" the browser to "paste" a cookie with "phpsessid" in the client browser cookies folder.
Now that we have the "phpsessid", if the client enters the server the browser sends to the server the "phpsessid" and the server takes a look at the tmp folder and if we have a match it loads back every data the user has for this client, but I am kinda confused with the process.
I will be thankful if some one can help me understand those processes of creating a session and cookies - what is happening behind the scenes.
Let's go through this:
Cookies and sessions are both ways to preserve the application's state between different requests the browser makes. It's thanks to them that, for instance, you don't need to log in every time you request a page on StackOverflow.
Cookies
Cookies are small bits of data, (maximum of 4KB long), which hold data in a key=value pairs:
name=value; name2=value2
These are set either by JavaScript, or via the server using an HTTP header.
Cookies have an expiry datetime set, example using HTTP headers:
Set-Cookie: name2=value2; Expires=Wed, 19 Jun 2021 10:18:14 GMT
Which would cause the browser to set a cookie named name2 with a value of value2, which would expire in about 9 years.
Cookies are considered highly insecure because the user can easily manipulate their content. That's why you should always validate cookie data. Don't assume what you get from a cookie is necessarily what you expect.
Cookies are usually used to preserve login state, where a username and a special hash are sent from the browser, and the server checks them against the database to approve access.
Cookies are also often used in sessions creation.
Sessions
Sessions are slightly different. Each user gets a session ID, which is sent back to the server for validation either by cookie or by GET variable.
Sessions are usually short-lived, which makes them ideal in saving temporary state between applications. Sessions also expire once the user closes the browser.
Sessions are considered more secure than cookies because the variables themselves are kept on the server. Here's how it works:
Server opens a session (sets a cookie via HTTP header)
Server sets a session variable.
Client changes page
Client sends all cookies, along with the session ID from step 1.
Server reads session ID from cookie.
Server matches session ID from a list in a database (or memory etc).
Server finds a match, reads variables which are now available on $_SESSION superglobal.
If PHP does not find a match, it will start a new session, and repeat the steps from 1-7.
You can store sensitive information on a session because it is kept on the server, but be aware that the session ID can still be stolen if the user, let's say, logged in over an insecure WiFi. (An attacker can sniff the cookies, and set it as its own, he won't see the variables themselves, but the server will identify the attacker as the user).
That's the gist of it. You can learn more on the PHP manual on both subjects.

Categories

Resources