> ## Documentation Index
> Fetch the complete documentation index at: https://docs.safesquid.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Cookie filtering

<Note>
  CLI man page: `safesquid-cookies-filtering(5)`
</Note>

<Frame caption="Cookie list walk">
  <img src="https://mintcdn.com/safe-squid-labs-12a0916f/VRx-_vpMam8ezhZz/images/admin_guide/cookie_filter_flowchart.svg?fit=max&auto=format&n=VRx-_vpMam8ezhZz&q=85&s=c81a16447a81164945143438bff59b5e" alt="Cookie list walk" width="480" height="160" data-path="images/admin_guide/cookie_filter_flowchart.svg" />
</Frame>

## Overview

The `Cookies-filtering` section (`safesquid-cookies-filtering(5)`) provides granular control over HTTP cookies passing between clients and servers.

## Core Mechanics (C++ Source Validation)

Dual-list Allow/Deny walk, last match in pass wins.

* **Dual-List Policy Engine**: Cookie filtering operates on a Global Policy (Allow or Deny) combined with Allow/Deny override lists. If the global policy is set to `Allow`, SafeSquid first scans the Deny List (to block matching cookies) and then scans the Allow List (to explicitly permit exceptions).
* **Time-Based Evaluation**: Unlike other modules, the time profiles here (`limitmonths`, `limitdays`, etc.) are checked against the cookie’s literal `Expires` attribute (`COOKIE_HAS_EXPIRES`), not the proxy’s current system time.
* **Action**: Matches result in the cookie being silently stripped from the HTTP stream (`HEADER_FILTERED`).

## Schema Fields

### Global Fields

* **Enabled (enabled)**: When off, cookie filtering hooks return without modifying Cookie headers. When on, allow/deny rows run per direction (IN/OUT/BOTH).
* **Policy (policy)**: Select the default action to take, when no matching entry for a requested cookie is found.

### Rule-Based Fields (Per Connection Tuning)

* **Enabled (enabled)**: Disabled rows are skipped. Enabled rows participate in allow/deny walks; within each list pass the last matching row wins.
* **Comment (comment)**: Operator notes only. Does not affect cookie match logic.
* **Profiles (profiles)**: Limit this entry to connections that already carry these Access Profile tags. SafeSquid tests against the connection’s active profiles: blank ignores profiles; a positive tag applies when present; prefix ! applies when absent. With multiple tags, the first list entry that resolves decides (positive match -> apply; negated match -> skip; lone unmatched ! -> apply). Rows are walked top to bottom. A matching deny row blocks cookie transmission for that direction (IN/OUT/BOTH) and host/path/expiry filters. (blank) Row applies to all connections that pass direction and expiry tests.
* **Expiry year range (year)**: Mention the cookie expiry year range that is relevant to this entry. The cookie from a particular host (website) expires after this range. Ex: 2016-2017
* **Expiry month range (month)**: Select cookie expiry month range that is relevant to this entry. The cookie from a particular host (website) expires after this range. Example: January – March, here cookie expires after March.
* **Expiry day range (day)**: The cookie expiry day range that is relevant to this entry. The cookie from a particular host (website) expires after this range. Example: 1-20, here cookie will expire after 20th day.
* **Expiry weekday range (weekday)**: The cookie expiry weekday range, this entry applies to. The cookie from a particular host (website) expires after this range. Example: Monday – Friday, here cookie will expire after Friday.
* **Expiry hour range (hour)**: The cookie expiry hour range, this entry applies to. The cookie from a particular host (website) expires after this range. Example: 1-10, here cookie will expire after 10AM.
* **Expiry minute range (minute)**: The cookie expiry minute range, this entry applies to. The cookie from a particular host (website) expires after this range. Example: 15-30, here cookie will expire after 10:30AM. In the above example, Hours are included from Hour range.
* **Domain (domain)**: you can mention the domain names by separating with pipe (|) which you want to allow or deny. You can use regular expression to match the domains. Ex: safesquid.com|google.com
* **Path (path)**: A regular expression matching the cookie’s path attribute. Ex: /
* **Direction (direction)**: The direction of the cookie this entry applies to; can be either in (Set-cookie sent by website), out (Cookie sent by browser), or both.
* **Time match mode (matchmode)**: Select the appropriate mode to match the multiple time ranges.

## How SafeSquid processes the lists

1. If Policy is **Deny**, SafeSquid walks **Allow** first, then **Deny**.
2. If Policy is **Allow**, SafeSquid walks **Deny** first, then **Allow**.
3. Within each list, every enabled matching row is evaluated; the **last** match in that list pass sets the outcome (not first-match like Access restrictions).
4. Each `Cookie` header field is processed separately; denied fields are erased from the header list.
5. Domain, path, and expiry filters on a row apply only when Direction is **IN** (Set-Cookie). The live request/response header hooks call filtering with outbound (`Cookie`) direction only — Set-Cookie rows are configured for server→browser cookies but are not applied by the active `filter_cookies` path in this tree.

<Warning>
  **Order matters.** Put specific host or profile rules above broad catch-alls. Because the last match in a list pass wins, a lower row can override an upper row in the same list.
</Warning>

## Important entry fields

* **Profiles** — Limit the row to connections that carry these Access Profile tags. Blank ignores profiles. Prefix `!` negates a tag. SafeSquid uses the profile matching engine: with multiple tags, the first list entry that resolves decides (positive match → apply; negated match → skip).
* **Direction** — **OUT** — browser→server `Cookie` headers (what the live hooks filter). **IN** — server→browser `Set-Cookie` (domain, path, expiry tests in code; not invoked by current hooks). **BOTH** — either direction when filtering runs.
* **Domain / Path** — Regular expressions. Used for Direction IN when Set-Cookie filtering runs. For OUT rows, only profiles and direction are tested.
* **Expiry ranges / Time match mode** — Apply only to Set-Cookie with a parseable `Expires` attribute. **ABSOLUTE** — one continuous window from start through end fields. **ALL RANGES** — expiry must satisfy every configured range at once.

## Examples

<Tip>
  ### 1 — Deny by default, allow intranet SSO cookies

  * Policy: **Deny**
  * Allow row: Profiles `Staff`, Direction OUT, Domain `corp\.example\.com`

  **Result:** staff users keep `Cookie` headers for `corp.example.com`; all other outbound cookies on matching requests are stripped and `Clear-Site-Data: "*"` is added when any cookie is dropped.
</Tip>

<Tip>
  ### 2 — Allow by default, block ad trackers

  * Policy: **Allow**
  * Deny row: Direction OUT, Domain `doubleclick\.net|ads\.example\.com`

  **Result:** cookies whose host matches the regex are removed from the request; other cookies pass through unchanged.
</Tip>

<Tip>
  ### 3 — IT bypasses cookie filter entirely

  * Access Allow entry for IT with **Bypass → Cookie filtering**

  **Result:** IT clients skip cookie filtering; all other users still hit Allow/Deny rows.
</Tip>

<Tip>
  ### 4 — Last match in Allow list wins

  * Policy: **Deny**
  * Allow row 1 (top): Domain `.*` — permits all
  * Allow row 2 (below): Profiles `Guest`, Direction OUT — no domain

  **Result:** for Guest connections, row 2 is the last Allow match and permits cookies; for others, row 1 is the last Allow match. If neither list changes the default, Policy **Deny** blocks the cookie.
</Tip>

## How to verify

1. From a test client, browse a site that sets cookies and watch the browser devtools Network tab for request `Cookie` headers upstream of SafeSquid.
2. Open **Reports → Detailed logs**; look for `filter_name` related to cookies and native `cookie:` lines when COOKIE is enabled in `LOG_LEVEL`.
3. Check debug response header `X-Cookie-Filter` on the connection (`Dropped-Cookie-Out` when cookies were stripped).
4. Enable **Trace Entry** on one row to confirm profile and domain matching in Native logs.


## Related topics

- [Cookie Inspection](/use_cases/cookie_inspection/cookie_inspection.md)
- [Cookie Filter Configuration and Reference](/use_cases/cookie_inspection/cookie_filter_configuration.md)
- [Content Modifier](/use_cases/content_modifier/content_modifier.md)
- [Suggested Profiles](/admin_guide/policies_and_profiles/suggested_profiles.md)
- [Security Logs](/use_cases/audit_and_forensics/security_logs.md)
