Secure Cookies and HTTPOnly Attributes for Better Security
Spot abnormal user behaviors and iron out the bugs early with OpenReplay. Dive into session replays and reinforce your front-end against vulnerabilities that hackers search for.
Discover how at OpenReplay.com.
Cookies are considered a significant fraction of web development as they store information on the client side, including application sessions, preferences, and other important information. There are numerous benefits to using cookies, but if they are not handled appropriately, they can be exposed to several threats in terms of security. In web application development, security is crucial, and an insecure cookie can compromise an entire application. For instance, a cookie can be targeted and attacked, resulting in session jacking, Cross-Site Scripting (XSS) attacks, and other malicious activities. This is why putting several things in place is desirable to protect cookies adequately. The HTTPOnly
and Secure
attributes are perfect measures that you can use to help protect cookies. In this article, we’ll guide you through both attributes, i.e., what each one is, how they work, and the details behind their setup.
What are Secure
Cookies?
Cookies that are transmitted only over an encrypted HTTPS connection are called secure
cookies. This attribute assists in ensuring that the data stored in a cookie is not exposed while the cookies are in transit. The Secure
cookie attribute functions by making sure that the cookies are only transmitted during an HTTPS connection. When a cookie is sent over HTTP, attackers can easily capture such cookies, especially through man-in-the-middle (MITM) attacks.
HTTPS provides a way to transfer data between a client and the server, including cookies, which will be labeled Secure
. This encryption also means that a third party can’t try and intercept a cookie and steal data. For example, here’s how a Secure
cookie can be set in an HTTP header:
Set-Cookie: sessionId=abc123; Secure; Path=/; HttpOnly
In the example above, the Set-Cookie: sessionId=abc123
sets a cookie named sessionId
with the value abc123
. In the response header, the cookie is set as Secure
and HttpOnly
, presenting users with a double safety net.
What is the HTTPOnly
Attribute?
HTTPOnly
is a type of attribute that operates by denying the client’s side scripts (such as the Javascript) access to cookies. If you apply this attribute to a cookie, it becomes a server-side cookie and is not accessible through other client-side scripts. This security aspect of the attribute prevents malicious scripts (popularly known as cross-site scripting) from accessing cookies that contain sensitive data.
That means that if a cookie isn’t protected with the HTTPOnly
attribute, it will certainly experience attacks that enable JavaScript to gain access to the cookies, read the contents, and then transfer the details to a specific remote server commonly employed by attackers. This means that a user’s session can be intercepted and then imitated by the mentioned user. Here’s a code example of how a cookie can be set with the HTTPOnly
attribute in the HTTP response header:
Set-Cookie: sessionId=abc123; HttpOnly; Path=/
In the example above, the server returns to the browser a Set-Cookie
header of the form shown above. The browser guarantees that the information is stored on the client’s side, but it is not accessible through client-side scripts.
Benefits of Using Secure
and HTTPOnly
Cookies
By now, you must have realized how securing your cookies aids in protecting privacy, data integrity, and user safety. In this section, we will describe the detailed benefits of applying the Secure
and HTTPOnly
attributes.
Preventing Cookie Theft Via Man-in-the-Middle Attacks (Secure
Attribute)
We had already discussed how the Secure
attribute aids in shielding cookies from unnecessary exposure while in transit. This attribute tags your cookies and only transmits them over HTTPS to stop them from being passed over insecure HTTP connections. Data transferred through HTTP is not encrypted. Thus, it is open to attacks, and data in cookies may be stolen this way, resulting in a hijack of the user’s session. The attribute is particularly important in the prevention of man-in-the-middle attacks. Thus, making this attribute is crucial if you expect to deal with sensitive information like tokens, payment details, or user preferences within your web application.
Mitigating Cross-Site Scripting (XSS) Risks (HTTPOnly
Attribute)
The HTTPOnly
attribute ensures that cookies are safe from being controlled by client-side scripts through Javascript. This restricts the cookies to the client end, which minimizes vulnerability to cross-site scripting, where a criminal injects scripts within a legitimate website to compromise information. Cross-site scripting vulnerabilities enable an attacker to execute any script on the victim’s browser. Since Javascript has access to cookies, an attacker can lure victims into visiting compromised links. The HTTPOnly
attribute remains an intermediary, as a bodyguard helping to ensure that a cookie will not go through to the client side even when an attacker uses the document.cookie
path to grab the cookie. This is very helpful in cases where a user input is usually reflected on a page, for instance in the comments section or form submission. Here, the HTTPOnly
attribute guarantees essential session management to remain safe even in the presence of XSS exploits.
Enhancing Overall Data Confidentiality and Integrity
By now, it is known that applying Secure
and HTTPOnly
attributes adequately protects your cookies against several kinds of attacks. This protection increases the confidentiality and integrity of a user’s data.
- Confidentiality: When a user’s data is well managed in terms of privacy, confidentiality is kept at its highest level. The
Secure
attribute plays a role here, ensuring that cookies that comprise sensitive information are only transmitted over secure channels.
Integrity: Data integrity occurs when a user’s data is not easily accessible. The HTTPOnly
attribute can be useful in increasing integrity since cookies cannot be read or modified by scripts from unauthorized parties.
A cookie with the Secure
and HTTPOnly
flags is protected at transit and from client-side attacks. Both attributes combine to meet the requirements of web security standards and compliance, especially with privacy regulations. Many security auditors will surely require the use of those two attributes to protect sensitive cookies.
How to Implement Secure
and HTTPOnly
Attributes
Using both Secure
and HTTPOnly
is the best way to go when embarking on the process of cookie protection. In this section, we are going to help you understand how you can set up your cookies using Express.js, as well as the best practices to follow to properly set up the cookies.
Example Code for Setting Secure
and HTTPOnly
Cookies in Express.js.
Here, you can set cookies very easily using the res.cookie()
method. The below is a simple example of where the secure
and HTTPOnly
attributes were set on a session cookie.
const express = require("express");
const app = express();
app.get("/login", (req, res) => {
// Set a session cookie with both Secure and HTTPOnly attributes
res.cookie("sessionId", "abc123", {
httpOnly: true, // Prevents access via JavaScript
secure: true, // Ensures cookie is sent over HTTPS
maxAge: 3600000, // Cookie expires in 1 hour (3600000 ms)
sameSite: "Strict", // Helps prevent CSRF attacks
path: "/", // Cookie is valid for the entire domain
});
res.send("Secure and HTTPOnly cookie has been set");
});
app.listen(3000, () => {
console.log("Server running on port 3000");
});
From the above:
res.cookie(‘sessionId’, ‘abc123’)
assigns a value ofabc123
to thesessionId
cookie. It can also stand for a session ID that is used to maintain an active logged user session.httpOnly: true
Keeps the cookie safe against XSS attacks, especially through Javascript.secure: true
guarantees that the code is only transmitted over HTTPS.maxAge: 3600000
is used to set the expiration time of the cookie, which is one hour (3600000 milliseconds). Beyond the time frame, the browser deletes the cookie.sameSite: ‘Strict’
is another segment of defense against Cross-site Request Forgery (CSRF), which works by giving restrictions to how cookies are sent with cross-site requests.Strict
makes sure the cookie goes to the domain that it was set for.Path: ‘/’
specifies that the cookie will be valid on all directories on the domain.
And so, once you have set up a cookie like the one above, you have aptly protected it against the various vulnerabilities.
Best Practices for Implementation
When you are attempting to secure your cookies with the help of the Secure
and HTTPOnly
attributes, there are several things to remember when it comes to their usage.
- Use secure cookies in production: After creating and setting up your cookies, double-check to ensure the
Secure
attribute is set in a production environment where HTTPS is available. If your cookies are sent over the HTTP channel, they are still open to attack. To do this, you can useprocess.env.NODE_ENV
to check the environment. Next, the cookies should only passed over secure connections using settings likesecure: true
in production andsecure: false
in development. Here’s a code example:
const isProduction = process.env.NODE_ENV === "production";
app.get("/login", (req, res) => {
res.cookie("sessionId", "abc123", {
httpOnly: true,
secure: isProduction, // Secure in production, not in dev
});
res.send("Cookie set");
});
- Combine
HTTPOnly
,Secure
, andSameSite
attributes: To optimize the results of your cookie security, it is encouraged to go with a combination of both attributes (Secure
andHTTPOnly
) withSameSite
because it helps to minimize CSRF incidences. Here’s how you combine these attributes:
res.cookie("sessionId", "abc123", {
httpOnly: true,
secure: true,
sameSite: "Strict", // Protects from CSRF attacks
});
- Set an appropriate expiration: You should set a lifespan for sensitive cookies using
maxAge
orExpires
. This prevents any cookie from being stored on the client side permanently. When a cookie has a short span, stolen cookies lose their efficacy. Here’s an example of setting an appropriate expiration time usingmaxAge
:
res.cookie("sessionId", "abc123", {
httpOnly: true,
secure: true,
maxAge: 600000, // Expires in 10 minutes (600,000 milliseconds)
});
- Use additional security headers: Both attributes give you a reasonable amount of protection, but it is also suggested that you use other security headers such as
Content-Security-Policy
(CSP) to further protect you against XSS attacks. You can set CSP to control contents (e.g, scripts) allowed to load on your site like the below example in Express.js:
app.use((req, res, next) => {
res.setHeader("Content-Security-Policy", "script-src 'self'");
next();
});
By following the above, you should be able to protect your cookies against common security threats. This protection makes your web apps more secure and private, as well as providing your data with improved confidentiality and integrity.
Conclusion
Secure
and HTTPOnly
attributes are a crucial response to increasing the security of web apps. The Secure
attribute allows your cookies to be only transmitted when the connection is encrypted through HTTPS, while the HTTPOnly
attribute prevents cookies from being accessed through scripts. Combined, these attributes protect your cookies, particularly those that hold precious and sensitive data. In this article, we have explained all that you need to know concerning these attributes, how to configure them, and the practices that you need to keep in mind to get the best out of them. If your web applications are to deal with client’s sensitive information, then the practices outlined in the article should be the standard for you.
Secure Your Front-End: Detect, Fix, and Fortify
Spot abnormal user behaviors and iron out the bugs early with OpenReplay. Dive into session replays and reinforce your front-end against vulnerabilities that hackers search for.