Concentric circles of light on a dark blue background

Cookies for Dutch SMEs: technology, risks, compliance, and audit practice

Cookies for Dutch SMEs: technology, risks, compliance, and audit practice

Written by
Jordy Bouwknegt

Cookies are a mechanism to store “state” (session and preference information) in a browser using the HTTP headers Set-Cookie (server → browser) and Cookie (browser → server). This is functional, but also forms a structural attack and privacy interface: cookies are automatically sent with requests by default, which enables session management but is also the foundation for session hijacking and CSRF, among others. [1]

In the Netherlands, cookies and similar techniques are covered by two layers of regulation: (a) the “cookie rule” from the Telecommunications Act (implementation of the ePrivacy Directive) which places the storing/reading of information on terminal equipment (such as cookies) under conditions of clear information + consent and is explicitly technology-neutral; and (b) the GDPR as soon as cookies (or cookie IDs) can be traced to individuals (e.g. via “online identifiers”). [2]

The biggest compliance errors in SMEs are rarely “we do not have a cookie banner”, but rather: incomplete (or outdated) cookie inventory; scripts and third-party cookies loading before consent; “accept” as the only clear option; consent that is not demonstrable or not withdrawable; and the lack of required information, such as retention periods and third-party access. [3]

The biggest security errors in SMEs are usually technical defaults: session cookie without Secure and/or HttpOnly; too broad Domain/Path scope; no (or incorrect) SameSite; and too long lifetime of sessions or “remember me” cookies. These are not cosmetic issues: a stolen session cookie can have the same impact as stolen credentials until it expires. [4]

For audits, this means: a “cookie or consent registration” as a document is insufficient. You must be able to provide evidence that (1) non-essential cookies are technically blocked until opt-in, (2) consent demonstrably meets GDPR criteria, and (3) security attributes are demonstrably correct (via header and network checks, not assumptions). [5]

Definitions and technical operation of cookies

What is a cookie technically?
In practice, a cookie is a small set of key-value data that a website can have stored in the browser (“user agent”) via HTTP in order to manage sessions and preferences over the largely stateless HTTP protocol. The formal specification of the HTTP cookie headers lies with the IETF. [7]

Headers and data flow (core mechanism)
- Server sends: Set-Cookie: <name>=<value>; <attributes…>
- Browser stores cookie in its “cookie store” and automatically sends with matching requests: Cookie: <name>=<value>; ...
This is precisely why cookies are both useful (sessions) and dangerous (automatic sending). [1]

HTTP/1.1 200 OK
Set-Cookie: session_id=abc123...; Path=/; Secure; HttpOnly; SameSite=Lax
Set-Cookie: pref_lang=en; Max-Age=31536000; Path=/; Secure; SameSite=Lax

# For a subsequent request to the same “site” context:
GET /account HTTP/1.1
Host: example.nl
Cookie: session_id=abc123...; pref_lang=en

[8]

Lifetime: session vs persistent

  • If a cookie has Max-Age or Expires, it is persistent (it remains until expiration, unless deleted earlier). If both are present, Max-Age takes precedence. [9]

  • Without Max-Age and Expires, the browser may keep the cookie until “the session is over” (browser definition). This is often a blind spot in audits, because “session cookie” in practice does not always mean “short” (browser restore, device sync, etc.). [9]

Scope: Domain/Path determine where cookies “leak” to
With Domain=site.example, the cookie is sent to that host and subdomains; without Domain, it is “host-only” and only goes back to the origin host. [10]
Path restricts which URL paths a cookie is sent to; too broad scope is a real risk if you run multiple applications on one domain (in SMEs: webshop + CMS + support portal on the same main domain). [11]

Transport and “secure context” reality
Without secure transport, the cookie content is basically readable (“in clear text”) to an eavesdropper and can even be manipulated in transit; therefore, standards advise to use cookies only over a secure channel and set the Secure attribute. [12]
In modern web security, this aligns with the “secure contexts” concept from the W3C web security specifications (HTTPS as a foundation for confidentiality/authenticity). [14]

Categorization of cookie types

Why categorization is difficult (but necessary)
A cookie can almost always be classified on multiple axes simultaneously: purpose (auth/analytics/marketing), lifetime (session/persistent), party (first/third), and security attributes (Secure, HttpOnly, SameSite, scope). In compliance and audits, this often happens too one-dimensionally (“functional vs tracking”), leaving risks unaddressed. [15]

Axes that you must at least record separately in a cookie inventory
Purpose category: essential/necessary, functional/preference, security/fraud, analytics, marketing/tracking. [16]
Lifetime: session or persistent (Max-Age/Expires). [9]
Party: first-party (set by visited site) or third-party (external service). [17]
Transport and security: Secure, HttpOnly, SameSite, Domain, Path, and where possible cookie prefixes. [18]

Comparison table: cookie purpose types versus use, risk, and mitigation

Purpose Type

Typical Examples

Typical Implementation Patterns

Privacy Risks

Security Risks

Minimal Mitigations

Essential / strictly necessary

session ID for login, shopping cart ID, load-balancing cookie

Set directly upon page load; often first-party; often HttpOnly possible

low if limited to functionality; risk increases if IDs are reusable or shared

session hijacking upon theft; session fixation from too broad scope

Secure + HttpOnly + at least SameSite=Lax; short TTL; server-side sessions; narrow Domain/Path; preferably __Host- prefix where appropriate [19]

Functional / preferences

language/locale, UI settings, “cookie banner seen”

persistent; often set via JS (so often not HttpOnly)

usually limited, but can still become personal data (e.g. unique preference IDs)

XSS can abuse preferences; excessive scope can cause lateral impact

minimize content; no identifiers if not needed; Secure; SameSite=Lax; limit scope; sanitization against XSS [11]

Security / fraud prevention

anti-bot cookie, device-binding hint, CSRF token cookie

often linked to login/checkout; sometimes third-party (anti-fraud vendor)

can implicitly profile (device or behavior characteristics)

incorrect implementation of CSRF token (or token in JS-readable cookie)

CSRF tokens + server-side validation; SameSite as defense-in-depth; limit third-party; record purpose and necessity [20]

Analytics (privacy-friendly)

visit statistics cookies, “new vs returning visitor”

first-party; IP/identifiers anonymized; no data transfer to third parties

depends on “privacy impact”; can turn into tracking if data is shared/linked

typically low, unless analytics script increases XSS surface

limit data sharing; data minimization; transparency (purpose + retention); technical pre-consent gating if consent is required [21]

Marketing / tracking

advertising IDs, cross-site trackers

often third-party; loaded via tags/scripts; cross-site context

high: profiling, selling/transferring data; unclear recipients

extra script supply chain risk; cookie theft impact if tokens are used incorrectly

explicit opt-in; block before consent; state third-party access + duration; periodic re-consent; DPIA for high risk [22]

Sources for definitions/attributes and (minimal) technical mitigations include RFC6265/6265bis and OWASP/NCSC guidance. [23]

Privacy, ePrivacy, and GDPR implications in practice

Telecommunications Act and ePrivacy: it is about the device, not just personal data
The Dutch “cookie provision” (Telecommunications Act Art. 11.7a) is the implementation of Art. 5(3) of the ePrivacy Directive and protects personal privacy by making the storing of or access to information on terminal equipment dependent on clear/comprehensive information and consent. The law is explicitly broader and technology-neutral (so also relevant for similar storage/read technologies). [24]

It is crucial that you do not narrow this down to “cookies = personal data”. The Court of Justice (Planet49) confirmed that the cookie rule applies to “storing/access to information” on the device, regardless of whether that information is personal data. [25]

When is consent required (practical Dutch perspective)?

  • Functional/necessary cookies are mostly seen as an exception: you do not need to ask for consent, but you must be transparent. [26]

  • For analytics, there is a practice in the Netherlands where “analytical cookies with little impact on privacy” (or “anonymized measurement”) can be set without consent, provided the privacy impact remains low and you explain this properly. [27]

  • For tracking/marketing, consent is explicitly the starting point in the Netherlands (“tracking cookies: always consent required”). [28]

GDPR: when do cookies become personal data?
The GDPR defines personal data, in part, as information by which someone is indirectly identifiable, including an “online identifier.” In many realistic setups, cookie IDs fall under this definition as soon as they persistently recognize a user or can be linked to other data. [29]

Valid consent: opt-in, free, demonstrable, withdrawable
The GDPR sets requirements for consent (free, specific, informed, unambiguous; active action). [30]
Pre-ticked boxes do not constitute valid consent; active behavior is required (Planet49). [31]
Cookie walls (denying access unless “accept” is clicked) are fundamentally problematic because consent is not freely given if access to the service/functions is made conditional on cookie consent. This is explicitly stated in the consent guidelines of the European Data Protection Board. [33]
You must make it as easy to withdraw consent as to give it (GDPR Art. 7 paragraph 3 and EDPB further elaboration). [34]
You must be able to demonstrate that consent was given (GDPR Art. 7 paragraph 1). This is not just “convenient”, this is an explicit burden of proof. [35]

Duty to inform: the often forgotten fields
Planet49 is audit gold here, as it makes clear what “clear and comprehensive information” must cover at a minimum. The information provided to the user must also include:

  • the duration/operation of cookies (retention or “operation” duration), and

  • whether third parties have access to those cookies. [36]

Practically, this means: in your cookie list and banner information, “retention” and “third parties” should not be an afterthought, but core fields.

Data controller / data processor in cookie ecosystems
If you as a company decide “why and how” personal data (including cookie data) is processed, you are the data controller; a processor processes on your behalf. This is relevant as soon as you purchase analytics, marketing, or fraud services (contracts, instructions, data use for own purposes). [37]

DPIA: when is using cookies ‘high risk’?
If processing (especially using new technologies) is likely to result in a high risk, a DPIA is mandatory. Tracking/profiling and large-scale monitoring are typical triggers (especially with marketing/tracking stacks). [38]

Data breach notification and cookies (session hijacking as a data breach catalyst)
If a session cookie is stolen and unauthorized access to personal data occurs as a result, this can constitute a data breach. In that case: report to the supervisory authority without undue delay and, where feasible, within 72 hours, unless the risk to rights and freedoms is unlikely; and document all data breaches. [39] For Dutch reporting practice and assessment, the Autoriteit Persoonsgegevens is the designated supervisory authority. [41]

Security implications and concrete mitigations

Why cookies are a security ‘hotspot’
The cookie standard itself recognizes that cookies have historical shortcomings that degrade security and privacy. [42]

Security-wise, session cookies are “bearer tokens”: whoever has the cookie often has the session. OWASP is explicit: stolen session cookies have the same impact as stolen authentication credentials until the cookie expires. [43]

Typical attack scenarios and why SMEs often underestimate them

  • Session hijacking via XSS or insecure transport paths
    Without HttpOnly, JavaScript (document.cookie) can read the session cookie; with XSS, an attacker can therefore exfiltrate cookies. [44]

  • Without Secure, a browser can be tricked into sending a session cookie over HTTP; OWASP notes that “only using HTTPS” is not enough if Secure is missing. [44]

  • The standard specification also emphasizes that cookie headers go “in the clear” without a secure channel and that servers should apply Secure broadly. [45]

sequenceDiagram
    participant U as User (browser)
    participant S as Website (server)
    participant A as Attacker

    U->>S: Login (HTTPS)
    S-->>U: Set-Cookie: session_id=... (without HttpOnly/Secure)
    Note over U: Cookie is readable by JS and can also leak via HTTP

    A->>U: Injects script (XSS) or forces HTTP call
    U-->>A: Exfiltrates session_id (document.cookie or via HTTP)
    A->>S: Request with stolen Cookie: session_id=...
    S-->>A: Access as user (session hijacking)

[46]

CSRF: ‘automatic sending’ is the problem
CSRF works because browsers automatically send cookies; without an extra “challenge-response” (CSRF token/headers), the server cannot distinguish forged requests from genuine ones. [47]
SameSite helps, but is not a complete solution; RFC6265bis explicitly advises to continue using server-side defenses such as CSRF tokens as well. [48]

Minimal technical baseline for SME websites

  • Cookie attributes you should (almost) always enforce
    Secure: only sent over HTTPS; essential against MitM session leaks. [49]

  • HttpOnly: prevents reading via scripts; essential against cookie theft in XSS (note: it does not prevent the browser from sending the cookie). [44]

  • SameSite: defense-in-depth against CSRF and cross-site leakage, with clear trade-offs: - Strict: strongest, but can surprise users when navigating from other sites. [50]

  • Lax: often a pragmatic default for sessions. [51]

  • None: required for embedded cross-site use-cases (widgets, some SSO flows), but must only be used in combination with Secure; otherwise, browsers will ignore the cookie. [52]

Scope hardening: Domain/Path and cookie prefixes
Too broad Domain scoping makes subdomain attacks and session fixation more realistic, especially in “messy” SME domain landscapes. OWASP recommends a restrictive scope (preferably no Domain, and Path as narrow as possible). [11]

Use cookie prefixes as “guardrails” where possible:
- __Secure- requires Secure. [53]
- __Host- requires Secure, Path=/ and no Domain (host-only). [54]

# Strong session cookie for most web apps
Set-Cookie: __Host-session_id=RANDOM_LONG; Path=/; Secure; HttpOnly; SameSite=Lax

# Cross-site (e.g. embedded login) — only if functionally really needed
Set-Cookie: auth_embed=RANDOM_LONG; Path=/; Secure; HttpOnly; SameSite=None

[55]

Server-side sessions over “rich cookies”
The standard advises to encrypt/sign cookie content where necessary, but implicitly emphasizes a harsh reality: even then, an attacker can replay or “transplant” cookies to another agent. This is an additional argument to limit cookies to random identifiers with server-side state, and to consider additional session validation or anomaly detection. [56]

Additional detection (pragmatic for SMEs)
OWASP describes a practical detection approach: when stolen session cookies are used, environmental characteristics (IP region, user-agent, language, time) often change. This is not a perfect detection (false positives), but for SMEs, it can make a large portion of “silent hijacking” visible. [57]

Audit approach, acceptable evidence, and checklist for SME managers

Common SME errors that audits miss

Consent is designed ‘legally’ but not enforced ‘technically’
The banner shows options, but third-party scripts already load before consent (network calls to trackers/ads, cookies set in the background). This is precisely why banner screenshots are weak audit evidence. (You must technically demonstrate that non-essential cookies are not set/read before opt-in.) [58]

A concrete tip is to perform an initial scan yourself, for example with the free open-source tool Webbkoll (https://webbkoll.5july.net) or via the network tab of the browser DevTools during an initial visit in incognito mode. (The previously popular scanner 2GDPR no longer offers free public checks.)

“Withdrawal” is hidden or cumbersome
GDPR requires that withdrawing consent is as easy as giving it; the EDPB elaborates on this for online interfaces (one click to give = also low-threshold online withdrawal, without disadvantage). In SMEs, you often see “email us” or “call during office hours”. [34]

Cookie information misses “duration” and “third-party access”
Planet49 makes it clear that this is not a nice-to-have: cookie duration and access by third parties belong in the information obligation. In SME cookie lists, these fields are remarkably often missing, or they are generic (“13 months”) instead of per cookie. [36]

Security attributes are assumed instead of measured
“We use HTTPS” is sometimes seen as sufficient, whereas the lack of Secure or HttpOnly is precisely what creates the practical leak. OWASP and NCSC are explicit about this. [59]

Mermaid flow: what a demonstrable consent flow looks like for auditing

flowchart TD
  A[Page load] --> B{Consent cookie present?}
  B -- Yes --> C[Apply preferences]
  C --> D[Load allowed categories of scripts only]
  B -- No --> E[Load essential cookies/scripts only]
  E --> F[Show cookie banner with granularity]
  F --> G{User choice}
  G -- Decline --> H[Block non-essential]
  H --> I[Store choice: consent cookie + consent log]
  G -- Accept (selective) --> J[Activate selected categories]
  J --> I
  I --> K[Make withdrawal as easy as giving consent]

[60]

Table: what auditors often accept versus what you actually need to be able to demonstrate

Audit Area

Too Superficial (what is often found “sufficient”)

What You Actually Need (acceptable proof)

Practical Checks

Red Flags

Cookie inventory

One Excel/PDF “cookie list”

Reproducible cookie scan (incl. multiple pages), per cookie: name, purpose, party, lifetime, third-party access, category, lawful basis/consent status, and change process

Browser DevTools + export (HAR), automated scan, manual check of critical flows (login/checkout)

“Unknown cookies” or “n/a”; no lifetime; no third-party field; list older than site release [61]

Consent before placement

Banner screenshot

Network and cookie proof that non-essential tags/cookies do not load before opt-in (and that declining works)

First-load test in incognito; compare “accept” vs “reject”; check Set-Cookie/third-party calls

Third-party calls before choice; cookies set before choice; only “Agree” button prominent [62]

Demonstrate consent

“We use a CMP”

Consent logs (who/what/when/which version), and proof that this can be linked to the actually loaded categories

Audit sample: 10 consent events → proof that behavior is correct

No logs; logs without version/text; no proof of granularity [63]

Withdrawal of consent

Link to privacy statement

Direct withdrawal function in the same interface/layer; proof that tracking stops and cookies are removed/phased out after withdrawal

Test withdrawal → reload → scan again

Withdrawal via email/phone; “withdrawal = clear browser cookies” as the only option [34]

Cookie security

“Everything runs on HTTPS”

Proof from headers: Secure, HttpOnly, SameSite, restricted Domain/Path, and where appropriate prefixes (__Host-)

curl -I/DevTools: inspect Set-Cookie; test cross-site requests

Session cookies without Secure/HttpOnly; SameSite=None without Secure; Domain=.example.nl without necessity [64]

DPIA / high risk

“Not applicable”

DPIA or reasoned DPIA screening for tracking/profilering; document data flows and recipients

Check if marketing stack creates profiles / shares data

No analysis while marketing/tracking is active; no visibility into recipients [65]

Data breach notification process

General incident process

Specifically: (a) “session hijacking” scenario in threat model, (b) detection/response, (c) reporting criteria/72 hours, (d) breach log

Tabletop exercise: “stolen session cookie”

No logging; no incident playbook; no understanding of 72 hours and documentation obligation [66]

Concrete audit questions for SMEs (interview, documentation, technical checks)

Interview (practice over theory)

  • Who owns “cookies & tracking” (both business and IT)? [67]

  • Which third-party services can set cookies via your site (embedded content, tags, analytics, chat)? [68]

  • Which use-cases actually require SameSite=None (cross-site) and why? [52]

  • How can a visitor withdraw consent in a maximum of two clicks? Show it live. [34]

Documentation

  • Show the cookie list including, per cookie: purpose, retention period, third-party access, and category. [36]

  • Show consent log structure (fields) and retention period; how do you show “demonstrability” in accordance with GDPR Art. 7 paragraph 1? [35]

  • Is there a DPIA or DPIA screening for tracking/profiling? [69]

  • Is there a data breach process that explicitly includes cookie/session hijacking as a scenario? [70]

Technical checks (the only way to truly test ‘pre-consent’)

  • Network trace first load (incognito): which cookies are set, which domains are called? [71]

  • Compare “reject” vs “accept”: differences in network calls/cookies. [72]

  • Inspect Set-Cookie headers for Secure, HttpOnly, SameSite, Domain, Path, cookie prefixes. [73]

Closing checklist for SME Security Officers and business owners

Assign one process owner for “cookies, tracking, and consent” (with mandate over marketing and IT). [67] Bonus points if you call that person ‘the cookie monster’ internally.

  • Perform a reproducible cookie scan (multiple pages + login/checkout) and update this with every release. [7]

  • Record per cookie: purpose, category, party, lifetime, third-party access, and whether consent is required. [74]

  • Ensure that “decline” is functionally equally visible/usable as “accept”; avoid cookie walls. [33] Technically block all non-essential scripts and cookies until opt-in (provable via network logs). [75]

  • Make withdrawal as easy as giving (same interface, no email/phone as primary route). [34]

  • Log consent in such a way that you can demonstrate it (GDPR Art. 7 paragraph 1), including the version/text of the consent request. [34]

  • State at least the retention period and third-party access in cookie information; Planet49 makes this explicitly relevant. [36]

  • For session and auth cookies, set by default: Secure; HttpOnly; SameSite=Lax (unless justified otherwise). [76]

  • Only use SameSite=None if you genuinely need it; always combine with Secure (otherwise the cookie is ignored). [77]

  • Restrict Domain/Path and use __Host-/__Secure- prefixes where possible to make misconfigurations fail. [78]

  • Keep sessions short, rotate tokens upon login/privilege change, and terminate sessions upon logout. [4]

  • Add detection for “session cookie misuse” (IP/UA discrepancy) as a pragmatic compensating control. [57]

  • Assess whether tracking/profiling requires a DPIA; document the decision. [69]

  • Explicitly include “session hijacking via cookie theft” in your data breach process (72 hours, risk assessment, documentation obligation). [39]

  • For the Dutch supervisory context: involve the roles and interpretations of the Netherlands Authority for Consumers and Markets (ACM) and the AP in your compliance risk picture. [80]

  • Use guidance from the National Cyber Security Centre, OWASP[4] and ENISA[17] as a “minimum reference framework” for security baselines and testing when you do not have your own security team. [84]

Consulted sources and resources

[1] [7] [23] [42] [71] https://datatracker.ietf.org/doc/html/rfc6265

[2] [24] [67] [80]  https://zoek.officielebekendmakingen.nl/kst-33902-3.html

[3] [33] [58] [72] https://www.edpb.europa.eu/sites/default/files/files/file1/edpb_guidelines_202005_consent_en.pdf

[4]  [11] [18] [19] [44] [46] [49] [59] [64] [73] [76] [78]  https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html

[5]  [29] [30] [34] [35] [37] [38] [39] [60] [63] [65] [66] [69] [70]  https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX%3A02016R0679-20160504

[8] [9] [10] [12]  [45] [48] [50] [51] [52] [53] [54] [55] [56] [77] https://httpwg.org/http-extensions/draft-ietf-httpbis-rfc6265bis.html

[14] https://www.w3.org/TR/secure-contexts/

[15] [16] [21] [84] https://www.ncsc.nl/webapplicaties/gebruik-van-cookies

[17] https://www.enisa.europa.eu/about-enisa/cookies

[20] [47] https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html

[22] https://www.digitaleoverheid.nl/overzicht-van-alle-onderwerpen/cookies-en-online-tracking/

[25] [31] [36]  [61] [62] [74] [75] https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX%3A62017CJ0673

[26] [27] [28] https://www.rijksoverheid.nl/onderwerpen/telecommunicatie/vraag-en-antwoord/mag-een-website-ongevraagd-cookies-plaatsen

[41] https://www.autoriteitpersoonsgegevens.nl/themas/beveiliging/datalekken/datalek-wel-of-niet-melden

[43] [57] https://cheatsheetseries.owasp.org/cheatsheets/Cookie_Theft_Mitigation_Cheat_Sheet.html

[68] https://www.communicatierijk.nl/vakkennis/rijkswebsites/verplichte-richtlijnen/telecommunicatiewet-cookiewet

Cookies are a mechanism to store “state” (session and preference information) in a browser using the HTTP headers Set-Cookie (server → browser) and Cookie (browser → server). This is functional, but also forms a structural attack and privacy interface: cookies are automatically sent with requests by default, which enables session management but is also the foundation for session hijacking and CSRF, among others. [1]

In the Netherlands, cookies and similar techniques are covered by two layers of regulation: (a) the “cookie rule” from the Telecommunications Act (implementation of the ePrivacy Directive) which places the storing/reading of information on terminal equipment (such as cookies) under conditions of clear information + consent and is explicitly technology-neutral; and (b) the GDPR as soon as cookies (or cookie IDs) can be traced to individuals (e.g. via “online identifiers”). [2]

The biggest compliance errors in SMEs are rarely “we do not have a cookie banner”, but rather: incomplete (or outdated) cookie inventory; scripts and third-party cookies loading before consent; “accept” as the only clear option; consent that is not demonstrable or not withdrawable; and the lack of required information, such as retention periods and third-party access. [3]

The biggest security errors in SMEs are usually technical defaults: session cookie without Secure and/or HttpOnly; too broad Domain/Path scope; no (or incorrect) SameSite; and too long lifetime of sessions or “remember me” cookies. These are not cosmetic issues: a stolen session cookie can have the same impact as stolen credentials until it expires. [4]

For audits, this means: a “cookie or consent registration” as a document is insufficient. You must be able to provide evidence that (1) non-essential cookies are technically blocked until opt-in, (2) consent demonstrably meets GDPR criteria, and (3) security attributes are demonstrably correct (via header and network checks, not assumptions). [5]

Definitions and technical operation of cookies

What is a cookie technically?
In practice, a cookie is a small set of key-value data that a website can have stored in the browser (“user agent”) via HTTP in order to manage sessions and preferences over the largely stateless HTTP protocol. The formal specification of the HTTP cookie headers lies with the IETF. [7]

Headers and data flow (core mechanism)
- Server sends: Set-Cookie: <name>=<value>; <attributes…>
- Browser stores cookie in its “cookie store” and automatically sends with matching requests: Cookie: <name>=<value>; ...
This is precisely why cookies are both useful (sessions) and dangerous (automatic sending). [1]

HTTP/1.1 200 OK
Set-Cookie: session_id=abc123...; Path=/; Secure; HttpOnly; SameSite=Lax
Set-Cookie: pref_lang=en; Max-Age=31536000; Path=/; Secure; SameSite=Lax

# For a subsequent request to the same “site” context:
GET /account HTTP/1.1
Host: example.nl
Cookie: session_id=abc123...; pref_lang=en

[8]

Lifetime: session vs persistent

  • If a cookie has Max-Age or Expires, it is persistent (it remains until expiration, unless deleted earlier). If both are present, Max-Age takes precedence. [9]

  • Without Max-Age and Expires, the browser may keep the cookie until “the session is over” (browser definition). This is often a blind spot in audits, because “session cookie” in practice does not always mean “short” (browser restore, device sync, etc.). [9]

Scope: Domain/Path determine where cookies “leak” to
With Domain=site.example, the cookie is sent to that host and subdomains; without Domain, it is “host-only” and only goes back to the origin host. [10]
Path restricts which URL paths a cookie is sent to; too broad scope is a real risk if you run multiple applications on one domain (in SMEs: webshop + CMS + support portal on the same main domain). [11]

Transport and “secure context” reality
Without secure transport, the cookie content is basically readable (“in clear text”) to an eavesdropper and can even be manipulated in transit; therefore, standards advise to use cookies only over a secure channel and set the Secure attribute. [12]
In modern web security, this aligns with the “secure contexts” concept from the W3C web security specifications (HTTPS as a foundation for confidentiality/authenticity). [14]

Categorization of cookie types

Why categorization is difficult (but necessary)
A cookie can almost always be classified on multiple axes simultaneously: purpose (auth/analytics/marketing), lifetime (session/persistent), party (first/third), and security attributes (Secure, HttpOnly, SameSite, scope). In compliance and audits, this often happens too one-dimensionally (“functional vs tracking”), leaving risks unaddressed. [15]

Axes that you must at least record separately in a cookie inventory
Purpose category: essential/necessary, functional/preference, security/fraud, analytics, marketing/tracking. [16]
Lifetime: session or persistent (Max-Age/Expires). [9]
Party: first-party (set by visited site) or third-party (external service). [17]
Transport and security: Secure, HttpOnly, SameSite, Domain, Path, and where possible cookie prefixes. [18]

Comparison table: cookie purpose types versus use, risk, and mitigation

Purpose Type

Typical Examples

Typical Implementation Patterns

Privacy Risks

Security Risks

Minimal Mitigations

Essential / strictly necessary

session ID for login, shopping cart ID, load-balancing cookie

Set directly upon page load; often first-party; often HttpOnly possible

low if limited to functionality; risk increases if IDs are reusable or shared

session hijacking upon theft; session fixation from too broad scope

Secure + HttpOnly + at least SameSite=Lax; short TTL; server-side sessions; narrow Domain/Path; preferably __Host- prefix where appropriate [19]

Functional / preferences

language/locale, UI settings, “cookie banner seen”

persistent; often set via JS (so often not HttpOnly)

usually limited, but can still become personal data (e.g. unique preference IDs)

XSS can abuse preferences; excessive scope can cause lateral impact

minimize content; no identifiers if not needed; Secure; SameSite=Lax; limit scope; sanitization against XSS [11]

Security / fraud prevention

anti-bot cookie, device-binding hint, CSRF token cookie

often linked to login/checkout; sometimes third-party (anti-fraud vendor)

can implicitly profile (device or behavior characteristics)

incorrect implementation of CSRF token (or token in JS-readable cookie)

CSRF tokens + server-side validation; SameSite as defense-in-depth; limit third-party; record purpose and necessity [20]

Analytics (privacy-friendly)

visit statistics cookies, “new vs returning visitor”

first-party; IP/identifiers anonymized; no data transfer to third parties

depends on “privacy impact”; can turn into tracking if data is shared/linked

typically low, unless analytics script increases XSS surface

limit data sharing; data minimization; transparency (purpose + retention); technical pre-consent gating if consent is required [21]

Marketing / tracking

advertising IDs, cross-site trackers

often third-party; loaded via tags/scripts; cross-site context

high: profiling, selling/transferring data; unclear recipients

extra script supply chain risk; cookie theft impact if tokens are used incorrectly

explicit opt-in; block before consent; state third-party access + duration; periodic re-consent; DPIA for high risk [22]

Sources for definitions/attributes and (minimal) technical mitigations include RFC6265/6265bis and OWASP/NCSC guidance. [23]

Privacy, ePrivacy, and GDPR implications in practice

Telecommunications Act and ePrivacy: it is about the device, not just personal data
The Dutch “cookie provision” (Telecommunications Act Art. 11.7a) is the implementation of Art. 5(3) of the ePrivacy Directive and protects personal privacy by making the storing of or access to information on terminal equipment dependent on clear/comprehensive information and consent. The law is explicitly broader and technology-neutral (so also relevant for similar storage/read technologies). [24]

It is crucial that you do not narrow this down to “cookies = personal data”. The Court of Justice (Planet49) confirmed that the cookie rule applies to “storing/access to information” on the device, regardless of whether that information is personal data. [25]

When is consent required (practical Dutch perspective)?

  • Functional/necessary cookies are mostly seen as an exception: you do not need to ask for consent, but you must be transparent. [26]

  • For analytics, there is a practice in the Netherlands where “analytical cookies with little impact on privacy” (or “anonymized measurement”) can be set without consent, provided the privacy impact remains low and you explain this properly. [27]

  • For tracking/marketing, consent is explicitly the starting point in the Netherlands (“tracking cookies: always consent required”). [28]

GDPR: when do cookies become personal data?
The GDPR defines personal data, in part, as information by which someone is indirectly identifiable, including an “online identifier.” In many realistic setups, cookie IDs fall under this definition as soon as they persistently recognize a user or can be linked to other data. [29]

Valid consent: opt-in, free, demonstrable, withdrawable
The GDPR sets requirements for consent (free, specific, informed, unambiguous; active action). [30]
Pre-ticked boxes do not constitute valid consent; active behavior is required (Planet49). [31]
Cookie walls (denying access unless “accept” is clicked) are fundamentally problematic because consent is not freely given if access to the service/functions is made conditional on cookie consent. This is explicitly stated in the consent guidelines of the European Data Protection Board. [33]
You must make it as easy to withdraw consent as to give it (GDPR Art. 7 paragraph 3 and EDPB further elaboration). [34]
You must be able to demonstrate that consent was given (GDPR Art. 7 paragraph 1). This is not just “convenient”, this is an explicit burden of proof. [35]

Duty to inform: the often forgotten fields
Planet49 is audit gold here, as it makes clear what “clear and comprehensive information” must cover at a minimum. The information provided to the user must also include:

  • the duration/operation of cookies (retention or “operation” duration), and

  • whether third parties have access to those cookies. [36]

Practically, this means: in your cookie list and banner information, “retention” and “third parties” should not be an afterthought, but core fields.

Data controller / data processor in cookie ecosystems
If you as a company decide “why and how” personal data (including cookie data) is processed, you are the data controller; a processor processes on your behalf. This is relevant as soon as you purchase analytics, marketing, or fraud services (contracts, instructions, data use for own purposes). [37]

DPIA: when is using cookies ‘high risk’?
If processing (especially using new technologies) is likely to result in a high risk, a DPIA is mandatory. Tracking/profiling and large-scale monitoring are typical triggers (especially with marketing/tracking stacks). [38]

Data breach notification and cookies (session hijacking as a data breach catalyst)
If a session cookie is stolen and unauthorized access to personal data occurs as a result, this can constitute a data breach. In that case: report to the supervisory authority without undue delay and, where feasible, within 72 hours, unless the risk to rights and freedoms is unlikely; and document all data breaches. [39] For Dutch reporting practice and assessment, the Autoriteit Persoonsgegevens is the designated supervisory authority. [41]

Security implications and concrete mitigations

Why cookies are a security ‘hotspot’
The cookie standard itself recognizes that cookies have historical shortcomings that degrade security and privacy. [42]

Security-wise, session cookies are “bearer tokens”: whoever has the cookie often has the session. OWASP is explicit: stolen session cookies have the same impact as stolen authentication credentials until the cookie expires. [43]

Typical attack scenarios and why SMEs often underestimate them

  • Session hijacking via XSS or insecure transport paths
    Without HttpOnly, JavaScript (document.cookie) can read the session cookie; with XSS, an attacker can therefore exfiltrate cookies. [44]

  • Without Secure, a browser can be tricked into sending a session cookie over HTTP; OWASP notes that “only using HTTPS” is not enough if Secure is missing. [44]

  • The standard specification also emphasizes that cookie headers go “in the clear” without a secure channel and that servers should apply Secure broadly. [45]

sequenceDiagram
    participant U as User (browser)
    participant S as Website (server)
    participant A as Attacker

    U->>S: Login (HTTPS)
    S-->>U: Set-Cookie: session_id=... (without HttpOnly/Secure)
    Note over U: Cookie is readable by JS and can also leak via HTTP

    A->>U: Injects script (XSS) or forces HTTP call
    U-->>A: Exfiltrates session_id (document.cookie or via HTTP)
    A->>S: Request with stolen Cookie: session_id=...
    S-->>A: Access as user (session hijacking)

[46]

CSRF: ‘automatic sending’ is the problem
CSRF works because browsers automatically send cookies; without an extra “challenge-response” (CSRF token/headers), the server cannot distinguish forged requests from genuine ones. [47]
SameSite helps, but is not a complete solution; RFC6265bis explicitly advises to continue using server-side defenses such as CSRF tokens as well. [48]

Minimal technical baseline for SME websites

  • Cookie attributes you should (almost) always enforce
    Secure: only sent over HTTPS; essential against MitM session leaks. [49]

  • HttpOnly: prevents reading via scripts; essential against cookie theft in XSS (note: it does not prevent the browser from sending the cookie). [44]

  • SameSite: defense-in-depth against CSRF and cross-site leakage, with clear trade-offs: - Strict: strongest, but can surprise users when navigating from other sites. [50]

  • Lax: often a pragmatic default for sessions. [51]

  • None: required for embedded cross-site use-cases (widgets, some SSO flows), but must only be used in combination with Secure; otherwise, browsers will ignore the cookie. [52]

Scope hardening: Domain/Path and cookie prefixes
Too broad Domain scoping makes subdomain attacks and session fixation more realistic, especially in “messy” SME domain landscapes. OWASP recommends a restrictive scope (preferably no Domain, and Path as narrow as possible). [11]

Use cookie prefixes as “guardrails” where possible:
- __Secure- requires Secure. [53]
- __Host- requires Secure, Path=/ and no Domain (host-only). [54]

# Strong session cookie for most web apps
Set-Cookie: __Host-session_id=RANDOM_LONG; Path=/; Secure; HttpOnly; SameSite=Lax

# Cross-site (e.g. embedded login) — only if functionally really needed
Set-Cookie: auth_embed=RANDOM_LONG; Path=/; Secure; HttpOnly; SameSite=None

[55]

Server-side sessions over “rich cookies”
The standard advises to encrypt/sign cookie content where necessary, but implicitly emphasizes a harsh reality: even then, an attacker can replay or “transplant” cookies to another agent. This is an additional argument to limit cookies to random identifiers with server-side state, and to consider additional session validation or anomaly detection. [56]

Additional detection (pragmatic for SMEs)
OWASP describes a practical detection approach: when stolen session cookies are used, environmental characteristics (IP region, user-agent, language, time) often change. This is not a perfect detection (false positives), but for SMEs, it can make a large portion of “silent hijacking” visible. [57]

Audit approach, acceptable evidence, and checklist for SME managers

Common SME errors that audits miss

Consent is designed ‘legally’ but not enforced ‘technically’
The banner shows options, but third-party scripts already load before consent (network calls to trackers/ads, cookies set in the background). This is precisely why banner screenshots are weak audit evidence. (You must technically demonstrate that non-essential cookies are not set/read before opt-in.) [58]

A concrete tip is to perform an initial scan yourself, for example with the free open-source tool Webbkoll (https://webbkoll.5july.net) or via the network tab of the browser DevTools during an initial visit in incognito mode. (The previously popular scanner 2GDPR no longer offers free public checks.)

“Withdrawal” is hidden or cumbersome
GDPR requires that withdrawing consent is as easy as giving it; the EDPB elaborates on this for online interfaces (one click to give = also low-threshold online withdrawal, without disadvantage). In SMEs, you often see “email us” or “call during office hours”. [34]

Cookie information misses “duration” and “third-party access”
Planet49 makes it clear that this is not a nice-to-have: cookie duration and access by third parties belong in the information obligation. In SME cookie lists, these fields are remarkably often missing, or they are generic (“13 months”) instead of per cookie. [36]

Security attributes are assumed instead of measured
“We use HTTPS” is sometimes seen as sufficient, whereas the lack of Secure or HttpOnly is precisely what creates the practical leak. OWASP and NCSC are explicit about this. [59]

Mermaid flow: what a demonstrable consent flow looks like for auditing

flowchart TD
  A[Page load] --> B{Consent cookie present?}
  B -- Yes --> C[Apply preferences]
  C --> D[Load allowed categories of scripts only]
  B -- No --> E[Load essential cookies/scripts only]
  E --> F[Show cookie banner with granularity]
  F --> G{User choice}
  G -- Decline --> H[Block non-essential]
  H --> I[Store choice: consent cookie + consent log]
  G -- Accept (selective) --> J[Activate selected categories]
  J --> I
  I --> K[Make withdrawal as easy as giving consent]

[60]

Table: what auditors often accept versus what you actually need to be able to demonstrate

Audit Area

Too Superficial (what is often found “sufficient”)

What You Actually Need (acceptable proof)

Practical Checks

Red Flags

Cookie inventory

One Excel/PDF “cookie list”

Reproducible cookie scan (incl. multiple pages), per cookie: name, purpose, party, lifetime, third-party access, category, lawful basis/consent status, and change process

Browser DevTools + export (HAR), automated scan, manual check of critical flows (login/checkout)

“Unknown cookies” or “n/a”; no lifetime; no third-party field; list older than site release [61]

Consent before placement

Banner screenshot

Network and cookie proof that non-essential tags/cookies do not load before opt-in (and that declining works)

First-load test in incognito; compare “accept” vs “reject”; check Set-Cookie/third-party calls

Third-party calls before choice; cookies set before choice; only “Agree” button prominent [62]

Demonstrate consent

“We use a CMP”

Consent logs (who/what/when/which version), and proof that this can be linked to the actually loaded categories

Audit sample: 10 consent events → proof that behavior is correct

No logs; logs without version/text; no proof of granularity [63]

Withdrawal of consent

Link to privacy statement

Direct withdrawal function in the same interface/layer; proof that tracking stops and cookies are removed/phased out after withdrawal

Test withdrawal → reload → scan again

Withdrawal via email/phone; “withdrawal = clear browser cookies” as the only option [34]

Cookie security

“Everything runs on HTTPS”

Proof from headers: Secure, HttpOnly, SameSite, restricted Domain/Path, and where appropriate prefixes (__Host-)

curl -I/DevTools: inspect Set-Cookie; test cross-site requests

Session cookies without Secure/HttpOnly; SameSite=None without Secure; Domain=.example.nl without necessity [64]

DPIA / high risk

“Not applicable”

DPIA or reasoned DPIA screening for tracking/profilering; document data flows and recipients

Check if marketing stack creates profiles / shares data

No analysis while marketing/tracking is active; no visibility into recipients [65]

Data breach notification process

General incident process

Specifically: (a) “session hijacking” scenario in threat model, (b) detection/response, (c) reporting criteria/72 hours, (d) breach log

Tabletop exercise: “stolen session cookie”

No logging; no incident playbook; no understanding of 72 hours and documentation obligation [66]

Concrete audit questions for SMEs (interview, documentation, technical checks)

Interview (practice over theory)

  • Who owns “cookies & tracking” (both business and IT)? [67]

  • Which third-party services can set cookies via your site (embedded content, tags, analytics, chat)? [68]

  • Which use-cases actually require SameSite=None (cross-site) and why? [52]

  • How can a visitor withdraw consent in a maximum of two clicks? Show it live. [34]

Documentation

  • Show the cookie list including, per cookie: purpose, retention period, third-party access, and category. [36]

  • Show consent log structure (fields) and retention period; how do you show “demonstrability” in accordance with GDPR Art. 7 paragraph 1? [35]

  • Is there a DPIA or DPIA screening for tracking/profiling? [69]

  • Is there a data breach process that explicitly includes cookie/session hijacking as a scenario? [70]

Technical checks (the only way to truly test ‘pre-consent’)

  • Network trace first load (incognito): which cookies are set, which domains are called? [71]

  • Compare “reject” vs “accept”: differences in network calls/cookies. [72]

  • Inspect Set-Cookie headers for Secure, HttpOnly, SameSite, Domain, Path, cookie prefixes. [73]

Closing checklist for SME Security Officers and business owners

Assign one process owner for “cookies, tracking, and consent” (with mandate over marketing and IT). [67] Bonus points if you call that person ‘the cookie monster’ internally.

  • Perform a reproducible cookie scan (multiple pages + login/checkout) and update this with every release. [7]

  • Record per cookie: purpose, category, party, lifetime, third-party access, and whether consent is required. [74]

  • Ensure that “decline” is functionally equally visible/usable as “accept”; avoid cookie walls. [33] Technically block all non-essential scripts and cookies until opt-in (provable via network logs). [75]

  • Make withdrawal as easy as giving (same interface, no email/phone as primary route). [34]

  • Log consent in such a way that you can demonstrate it (GDPR Art. 7 paragraph 1), including the version/text of the consent request. [34]

  • State at least the retention period and third-party access in cookie information; Planet49 makes this explicitly relevant. [36]

  • For session and auth cookies, set by default: Secure; HttpOnly; SameSite=Lax (unless justified otherwise). [76]

  • Only use SameSite=None if you genuinely need it; always combine with Secure (otherwise the cookie is ignored). [77]

  • Restrict Domain/Path and use __Host-/__Secure- prefixes where possible to make misconfigurations fail. [78]

  • Keep sessions short, rotate tokens upon login/privilege change, and terminate sessions upon logout. [4]

  • Add detection for “session cookie misuse” (IP/UA discrepancy) as a pragmatic compensating control. [57]

  • Assess whether tracking/profiling requires a DPIA; document the decision. [69]

  • Explicitly include “session hijacking via cookie theft” in your data breach process (72 hours, risk assessment, documentation obligation). [39]

  • For the Dutch supervisory context: involve the roles and interpretations of the Netherlands Authority for Consumers and Markets (ACM) and the AP in your compliance risk picture. [80]

  • Use guidance from the National Cyber Security Centre, OWASP[4] and ENISA[17] as a “minimum reference framework” for security baselines and testing when you do not have your own security team. [84]

Consulted sources and resources

[1] [7] [23] [42] [71] https://datatracker.ietf.org/doc/html/rfc6265

[2] [24] [67] [80]  https://zoek.officielebekendmakingen.nl/kst-33902-3.html

[3] [33] [58] [72] https://www.edpb.europa.eu/sites/default/files/files/file1/edpb_guidelines_202005_consent_en.pdf

[4]  [11] [18] [19] [44] [46] [49] [59] [64] [73] [76] [78]  https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html

[5]  [29] [30] [34] [35] [37] [38] [39] [60] [63] [65] [66] [69] [70]  https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX%3A02016R0679-20160504

[8] [9] [10] [12]  [45] [48] [50] [51] [52] [53] [54] [55] [56] [77] https://httpwg.org/http-extensions/draft-ietf-httpbis-rfc6265bis.html

[14] https://www.w3.org/TR/secure-contexts/

[15] [16] [21] [84] https://www.ncsc.nl/webapplicaties/gebruik-van-cookies

[17] https://www.enisa.europa.eu/about-enisa/cookies

[20] [47] https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html

[22] https://www.digitaleoverheid.nl/overzicht-van-alle-onderwerpen/cookies-en-online-tracking/

[25] [31] [36]  [61] [62] [74] [75] https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX%3A62017CJ0673

[26] [27] [28] https://www.rijksoverheid.nl/onderwerpen/telecommunicatie/vraag-en-antwoord/mag-een-website-ongevraagd-cookies-plaatsen

[41] https://www.autoriteitpersoonsgegevens.nl/themas/beveiliging/datalekken/datalek-wel-of-niet-melden

[43] [57] https://cheatsheetseries.owasp.org/cheatsheets/Cookie_Theft_Mitigation_Cheat_Sheet.html

[68] https://www.communicatierijk.nl/vakkennis/rijkswebsites/verplichte-richtlijnen/telecommunicatiewet-cookiewet

AuditDirect guides you from start to finish toward your ISO 27001 certification

ISO Reality Check

A brief, honest conversation to determine whether ISO 27001 is truly necessary.

FREE*

In 45 minutes, we will discuss:

  • Why the ISO requirement is there (from your client or internally)

  • Whether a certification is actually necessary, or if an alternative is sufficient

  • What your organization is already doing well

  • And what options you have to handle it smarter and simpler


And we are pragmatic enough that we are also willing to have this conversation with you and your client.

*A limited number of spots available.

Schedule your ISO Reality Check

More information

ISO Baseline Assessment

In one day, we assess together how far your organization has already progressed toward ISO 27001.

€1,250

Within 24 hours you will receive:

  • A complete baseline assessment of your current situation

  • An action plan with concrete next steps

  • Insight into your strongest points and areas for improvement

  • Support within the organization, as our consultants will conduct interviews with the involved employees


Guidance only starts after the baseline assessment. This way, we know exactly what is and what is not needed, without wasting your company's time.

Schedule your ISO Baseline Assessment

More information

ISO Internal Audit

A practical Internal Audit that tells you exactly whether you are ready for the external audit.

$1,600*

Within 72 hours you will receive:

  • A complete independent internal audit that meets the ISO 27001 standard 9.2.

  • Clear and applicable findings and recommendations

  • Concrete overview of areas for improvement before the external audit

  • Clear explanation for management and teams involved

    *price is based on a small organization


Schedule your ISO internal audit

More information