Chrome Extension Cookies API: Read, Write, and Manage Browser Cookies

20 min read

Chrome Extension Cookies API: Read, Write, and Manage Browser Cookies

Chrome Extension Cookies API: Read, Write, and Manage Browser Cookies

Browser cookies are the backbone of modern web functionality, enabling everything from session persistence to personalized user experiences. For Chrome extension developers, understanding how to interact with cookies through the Chrome Extension Cookies API is essential for building powerful browser extensions that can manage user sessions, implement authentication flows, and create sophisticated cookie management tools.

This comprehensive guide walks you through every aspect of the Chrome Cookies API, from basic operations like reading and writing cookies to advanced techniques for managing cookie permissions, handling cross-site cookies, and building a complete cookie manager extension. Whether you are a beginner looking to understand cookie fundamentals or an experienced developer seeking to implement advanced cookie management features, this guide has you covered.


Understanding the Chrome Cookies API

The Chrome Cookies API, accessible through the chrome.cookies namespace, provides extension developers with comprehensive functionality to read, write, and delete browser cookies. This API is one of the most powerful features available to Chrome extension developers, enabling the creation of sophisticated tools for session management, authentication automation, and privacy control.

Before diving into implementation, it is important to understand the architecture of cookies in Chrome. Cookies are small pieces of data stored by websites in your browser to remember information between visits. They come in two primary flavors: first-party cookies, which are set by the website you are currently visiting, and third-party cookies, which are set by embedded resources from other domains. The Chrome Cookies API allows you to interact with both types, though you will need appropriate permissions to do so.

The API follows a consistent pattern common to Chrome extension APIs, using promises for asynchronous operations and providing detailed error handling. Each cookie operation returns specific information about the cookie being manipulated, including its name, value, domain, path, expiration date, and various security attributes like the Secure and HttpOnly flags.

To use the Chrome Cookies API, you must declare the appropriate permissions in your extension’s manifest file. The most common permission is simply “cookies”, which grants access to cookies for all URLs. However, for more granular control and to avoid triggering unnecessary permission warnings, you can specify specific host permissions.

Here is how to configure your manifest.json for cookie access:

{
  "name": "My Cookie Extension",
  "version": "1.0",
  "permissions": [
    "cookies"
  ],
  "host_permissions": [
    "*://*.example.com/*"
  ]
}

The host permissions are particularly important because Chrome’s cookie model has evolved to emphasize privacy. Starting with Chrome 80 and later versions, third-party cookies are being phased out, and the SameSite attribute behavior has changed. Understanding these changes is crucial for building extensions that work correctly with modern cookie policies.


Reading Cookies with the Chrome Cookies API

Reading cookies is the most common operation when working with the Chrome Cookies API. The chrome.cookies.get() method allows you to retrieve a specific cookie by name for a given URL, while chrome.cookies.getAll() enables retrieving multiple cookies based on filtering criteria.

The chrome.cookies.get() method requires a URL and a cookie name, returning a Promise that resolves to a Cookie object or null if the cookie does not exist:

chrome.cookies.get({ url: "https://example.com", name: "session_id" })
  .then(cookie => {
    if (cookie) {
      console.log("Cookie value:", cookie.value);
      console.log("Domain:", cookie.domain);
      console.log("Secure:", cookie.secure);
      console.log("HttpOnly:", cookie.httpOnly);
    } else {
      console.log("Cookie not found");
    }
  })
  .catch(error => {
    console.error("Error getting cookie:", error);
  });

The URL parameter is crucial because cookies are scoped to specific domains and paths. The method uses the URL to determine which cookies to consider, taking into account domain matching rules and path matching. This approach ensures that you can correctly retrieve cookies even when dealing with complex domain structures like subdomains.

Getting Multiple Cookies

For scenarios where you need to retrieve all cookies matching certain criteria, the chrome.cookies.getAll() method provides powerful filtering capabilities:

// Get all cookies for a specific domain
chrome.cookies.getAll({ domain: ".example.com" })
  .then(cookies => {
    cookies.forEach(cookie => {
      console.log(`${cookie.name}: ${cookie.value}`);
    });
  });

// Get all session cookies
chrome.cookies.getAll({ session: true })
  .then(cookies => {
    console.log(`Found ${cookies.length} session cookies`);
  });

// Get all cookies for the current tab
chrome.cookies.getAll({ url: window.location.href })
  .then(cookies => {
    cookies.forEach(cookie => {
      console.log(cookie.name);
    });
  });

The filtering options are extensive, allowing you to filter by domain, name, path, secure flag, session flag, and URL. This flexibility makes it easy to implement features like cookie export, cookie analysis, and session management.

Each cookie returned by the Chrome Cookies API contains a wealth of information organized into a structured object:

  • name: The cookie’s name as a string
  • value: The cookie’s value as a string
  • domain: The domain associated with the cookie
  • hostOnly: Boolean indicating if the cookie is host-only
  • path: The cookie’s path
  • secure: Boolean indicating if the cookie requires HTTPS
  • httpOnly: Boolean indicating if the cookie is inaccessible to JavaScript
  • session: Boolean indicating if this is a session cookie
  • expirationDate: Unix timestamp of the cookie’s expiration (for persistent cookies)
  • sameSite: The SameSite attribute value (“strict”, “lax”, or “none”)

Understanding these attributes is essential for properly managing cookies and implementing features that respect cookie security settings.


Writing and Setting Cookies

Creating new cookies or updating existing ones is accomplished through the chrome.cookies.set() method. This powerful method accepts a details object containing all the parameters needed to create a cookie with precise control over its behavior.

Here is how to create a basic cookie:

chrome.cookies.set({
  url: "https://example.com",
  name: "user_preference",
  value: "dark_mode",
  domain: ".example.com",
  path: "/",
  secure: true,
  httpOnly: false,
  sameSite: "lax"
})
  .then(cookie => {
    if (cookie) {
      console.log("Cookie created successfully");
      console.log("Name:", cookie.name);
      console.log("Value:", cookie.value);
      console.log("Domain:", cookie.domain);
    } else {
      console.log("Failed to create cookie");
    }
  })
  .catch(error => {
    console.error("Error creating cookie:", error);
  });

The method returns the newly created cookie object if successful, or null if the cookie could not be set. Common reasons for failure include invalid URL formats, permission issues, or conflicts with existing cookie settings.

Setting Session Cookies

Session cookies are temporary cookies that are deleted when the browser closes. These are the most common type of cookie for maintaining login sessions and user preferences during a browsing session:

chrome.cookies.set({
  url: "https://example.com",
  name: "session_token",
  value: "abc123xyz",
  domain: ".example.com",
  path: "/",
  secure: true,
  httpOnly: true,
  sameSite: "strict"
  // No expirationDate means this is a session cookie
})
  .then(cookie => console.log("Session cookie created:", cookie));

The httpOnly flag is particularly important for security, as it prevents JavaScript from accessing the cookie, protecting it from cross-site scripting attacks. Similarly, the secure flag ensures the cookie is only transmitted over HTTPS connections.

Setting Persistent Cookies

Persistent cookies remain stored after the browser closes and are automatically deleted after their expiration date:

const expirationDate = new Date();
expirationDate.setDate(expirationDate.getDate() + 30); // 30 days from now

chrome.cookies.set({
  url: "https://example.com",
  name: "remember_me",
  value: "true",
  domain: ".example.com",
  path: "/",
  secure: true,
  httpOnly: true,
  sameSite: "lax",
  expirationDate: expirationDate.getTime() / 1000
})
  .then(cookie => {
    console.log("Persistent cookie will expire on:", 
      new Date(cookie.expirationDate * 1000));
  });

The expirationDate parameter expects a Unix timestamp in seconds, not milliseconds. This is an important detail to remember, as it is a common source of bugs when setting cookie expiration dates.


Deleting and Managing Cookies

Cookie deletion is as important as creation, especially when building privacy-focused extensions or implementing logout functionality. The Chrome Cookies API provides methods for both removing individual cookies and clearing all cookies for specific domains.

To delete a specific cookie, use the chrome.cookies.remove() method:

chrome.cookies.remove({
  url: "https://example.com",
  name: "session_token"
})
  .then(details => {
    if (details) {
      console.log("Cookie removed:", details.name);
    } else {
      console.log("Cookie not found or could not be removed");
    }
  });

The method returns the details of the removed cookie if successful, or null if no matching cookie was found. The URL parameter is required and must match the URL used when the cookie was set.

For scenarios requiring bulk cookie management, such as clearing all cookies for a domain or removing all session cookies, you can combine the getAll and remove methods:

// Clear all cookies for a domain
chrome.cookies.getAll({ domain: ".example.com" })
  .then(cookies => {
    const promises = cookies.map(cookie => 
      chrome.cookies.remove({
        url: `https://${cookie.domain.replace(/^\./, '')}${cookie.path}`,
        name: cookie.name
      })
    );
    return Promise.all(promises);
  })
  .then(results => {
    console.log(`Deleted ${results.length} cookies`);
  });

// Remove all session cookies
chrome.cookies.getAll({ session: true })
  .then(cookies => {
    cookies.forEach(cookie => {
      chrome.cookies.remove({
        url: `https://${cookie.domain.replace(/^\./, '')}${cookie.path}`,
        name: cookie.name
      });
    });
  });

Advanced Cookie API Features

Beyond the basic CRUD operations, the Chrome Cookies API provides additional features for monitoring cookie changes and handling cookie conflicts.

The chrome.cookies.onChanged event allows your extension to react to any modifications to the cookie store:

chrome.cookies.onChanged.addListener((changeInfo) => {
  console.log("Cookie changed:", changeInfo.cause);
  console.log("Cookie details:", changeInfo.cookie);
  console.log("Removed:", changeInfo.removed);

  if (changeInfo.cause === "expire") {
    console.log(`Cookie "${changeInfo.cookie.name}" has expired`);
  } else if (changeInfo.cause === "explicit") {
    console.log(`Cookie "${changeInfo.cookie.name}" was ${changeInfo.removed ? 'removed' : 'set'}`);
  }
});

This event is invaluable for building real-time cookie monitors, tracking user session changes, or implementing features that need to respond to cookie modifications by other extensions or scripts.

The cause property in the changeInfo object provides context about why a cookie change occurred:

  • explicit: The cookie was set or removed by a script or extension
  • expire: The cookie was automatically removed due to expiration
  • evict: The cookie was removed to make room for other cookies
  • expired_overwrite: The cookie was overwritten by a cookie with an already-expired expiration date
  • charset_override: The cookie was set with a different charset than the original
  • secure_force: A secure cookie was set from an insecure origin

Understanding these causes helps you build more intelligent cookie management features that respond appropriately to different types of cookie changes.


Now that you understand the fundamentals, let us build a practical cookie manager extension that demonstrates these concepts in action.

Manifest Configuration

First, set up your manifest.json with the necessary permissions:

{
  "manifest_version": 3,
  "name": "Cookie Manager Pro",
  "version": "1.0",
  "description": "A powerful cookie management extension",
  "permissions": [
    "cookies",
    "storage"
  ],
  "host_permissions": [
    "<all_urls>"
  ],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  }
}

Create a popup.html that displays cookies for the current domain:

<!DOCTYPE html>
<html>
<head>
  <title>Cookie Manager</title>
  <style>
    body { width: 350px; font-family: Arial, sans-serif; padding: 10px; }
    h2 { margin-top: 0; }
    .cookie-list { max-height: 300px; overflow-y: auto; }
    .cookie-item { 
      padding: 8px; 
      border-bottom: 1px solid #eee; 
      font-size: 12px;
    }
    .cookie-name { font-weight: bold; }
    .cookie-value { color: #666; word-break: break-all; }
    button { margin: 5px 0; padding: 5px 10px; }
  </style>
</head>
<body>
  <h2>Cookie Manager</h2>
  <div id="current-url"></div>
  <button id="refresh-btn">Refresh</button>
  <button id="clear-session-btn">Clear Session Cookies</button>
  <div class="cookie-list" id="cookie-list"></div>
  <script src="popup.js"></script>
</body>
</html>

Implement the popup.js to handle cookie operations:

document.addEventListener('DOMContentLoaded', async () => {
  const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
  const url = new URL(tab.url);
  
  document.getElementById('current-url').textContent = url.hostname;
  
  loadCookies(url.href);

  document.getElementById('refresh-btn').addEventListener('click', () => {
    loadCookies(url.href);
  });

  document.getElementById('clear-session-btn').addEventListener('click', async () => {
    const cookies = await chrome.cookies.getAll({ url: url.href, session: true });
    for (const cookie of cookies) {
      await chrome.cookies.remove({
        url: url.href,
        name: cookie.name
      });
    }
    loadCookies(url.href);
  });
});

async function loadCookies(url) {
  const cookies = await chrome.cookies.getAll({ url });
  const list = document.getElementById('cookie-list');
  list.innerHTML = '';

  if (cookies.length === 0) {
    list.innerHTML = '<p>No cookies found for this site.</p>';
    return;
  }

  cookies.forEach(cookie => {
    const item = document.createElement('div');
    item.className = 'cookie-item';
    item.innerHTML = `
      <div class="cookie-name">${escapeHtml(cookie.name)}</div>
      <div class="cookie-value">${escapeHtml(cookie.value)}</div>
      <div class="cookie-info">
        Secure: ${cookie.secure} | HttpOnly: ${cookie.httpOnly} | 
        SameSite: ${cookie.sameSite}
      </div>
    `;
    list.appendChild(item);
  });
}

function escapeHtml(text) {
  const div = document.createElement('div');
  div.textContent = text;
  return div.innerHTML;
}

This basic implementation provides a foundation for building more sophisticated cookie management features, including cookie editing, export functionality, and advanced filtering.


Best Practices and Security Considerations

When working with the Chrome Cookies API, following best practices ensures your extension is secure, performant, and respects user privacy.

Permission Minimization

Only request the cookie permissions your extension actually needs. Using specific host permissions rather than broad permissions reduces permission warnings and improves user trust. For example, if your extension only works with a specific website, limit your host permissions to that domain:

{
  "permissions": ["cookies"],
  "host_permissions": ["*://*.mysite.com/*"]
}

Always respect cookie security attributes. When setting cookies, use appropriate flags:

  • Secure: Set to true for cookies that should only be transmitted over HTTPS
  • HttpOnly: Set to true to prevent JavaScript access, protecting against XSS
  • SameSite: Use “strict” or “lax” to prevent CSRF attacks (avoid “none” unless necessary)

User Privacy

Cookie extensions have access to sensitive user data. Always:

  • Be transparent about what data you collect and why
  • Provide users with control over cookie management
  • Never exfiltrate cookie data without explicit user consent
  • Implement proper data retention policies

Error Handling

Cookie operations can fail for various reasons. Always implement proper error handling:

async function safeCookieSet(details) {
  try {
    const cookie = await chrome.cookies.set(details);
    if (!cookie) {
      console.warn("Cookie could not be set. This might be due to blocking policies.");
    }
    return cookie;
  } catch (error) {
    console.error("Failed to set cookie:", error);
    throw error;
  }
}

Troubleshooting Common Issues

Even with proper implementation, you may encounter issues when working with the Chrome Cookies API. Here are solutions to common problems.

If chrome.cookies.get() returns null when you expect a cookie to exist:

  • Verify the URL matches exactly (including protocol and port)
  • Check if the cookie is set on a parent domain (use the domain without leading dot)
  • Ensure the cookie has not expired
  • Confirm the path matches the cookie’s scope

Permission Denied Errors

If you receive permission errors:

  • Check that the appropriate host permissions are declared
  • Verify the URL uses the correct protocol (http or https)
  • For cross-site cookies, ensure you have permission for both the source and destination domains

Cookies Not Persisting

If cookies are not being saved:

  • Verify you are not using Incognito mode without proper permissions
  • Check if the cookie’s expiration date is set correctly
  • Ensure the domain is valid and accessible
  • Check if third-party cookie blocking is enabled in Chrome settings

Conclusion

The Chrome Extension Cookies API provides powerful capabilities for managing browser cookies, enabling developers to create sophisticated tools for session management, authentication, and privacy control. By mastering the concepts covered in this guide—reading, writing, and deleting cookies, listening for changes, and implementing proper security practices—you can build robust cookie management extensions that enhance user productivity and privacy.

Remember to always prioritize user privacy, minimize permissions, and follow security best practices when working with sensitive cookie data. With these foundations in place, you are well-equipped to create professional-grade Chrome extensions that effectively manage browser cookies.

For more information on Chrome extension development and to explore additional APIs, continue learning with our other tutorials on the Chrome Extension Guide.

No previous article
No next article