Back

Secure Cookies and HTTPOnly Attributes for Better Security

Secure Cookies and HTTPOnly Attributes for Better Security

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.

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 of abc123 to the sessionId 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 use process.env.NODE_ENV to check the environment. Next, the cookies should only passed over secure connections using settings like secure: true in production and secure: 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, and SameSite attributes: To optimize the results of your cookie security, it is encouraged to go with a combination of both attributes (Secure and HTTPOnly) with SameSite 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 or Expires. 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 using maxAge:
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.

OpenReplay