Technical audit · 2026-05-31

cnmc.es

Spain's National Commission on Markets and Competition

Spain's National Commission on Markets and Competition — 217 requests, eight hosts, 25 outbound requests. A consent-management mechanism is installed on the site, including a submodule specifically designed to hold Google Analytics back until the user's choice. The counter loads around it: the tag is baked into the homepage markup and fires at the 368th millisecond, 21 ms before the submodule itself. A GA4 request carrying a client identifier and device parameters follows at the 5709th. Among four external recipients, the documents name only one.

Timeline of the leak

+0 ms · homepage loads
The document is served from cnmc.es, running Drupal 10.6.9. The site sets its own Content-Security-Policy header, 1895 characters long. The browser sent a DNT: 1 header.
+351…+368 ms · consent mechanism spins up
Styling and configuration for the cookiesjsr panel: cookiesjsr.min.css, cookiesjsr.conf.js, cookiesjsr-preloader.min.js — the consent-management library loads from the site's own domain.
+368 ms · counter bypasses the mechanism
www.googletagmanager.com/gtag/js?id=G-GJ0T3SEQ50. The initiator is parsing of the main document's markup, line 110. The request goes out in the same window as the banner's preloader.
+385 ms · accessibility widget
www.skynettechnologies.com/accessibility/js/all-in-one-accessibility-js-widget-minify.js with a site token in the address.
+389 ms · the counter-management submodule — delayed
cookies_ga.js — the part of the cookies module intended to hold Google Analytics back until consent. It loads 21 ms after the very Google tag it is supposed to manage.
+422…+459 ms · fonts and icons
fonts.googleapis.com and fonts.gstatic.com — the Noto Sans font from Google's servers. use.fontawesome.com — icon stylesheets and glyphs, served via Cloudflare.
+1773…+2287 ms · widget assembly
Thirteen accessibility-widget scripts from www.skynettechnologies.com, followed by a POST to freeada.skynettechnologies.com/api/widget-settings — the site address is transmitted in the form body.
+5709 ms · data transmission to Google
region1.analytics.google.com/g/collect, a page_view event: client identifier, screen resolution of 1536x864, the Windows platform, x86/64 architecture, a list of browser versions, interface language ru, the address https://cnmc.es/, and the page title. First-session markers are set.

Declared versus actual

For the listed purposes, the commission collects the user's consent ('para lo que recabamos su consentimiento') — заявлен
Three cookie categories: technical (cannot be disabled), analytics, preferences and personalization — заявлен
Analytics cookies — processed by the commission or third parties, used to count users and for statistical analysis — заявлен
Third-party cookies: Google Analytics services are used for statistics — заявлен
Cookie disabling — via browser settings — заявлен
No transfer of data to any third party is foreseen, except in cases of legal obligation — заявлен
Legal basis for processing — performance of a legal obligation, performance of a task in the public interest, and exercise of public authority — заявлен
Data controller — the National Commission on Markets and Competition, Data Protection Officer dpd@cnmc.es — заявлен
+ Skynet Technologies — accessibility widget, 17 requests across two domains, transmission of the site address in an internal request — не заявлен
+ Font Awesome — icon set, loaded via Cloudflare infrastructure — не заявлен
+ Google Fonts — the Noto Sans font from Google's servers — не заявлен
+ Client identifier, screen resolution, and browser client hints transmitted to GA4 — не заявлен
+ The consent-management panel installed on the site — not described in the policy — не заявлен

Transfer timings

+368 ms www.googletagmanager.com

gtag/js for the GA4 stream, parsed from the document's markup, line 110.

+385 ms www.skynettechnologies.com

Accessibility-widget script with a site token. Served via Cloudflare.

+422 ms fonts.googleapis.com

The Noto Sans font stylesheet.

+430 ms use.fontawesome.com

Font Awesome icons, 4 requests, served via Cloudflare.

+458 ms fonts.gstatic.com

Font glyphs from Google's servers.

+2100 ms freeada.skynettechnologies.com

POST api/widget-settings, site address in the form body.

+5709 ms region1.analytics.google.com

GA4 page_view: client identifier, screen resolution, browser client hints, language, page address and title.

Detected trackers

Indicators of GDPR non-compliance

Context

cnmc.es is the website of the National Commission on Markets and Competition, Spain’s independent administrative body. The commission oversees competition and regulates energy, electronic communications, the audiovisual sector, transport, and postal services; its remit also covers digital markets. The data controller is the commission itself, Madrid, Calle Alcalá 47. The Data Protection Officer is dpd@cnmc.es. The platform is Drupal 10.6.9.

Scan: 217 requests, eight hosts. One hundred ninety-two requests to the site’s own domain, 25 outbound. Capture duration: 5.7 seconds; full page load completed at 927 ms. Captured on May 31, 2026, on the homepage.

Two documents describe the processing: the site’s cookie policy and a data protection information document.

Who receives data directly

Google, Skynet Technologies, Font Awesome.

Declared versus actual

The discrepancy here has an unusual character. Typically, the violation consists of there being no consent mechanism at all. Here one exists, is properly configured, and even has a dedicated add-on — yet it is bypassed at the markup level.

First: the tool is installed but doesn’t work. The site runs a Drupal cookies module with the cookiesjsr library, along with a separate cookies_ga submodule. The existence of this submodule is telling: it is written for exactly one task — preventing Google Analytics from loading until the user makes a choice. Someone at the commission deliberately selected and installed the correct tool.

Here’s how it plays out. At +351 ms, the consent panel’s styling arrives; at +367 ms, its configuration; at +368 ms, its preloader. In that same millisecond window, at +368 ms, a request goes out to Google’s tag manager. The capture directly identifies the initiator: parsing of the main document’s markup, line 110. The tag is written directly into the HTML and executes during its parsing — the submodule cannot, by definition, manage it. And the submodule cookies_ga.js itself only arrives at +389 ms, twenty-one milliseconds after the very thing it’s supposed to manage.

The result: the consent panel renders, the user sees a choice, but by that point the counter has already loaded and does not depend on that choice. At +5709 ms, an event goes out to Google with a client identifier, screen resolution of 1536x864, the Windows platform, bitness and architecture, a full list of browser versions, interface language, page address, and page title. Screen resolution and the set of browser client hints are fingerprinting parameters.

Second: an outright denial of transfer. The data protection information document answers the question of recipients briefly and unambiguously: no transfer of data to any third party is foreseen, except in cases of legal obligation. The cookie policy, meanwhile, opens with a statement that the commission collects the user’s consent for the described purposes. The scan disproves both claims: consent is not requested before the transfer, and the transfer occurs.

Third: three undisclosed recipients. The section on third-party cookies names only Google Analytics. In fact, the page runs the Skynet Technologies accessibility widget — seventeen requests across two domains, including a POST to the internal endpoint freeada.skynettechnologies.com with the site address in the form body, and a site token in the script addresses. Font Awesome icons load from an external host via Cloudflare infrastructure. The Noto Sans font is pulled directly from Google’s servers — a separate transmission of IP address and referrer, unrelated to either analytics or the widget.

Fourth: the policy doesn’t know about its own panel. The section on disabling cookies directs the user to browser settings and promises to provide links to popular browsers, but the list of links itself is absent from the text. The document says not a word about the fact that a consent-management panel is installed on the site, where the choice can be changed. A reader of the policy is sent off to configure their browser instead of the tool that already exists on the page.

What the Content Security Policy header reveals

The commission sets its own Content-Security-Policy header — 1895 characters, with separate rules for scripts, frames, images, fonts, styles, and connections. It shows what is permitted to run on the pages in principle.

Permitted, beyond what was observed: Cloudflare Turnstile verification, the cdnjs, unpkg, and jsDelivr script-delivery networks, Google Translate in two address variants, reCAPTCHA, YouTube, Google Docs, Power BI, the Bootswatch theme, and a second Skynet site in the .us zone. Separately, the connection rule permits stats.g.doubleclick.net — a Google advertising node. It did not fire in this scan, but permission for it has been granted.

Proven: the consent mechanism is installed and loads. The styling, configuration, and preloader for the cookiesjsr library arrive from the site’s own domain in the +351…+368 ms interval, along with the dedicated cookies_ga submodule at +389 ms.

Proven: the counter’s loading is not managed by this mechanism. The initiator of the request to the tag manager is recorded in the capture as parsing of the main document’s markup, with a line number given. The tag sits directly in the HTML, executes during parsing, and has no condition preceding it. The submodule intended to manage it loads after it. This claim is verified by the order of requests and does not depend on whether anyone clicked a button in the panel: whatever choice was made, the result would have been the same.

Proven: no choice was made in the panel during this session. Across all 217 requests, there is not a single one recording a user decision.

Proven: the identifier was recorded on the first visit to the site. The client identifier is transmitted to Google in the request body, meaning it exists on the device. The timestamp embedded within it points to 09:39:17 UTC — four seconds before the capture’s first request, and first-session markers in the same request confirm this is the start of the visit.

Not proven and not required: whether the panel was displayed on screen. Response bodies have been stripped from the published file, so the panel’s visual state cannot be reconstructed from it. This is immaterial to the conclusion: the counter’s loading does not depend on the panel regardless.

Separately: the browser sent a DNT: 1 header during the capture. This had no effect on the composition or volume of the transmissions. The GA4 request carries markers of non-personalized advertising and Digital Markets Act mode — the advertising component is limited; this does not affect the analytics transmission carrying the client identifier.

Limits of observation

The scan covers a single page — the homepage — in a single state. The observation records browser behavior, not the internal workings of the services: server-side processing, contractual relationships with recipients, and the services’ own settings on their owners’ side are not verified by a browser-based scan. Legal assessment falls to the competent authority — the Spanish Data Protection Agency (Agencia Española de Protección de Datos).

The file is published stripped of personal data: Cookie headers in requests, response bodies, the page title, the accessibility widget’s site token, the site address in the internal request body, and the analytics session identifier have been removed. The set of cookies on a device therefore cannot be reconstructed from the published file, and no conclusion in this analysis relies on it. The fact that the analytics identifier was recorded rests on something else and is verified directly: the identifier was transmitted to Google in the request body, visible in the file.

The list of recipients permitted by the Content Security Policy header is an inventory of what’s possible, not what was observed. The DoubleClick advertising node did not fire in this scan.

Identification of services relies on domains, address patterns, and response headers: Google — via googletagmanager.com, analytics.google.com, fonts.googleapis.com, and fonts.gstatic.com; Skynet Technologies — via skynettechnologies.com, the script names of the All in One Accessibility suite, and the internal path api/widget-settings; Font Awesome — via use.fontawesome.com. The consent mechanism was identified via the paths of the Drupal cookies module and the cookiesjsr library, with its version indicated.

Conclusion

Spain’s markets regulator installed the right tool on its site — a consent-management panel with a dedicated add-on written specifically to hold Google Analytics back until the user’s choice. And it bypassed that tool with its own markup: the counter tag is written into the homepage HTML and fires at the 368th millisecond, twenty-one milliseconds before the very add-on that was supposed to manage it loads. Five seconds later, a client identifier goes out to Google along with screen resolution, platform, a list of browser versions, and interface language.

The commission’s information document, meanwhile, answers the question of data recipients with a denial: no transfer to third parties is foreseen. The cookie policy states that consent is collected. Among four external recipients, only Google Analytics is named — the accessibility widget with seventeen requests, the external icon set, and the font from Google’s servers go unmentioned. The section on disabling cookies directs the reader to browser settings and doesn’t mention that the site has a panel where the choice can be changed, and the promised list of browser links is absent from the text.

For a body that itself supervises markets and enforces digital-regulation rules, the gap between the tool that was installed and its actual bypass constitutes a violation of the requirements on consent and transparency. Remediation: remove the counter tag from the markup and place its loading under the control of the already-installed submodule; list all recipients in the policy along with the fields transmitted; describe the consent-management panel and the method for withdrawing consent, filling in the missing list of links; move fonts and icons onto the site’s own infrastructure; and either remove the claim of no foreseen transfers from the information document or bring practice into line with it.

Evidence
Original (audit)
HAR file: es/cnmc-es-2026-05-31.har
SHA-256: fcbadcec25c147b111f0ba307dfa0dcc445870e2f7487dcf606c148d4262ce26
Re-check snapshot
Awaiting changes
HAR files are stored on EU infrastructure (Proton Drive). SHA-256 is published for integrity verification.
IMPORTANT: before filing a complaint with the regulator, first contact the company directly and give it 30 days to respond. Without this step the regulator may reject the complaint. Details and a template letter to the company are in the Methodology.
Ready-to-send complaint letter

Where to file: Spanish Data Protection Agency (AEPD)aepd.es

To: Spanish Data Protection Agency (AEPD)
From: [Your name], [contact email]

1. Subject of the complaint
I am filing a complaint regarding the processing of my personal data by the website cnmc.es.

2. Circumstances
I visited the website cnmc.es and found indications that the processing of my personal data does not comply with the GDPR. The technical analysis published on gdpru.eu on 31 May 2026 (open methodology, reproducible measurements) documents the following indications:

1) The site has a consent-management mechanism installed and configured: a Drupal 'cookies' module with the cookiesjsr library and a separate cookies_ga submodule, whose specific purpose is to prevent Google Analytics from loading before the user's choice. Loading of the counter bypasses this mechanism. The tag www.googletagmanager.com/gtag/js?id=G-GJ0T3SEQ50 is parsed by the browser directly from the main document's markup, line 110, and is requested at +368 ms — in the same millisecond window as the banner's own preloader, and 21 ms before the cookies_ga submodule loads, the very submodule that was supposed to manage this loading. The GA4 request carrying a client identifier goes out at +5709 ms. The site itself classifies analytics cookies under the 'cookies de análisis' category, which requires prior consent.

2) The data protection information document answers the question of recipients unambiguously: no transfer of data to any third party is foreseen, except in cases of legal obligation. The cookie policy opens with a statement that the commission collects the user's consent for the listed purposes. In fact, consent is not requested, and the GA4 request transmits to Google a client identifier, screen resolution of 1536x864, the Windows platform, x86/64 architecture, a list of browser versions, interface language, page address, and page title.

3) The section on third-party cookies names one service — Google Analytics. In the scan, visitor data also goes to Skynet Technologies (17 requests across two domains, including a request to freeada.skynettechnologies.com/api/widget-settings with the site address in the form body), to Font Awesome via Cloudflare infrastructure, and to Google Fonts, from which the Noto Sans font loads. None of these recipients is named in the commission's documents.

4) The 'Desactivar las cookies' section offers a single management method — browser settings — with a promise to provide links to popular browsers; the list of links itself is absent from the text. The document says nothing about the consent-management panel installed on the site, which allows the choice to be withdrawn. A reader of the policy is directed to browser settings instead of the tool that already sits on the page.

Full technical documentation is published at: https://gdpru.eu/en/audits/es-cnmc-es/

3. Provisions violated
ePrivacy — LSSI, Law 34/2002, Art. 22.2 (in conjunction with GDPR Art. 6(1)(a)); GDPR Art. 5(1)(a) — transparency; GDPR Art. 13(1)(e) — disclosure of recipients; GDPR Art. 12(1) — accessibility of the withdrawal mechanism

4. Request
I request that you investigate the violations described and apply the measures provided for in Article 58(2) GDPR.

5. Attachments
The full evidence base — the HAR file, its SHA-256 checksum and the quotation from the site's privacy policy documenting the stated contradiction — is published and verifiable at the link in point 2 above.

[Date]                                    [Signature / name]