Skip to content

fix: count sites instead of hostnames in public_hash_list - #357

Merged
max-ostapenko merged 5 commits into
HTTPArchive:mainfrom
tomayac:public-hash-list-sites
Oct 5, 2026
Merged

max-ostapenko merged 5 commits into
HTTPArchive:mainfrom
tomayac:public-hash-list-sites

Conversation

@tomayac

@tomayac tomayac commented Sep 29, 2026

Copy link
Copy Markdown
Member

The ≥100 threshold in public_hash_list counts distinct hostnames of the resource URL, so a font used only on 100 $city.$vulnerable-group.com landing pages passes, even though it identifies a single site, and any origin could then probe Cross-Origin Storage for its hash to infer that the user belongs to that group. This PR counts distinct sites (eTLD+1 of the embedding page) using the full Public Suffix List, including the private section that BigQuery's NET.PUBLIC_SUFFIX() skips, so alice.github.io and bob.github.io still count as two sites, renames num_origins to num_sites, and adds a script plus a monthly workflow that keep the private suffix rules current. @max-ostapenko, could you please review?

@tomayac

tomayac commented Sep 29, 2026

Copy link
Copy Markdown
Member Author

This is a follow-up to #324.

@tunetheweb

Copy link
Copy Markdown
Member

TIL NET.REG_DOMAIN only considers ICANN domains from the PSL and not Private PSL domains! That's sad... 😔

Signed-off-by: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com>
@max-ostapenko
max-ostapenko changed the base branch from main to fancy-warbler October 3, 2026 23:24
…domains and exception rules

Signed-off-by: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com>
@max-ostapenko

Copy link
Copy Markdown
Contributor

Hi @tomayac,
To avoid maintaining a 3,400-line static JavaScript file in the repo and a recurring GitHub Actions workflow to update it, I have automated the PSL ingestion in our pipeline:

  1. We downloads the complete Public Suffix List (both ICANN and Private domains) directly into BigQuery: httparchive.urls.public_suffix_list.

    • Columns: suffix STRING, is_wildcard BOOLEAN, is_exception BOOLEAN, is_private BOOLEAN, section STRING.
    • This runs automatically on every monthly crawl before the Dataform pipeline triggers.
  2. The table is declared in Dataform as urls.public_suffix_list.

Could you please:

  1. Rebase your PR on fancy-warbler.
  2. Update the private_suffixes CTE in definitions/output/performance/public_hash_list.js to query the table for the private rules:
WITH private_suffixes AS (
  SELECT suffix, is_wildcard
  FROM ${ctx.ref('urls', 'public_suffix_list')}
  WHERE is_private AND NOT is_exception
),

(and remove the sqlStringList helper).

  1. Remove the other files from your PR.

Your core SQL logic for site counting in public_hash_list.js will stay intact, and the suffix list will stay automatically up to date!

max-ostapenko and others added 2 commits October 4, 2026 02:13
…ines

Signed-off-by: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com>
The >=100 threshold counted distinct hostnames of the resource URL, so a
resource used only on many subdomains of one site (for example
$city.$vulnerable-group.com) passed the privacy gate. Count distinct
sites (eTLD+1 of the embedding page) using the full Public Suffix List,
including the private section that BigQuery's NET.PUBLIC_SUFFIX() skips.
The private rules come from the urls.public_suffix_list table, which the
crawl_complete DAG keeps current.
@tomayac
tomayac force-pushed the public-hash-list-sites branch from 342ae32 to 80cc0ae Compare October 5, 2026 07:17
@tomayac

tomayac commented Oct 5, 2026

Copy link
Copy Markdown
Member Author

Thanks, @max-ostapenko, that's cleaner. Rebased on fancy-warbler, switched private_suffixes to read from urls.public_suffix_list, removed sqlStringList, and dropped the static list, script, workflow, and config changes. The PR now only touches public_hash_list.js. PTAL, thank you!

@max-ostapenko
max-ostapenko changed the base branch from fancy-warbler to main October 5, 2026 11:53
@max-ostapenko
max-ostapenko merged commit cf7a9a1 into HTTPArchive:main Oct 5, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants