Fix Guide

How to Fix Cookie Security Flags in WordPress

February 8, 2026

If InspectWP reports cookies without the Secure, HttpOnly, or SameSite flags, your site may be vulnerable to session hijacking, XSS-based cookie theft, or cross-site request forgery (CSRF) attacks. These three flags are the most important cookie security attributes, and they work together to protect your users' session data. Fortunately, fixing them in WordPress is straightforward once you understand what each flag does and where to apply it.

Understanding Cookie Security Flags and Their Purpose

Before applying fixes, it helps to understand what each flag protects against:

  • Secure flag: Ensures the cookie is only sent over HTTPS connections. Without this flag, a cookie can be transmitted over unencrypted HTTP, allowing an attacker on the same network (e.g., public Wi-Fi) to intercept it using a simple packet sniffer. Once they have the session cookie, they can impersonate the user. This attack is known as session hijacking or sidejacking.
  • HttpOnly flag: Prevents JavaScript from accessing the cookie via document.cookie. This is critical protection against cross-site scripting (XSS) attacks. If an attacker manages to inject malicious JavaScript into your page (through a vulnerable plugin, comment field, or user input), the HttpOnly flag prevents that script from reading session cookies and sending them to an external server.
  • SameSite flag: Controls whether the cookie is sent along with cross-site requests. This protects against CSRF attacks, where a malicious site tricks a user's browser into making authenticated requests to your site. The SameSite attribute has three possible values:
    • Strict: The cookie is never sent with cross-site requests. This provides the strongest protection but can break login flows when users click links from external sources like emails or other websites.
    • Lax: The cookie is sent with top-level navigation (clicking a link) but not with embedded requests (images, iframes, AJAX). This is the recommended default for most WordPress sites.
    • None: The cookie is sent with all requests, including cross-site ones. This must be paired with the Secure flag and is only needed for cookies that must work in cross-site contexts, such as payment gateway integrations or embedded widgets.

Hardening WordPress Authentication Cookies

WordPress sets several cookies for logged-in users, including wordpress_logged_in_* and wordpress_sec_*. These are the most security-sensitive cookies on your site because they control admin access. To harden them, add the following constants to your wp-config.php file, before the line that says "That's all, stop editing!":

// Force cookies to be sent only over HTTPS
define('FORCE_SSL_ADMIN', true);

// Set cookie domain and path
define('COOKIE_DOMAIN', 'example.com');
define('COOKIEPATH', '/');

// Harden PHP session cookies
@ini_set('session.cookie_secure', '1');
@ini_set('session.cookie_httponly', '1');
@ini_set('session.cookie_samesite', 'Lax');

The FORCE_SSL_ADMIN constant is particularly important. It forces WordPress to use HTTPS for the admin area and login pages, which ensures that authentication cookies are only set over encrypted connections. Without this, a user logging in over HTTP would have their credentials and cookies transmitted in plain text.

Note that @ini_set only affects PHP session cookies, not the WordPress-specific cookies. WordPress uses its own cookie-setting functions that do not rely on PHP sessions. To secure WordPress cookies specifically, you need the server-level approaches described below.

Setting Cookie Flags via PHP Configuration

For PHP 7.3 and later, you can set default cookie attributes that apply to all cookies created by PHP's setcookie() function. Add these to your php.ini file if you have access:

session.cookie_secure = 1
session.cookie_httponly = 1
session.cookie_samesite = Lax

If you do not have access to php.ini (which is common on shared hosting), you can set these values in your .htaccess file instead:

# Set secure cookie defaults for PHP sessions
php_value session.cookie_secure 1
php_value session.cookie_httponly 1
php_value session.cookie_samesite "Lax"

Keep in mind that these settings only apply to cookies created through PHP's native session handling. WordPress core and most plugins use setcookie() or wp_set_auth_cookie() directly, which do not automatically inherit these ini settings. For comprehensive coverage, the server-level header approach is more reliable.

Fixing All Cookies via Apache .htaccess

The most reliable way to add security flags to every cookie on an Apache server is to modify the Set-Cookie header at the server level. This catches all cookies, including those set by WordPress core, plugins, and third-party scripts:

# Add security flags to all cookies
<IfModule mod_headers.c>
    Header always edit Set-Cookie ^(.*)$ "$1; Secure; HttpOnly; SameSite=Lax"
</IfModule>

Place this in your site's root .htaccess file. The Header always edit directive uses a regular expression to match all Set-Cookie headers and appends the security flags to each one.

There is an important caveat with this approach. If a cookie already has one of these flags set (e.g., a plugin sets Secure on its own), you may end up with duplicate flags like Secure; Secure. Most browsers handle duplicates gracefully, but a cleaner approach uses a negative lookahead to avoid adding flags that are already present:

<IfModule mod_headers.c>
    # Add Secure flag if not already present
    Header always edit Set-Cookie "^((?!.*Secure).*)$" "$1; Secure"

    # Add HttpOnly flag if not already present
    Header always edit Set-Cookie "^((?!.*HttpOnly).*)$" "$1; HttpOnly"

    # Add SameSite=Lax if no SameSite attribute is present
    Header always edit Set-Cookie "^((?!.*SameSite).*)$" "$1; SameSite=Lax"
</IfModule>

This version checks each cookie individually and only adds the flag if it is not already there. It is more verbose but avoids potential issues with duplicate attributes.

Fixing All Cookies via Nginx Configuration

For Nginx servers, the approach depends on your Nginx version:

Nginx 1.19.3 and later supports the proxy_cookie_flags directive natively:

# In your server or location block
proxy_cookie_flags ~ secure httponly samesite=lax;

The ~ matches all cookies. You can also target specific cookies by name:

# Only apply to WordPress session cookies
proxy_cookie_flags wordpress_logged_in_* secure httponly samesite=lax;
proxy_cookie_flags wordpress_sec_* secure httponly samesite=lax;

Older Nginx versions (before 1.19.3) can use the proxy_cookie_path directive as a workaround:

# Workaround for older Nginx versions
proxy_cookie_path / "/; Secure; HttpOnly; SameSite=Lax";

If you use Nginx as a reverse proxy in front of Apache or PHP-FPM, you may also need to add headers using the more_set_headers module or the add_header directive. However, add_header does not modify Set-Cookie headers, so proxy_cookie_flags is the correct approach.

Fixing Cookies on Cloudflare or CDN-Proxied Sites

If your WordPress site sits behind Cloudflare or another CDN proxy, cookie handling involves an extra layer. Cloudflare sets its own cookies (like __cf_bm for bot management), and these cookies are controlled by Cloudflare, not by your server configuration. You cannot add security flags to Cloudflare cookies via .htaccess or Nginx config.

Cloudflare cookies already include the Secure and HttpOnly flags by default. If InspectWP flags a Cloudflare cookie as missing a flag, it is likely a display issue or a cookie from a Cloudflare feature that intentionally omits certain flags (e.g., analytics cookies that need JavaScript access may lack HttpOnly).

For cookies set by your origin server, the .htaccess or Nginx fixes described above still work correctly even when Cloudflare is in front. Cloudflare passes Set-Cookie headers from your server through to the client without modification.

Handling Plugin Cookies That Lack Security Flags

Many WordPress plugins set their own cookies, and not all of them include proper security flags. Common offenders include:

  • Cookie consent plugins: Plugins like CookieYes, Complianz, or GDPR Cookie Consent set cookies to remember the user's consent choice. Check each plugin's settings for a "Secure cookies" or "Cookie security" option. Some plugins have added these options in recent versions.
  • Analytics and tracking plugins: Google Analytics, Matomo, and similar plugins may set tracking cookies without security flags. The server-level header approach (Apache/Nginx) is the best fix for these, since the plugins rarely offer cookie flag configuration.
  • Caching plugins: WP Rocket, LiteSpeed Cache, and others set cache identifier cookies that may lack flags. Again, the server-level approach handles these automatically.
  • WooCommerce: WooCommerce sets several cookies for cart data and session management. Recent versions of WooCommerce (5.0+) set the Secure flag when the site uses HTTPS, but older versions may not. Update WooCommerce to the latest version and apply the server-level header fix as a safety net.
  • Login and membership plugins: Plugins like MemberPress, Restrict Content Pro, or WP-Members may set their own session cookies. Check for plugin updates, as many have added security flag support in response to browser changes around SameSite enforcement.

The server-level approach (Apache Header edit or Nginx proxy_cookie_flags) is the most reliable solution because it catches all cookies regardless of which plugin or script sets them. Even if a plugin update removes the flags, your server configuration adds them back.

Special Considerations for SameSite=None Cookies

Some functionality requires cookies to be sent in cross-site contexts. Common examples include:

  • Payment gateway callbacks: Services like PayPal, Stripe, or Mollie may redirect users back to your site after payment. If your session cookie uses SameSite=Strict, the user will be logged out after the redirect because the browser does not send the cookie with the cross-site navigation.
  • Embedded content (iframes): If your WordPress site is embedded in an iframe on another domain, cookies need SameSite=None; Secure to function. This is relevant for headless WordPress setups or sites that provide embeddable widgets.
  • OAuth and SSO flows: Single sign-on implementations that redirect through third-party identity providers may require SameSite=None for the session cookie during the authentication flow.

If you need SameSite=None for specific cookies while keeping SameSite=Lax as the default, you will need a more targeted configuration. In Apache:

<IfModule mod_headers.c>
    # Default: add SameSite=Lax to all cookies
    Header always edit Set-Cookie "^((?!.*SameSite).*)$" "$1; SameSite=Lax"

    # Override for specific cookies that need cross-site access
    Header always edit Set-Cookie "(payment_session=.*)" "$1; SameSite=None; Secure"
</IfModule>

Adding Cookie Security via a WordPress Plugin

If you do not have access to server configuration files (common on managed WordPress hosting), you can use a WordPress plugin to add cookie security flags. The plugin approach works by hooking into the wp_headers filter or using PHP's header() function to modify Set-Cookie headers before they are sent to the browser:

function add_cookie_security_flags($headers) {
    // This affects headers sent by WordPress
    if (is_ssl()) {
        $headers['Set-Cookie'] = 'Secure; HttpOnly; SameSite=Lax';
    }
    return $headers;
}
add_filter('wp_headers', 'add_cookie_security_flags');

// For PHP-level cookie security
function enforce_cookie_security() {
    if (is_ssl() && PHP_VERSION_ID >= 70300) {
        ini_set('session.cookie_secure', '1');
        ini_set('session.cookie_httponly', '1');
        ini_set('session.cookie_samesite', 'Lax');
    }
}
add_action('init', 'enforce_cookie_security', 1);

This approach has limitations. It only affects cookies set after the WordPress init hook fires, and it cannot modify cookies set by JavaScript or by external scripts. The server-level approach is always more comprehensive.

Verifying Cookie Security Flags After Applying Fixes

After implementing your fixes, thorough testing is essential to confirm everything works correctly:

  1. Clear all browser cookies: Open your browser's developer tools, go to the Application tab (Chrome) or Storage tab (Firefox), and delete all cookies for your domain. This ensures you are testing fresh cookies with the new flags.
  2. Visit your site and log in: After logging in, go back to the developer tools and inspect each cookie. In Chrome, the Application > Cookies panel shows columns for Secure, HttpOnly, and SameSite. Every authentication cookie should show a checkmark for Secure and HttpOnly, and display "Lax" for SameSite.
  3. Test critical user flows: Navigate through your site's key functionality: add items to a cart (if WooCommerce), submit forms, go through the checkout process, and use any membership features. SameSite changes can occasionally break cross-site flows, so test anything that involves redirects from external services.
  4. Test login from external links: Send yourself a password reset email and click the link. If you used SameSite=Strict (not recommended), this flow may break because the cookie will not be sent with the cross-site navigation from the email client.
  5. Run InspectWP again: Perform a fresh scan of your site with InspectWP to confirm that all cookie security warnings are resolved. InspectWP checks each cookie individually, so you can see exactly which cookies now have the correct flags.

Troubleshooting Common Issues After Enabling Cookie Security Flags

  • Users get logged out after clicking email links: This happens when SameSite=Strict is set. Switch to SameSite=Lax, which allows cookies on top-level navigations from external sites while still blocking embedded cross-site requests.
  • Payment gateway integration breaks: Some payment processors redirect users through their own domain during checkout. If the session cookie is not sent after the redirect, the user loses their cart or login state. Set the payment session cookie to SameSite=None; Secure specifically, while keeping other cookies at SameSite=Lax.
  • Cookie consent banner keeps reappearing: If the cookie consent plugin's cookie is set without the Secure flag and your site redirects HTTP to HTTPS, the cookie set on HTTP is not sent over HTTPS, causing the banner to show again. Ensure your site fully runs on HTTPS and the consent cookie includes the Secure flag.
  • Caching conflicts: Some caching plugins cache the Set-Cookie headers along with the page content. After applying server-level cookie flag changes, purge your entire cache (both page cache and object cache) to ensure the new headers take effect.
  • Duplicate cookie flags: If you see attributes like Secure; Secure or SameSite=Lax; SameSite=Lax in your cookies, you have multiple layers adding the same flags. Check your .htaccess, wp-config.php, PHP ini settings, and any security plugins for overlapping configurations. Use the negative-lookahead regex approach in .htaccess to avoid duplicates.

Cookie Security Best Practices for WordPress

  • Always use HTTPS: The Secure flag is meaningless without HTTPS. Ensure your entire site loads over HTTPS, including all resources (images, scripts, stylesheets). Use the FORCE_SSL_ADMIN constant and consider an HSTS header to prevent any HTTP access.
  • Default to SameSite=Lax: This provides strong CSRF protection without breaking normal navigation. Only use SameSite=None for specific cookies that genuinely require cross-site access, and only use SameSite=Strict if you are certain no external navigation to your site needs to maintain sessions.
  • Apply flags at the server level: Server-level configuration (Apache .htaccess or Nginx config) catches all cookies regardless of origin. This is more reliable than plugin-level or PHP-level approaches.
  • Keep WordPress and plugins updated: Modern versions of WordPress core and most popular plugins set proper cookie flags when HTTPS is active. Keeping everything updated reduces the number of insecure cookies you need to fix at the server level.
  • Audit cookies regularly: Run periodic InspectWP scans to catch new cookies introduced by plugin updates or new integrations. Cookie security is not a one-time fix; it requires ongoing attention as your site evolves.
  • Test on multiple browsers: Chrome, Firefox, Safari, and Edge each handle cookie attributes slightly differently. Chrome is the strictest enforcer of SameSite policies, while Safari has its own Intelligent Tracking Prevention that affects cookie behavior. Test your site on all major browsers after making changes.

Check your WordPress site now

InspectWP analyzes your WordPress site for security issues, SEO problems, GDPR compliance, and performance — for free.

Analyze your site free