programming:registration
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revision | |||
| programming:registration [2026/08/27 12:46] – Replace 2.5 KB stub with corpus-backed login/registration page: 17/857 instrument figure, ROLE split of the schema 81, Shepherd demo. Authored by Claude. karel.kubicek.claude | programming:registration [2026/08/27 13:08] (current) – Apply focused+generic review: split Cookie Hunter 13.7% vs 25,242; Kubicek 25.7% of unique domains; login_diff segment match and aria-label; recaptcha deprecation; no ToS-consensus claim. Authored by Claude karel.kubicek.claude | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Automating Login and Registration to Websites ====== | ====== Automating Login and Registration to Websites ====== | ||
| - | Logged-out is the default crawl in this literature, and it is a **design**, not an accident of tooling. Of the 857 web crawls in this corpus, **553 (64.5%)** | + | Logged-out is the default crawl in this literature. Of the 857 web crawls in this corpus, **553 (64.5%)** |
| <WRAP important> | <WRAP important> | ||
| - | Do not read the 81, or the 42 + 24 + 15 split next to it, as " | + | Do not read the 81, or the 42 + 24 + 15 split next to it, as " |
| </ | </ | ||
| Line 12: | Line 12: | ||
| ^ Paper ^ Why ^ | ^ Paper ^ Why ^ | ||
| - | | Drakonakis et al., CCS 2020, //Cookie Hunter// {[drakonakis2020_cookie]} | The scale-registration baseline: | + | | Drakonakis et al., CCS 2020, //Cookie Hunter// {[drakonakis2020_cookie]} | The scale-registration baseline: |
| | Rautenstrauch et al., IEEE S&P 2024, //To Auth or Not To Auth// {[rautenstrauch2024_auth]} | Why you bother: 200 sites where automated login then kept working; more than 400 accounts made by hand; the failure modes that ate the rest of the list | | | Rautenstrauch et al., IEEE S&P 2024, //To Auth or Not To Auth// {[rautenstrauch2024_auth]} | Why you bother: 200 sites where automated login then kept working; more than 400 accounts made by hand; the failure modes that ate the rest of the list | | ||
| | Kaizer et al., IMC 2016 {[kaizer2016_characterizing]} | The existence proof that logged-in and logged-out are different websites: 345 sites, 14 Alexa categories, accounts created by hand, Selenium for the login | | | Kaizer et al., IMC 2016 {[kaizer2016_characterizing]} | The existence proof that logged-in and logged-out are different websites: 345 sites, 14 Alexa categories, accounts created by hand, Selenium for the login | | ||
| Line 109: | Line 109: | ||
| import sys | import sys | ||
| - | # Markers | + | # Attribute values are split into path segments. A segment matches |
| - | # already contain. Exact token match, not a substring of the HTML: " | + | # only if it equals the keyword, or the keyword plus a button/link suffix. |
| - | # inside " | + | # So "logout" |
| - | LOGOUT_RE = re.compile( | + | # do not. Substring search of the HTML is how those three false-positived. |
| - | r"(?: | + | ATTR_RE |
| - | re.IGNORECASE, | + | r" |
| - | ) | + | |
| - | USER_RE = re.compile( | + | |
| - | r"(?: | + | |
| - | re.IGNORECASE, | + | |
| - | ) | + | |
| - | LOGIN_AREA_RE | + | |
| - | r" | + | |
| re.IGNORECASE, | re.IGNORECASE, | ||
| ) | ) | ||
| + | SUFFIXES = ("", | ||
| + | LOGOUT_KW = (" | ||
| + | USER_KW = (" | ||
| + | LOGIN_KW = (" | ||
| + | |||
| + | |||
| + | def segments(value: | ||
| + | parts = re.split(r" | ||
| + | out = {p.strip() for p in parts if p.strip()} | ||
| + | # aria-label=" | ||
| + | # to hyphen so it matches the keyword " | ||
| + | # would turn the label into the tokens " | ||
| + | out.add(value.lower().replace(" | ||
| + | return out | ||
| + | |||
| + | |||
| + | def hits(html: str, keywords: tuple[str, ...]) -> set[str]: | ||
| + | found: set[str] = set() | ||
| + | allowed = {kw + suf for kw in keywords for suf in SUFFIXES} | ||
| + | for m in ATTR_RE.finditer(html): | ||
| + | for seg in segments(m.group(1)): | ||
| + | if seg in allowed: | ||
| + | found.add(seg) | ||
| + | return found | ||
| + | |||
| + | |||
| + | def markers(html: | ||
| + | return { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| Line 141: | Line 166: | ||
| <a href="/ | <a href="/ | ||
| <a href="/ | <a href="/ | ||
| - | <div data-testid=" | + | <div data-testid=" |
| </ | </ | ||
| """ | """ | ||
| - | # Trap: the word " | ||
| - | # but no attribute token is a login marker. A substring test would claim login. | ||
| TRAP_HTML = """< | TRAP_HTML = """< | ||
| < | < | ||
| Line 154: | Line 177: | ||
| </ | </ | ||
| """ | """ | ||
| - | |||
| - | |||
| - | def markers(html: | ||
| - | return { | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | } | ||
| Line 199: | Line 214: | ||
| print(" | print(" | ||
| - | ok, why = verdict(LOGGED_OUT_HTML, | + | ok, _why = verdict(LOGGED_OUT_HTML, |
| if ok: | if ok: | ||
| - | print(" | + | print(" |
| failed += 1 | failed += 1 | ||
| else: | else: | ||
| print(" | print(" | ||
| - | ok, why = verdict(TRAP_HTML, | + | ok, _why = verdict(TRAP_HTML, |
| if ok: | if ok: | ||
| - | print(" | + | print(" |
| failed += 1 | failed += 1 | ||
| else: | else: | ||
| print(" | print(" | ||
| - | # Equality, not substring: a logged-in page whose only new token is | + | # Substring traps the first regex version accepted. Both snapshots keep the |
| - | # " | + | # login form; the candidate only adds the tempting attribute. |
| - | | + | |
| - | | + | (" |
| - | in_m = markers(session_in) | + | (" |
| - | if any(" | + | (" |
| + | ): | ||
| + | candidate = LOGGED_OUT_HTML.replace("</ | ||
| + | ok, why = verdict(LOGGED_OUT_HTML, | ||
| + | if ok: | ||
| + | print(f" | ||
| + | failed += 1 | ||
| + | else: | ||
| + | print(f" | ||
| + | |||
| + | # Equality, not substring: a segment " | ||
| + | | ||
| + | if " | ||
| print(" | print(" | ||
| failed += 1 | failed += 1 | ||
| else: | else: | ||
| print(" | print(" | ||
| + | |||
| + | aria = LOGGED_OUT_HTML.replace( | ||
| + | "</ | ||
| + | ) | ||
| + | ok, why = verdict(LOGGED_OUT_HTML, | ||
| + | if not ok: | ||
| + | print(" | ||
| + | failed += 1 | ||
| + | else: | ||
| + | print(" | ||
| if failed: | if failed: | ||
| Line 265: | Line 302: | ||
| </ | </ | ||
| - | Documented run, 2026-08-27, | + | Documented run, 2026-08-27, |
| < | < | ||
| SELFTEST ok | SELFTEST ok | ||
| - | logout marker present only when logged in: /logout, logout-link | + | logout marker present only when logged in: logout, logout-link |
| - | user marker present only when logged in: logged-in-badge, user-menu | + | user marker present only when logged in: account, |
| - | login area present logged-out and absent logged-in: | + | login area present logged-out and absent logged-in: login, login-link, password |
| SELFTEST ok two logged-out snapshots do not verify | SELFTEST ok two logged-out snapshots do not verify | ||
| SELFTEST ok prose 'log out' / sessionStorage is not a marker | SELFTEST ok prose 'log out' / sessionStorage is not a marker | ||
| + | SELFTEST ok | ||
| + | SELFTEST ok | ||
| + | SELFTEST ok | ||
| SELFTEST ok ' | SELFTEST ok ' | ||
| + | SELFTEST ok | ||
| Documented run (embedded fixtures): | Documented run (embedded fixtures): | ||
| VERIFIED login | VERIFIED login | ||
| - | | + | |
| - | user marker present only when logged in: logged-in-badge, user-menu | + | user marker present only when logged in: account, |
| - | login area present logged-out and absent logged-in: | + | login area present logged-out and absent logged-in: login, login-link, password |
| </ | </ | ||
| Line 299: | Line 340: | ||
| ^ Paper ^ What was created ^ Of what ^ Rate ^ | ^ Paper ^ What was created ^ Of what ^ Rate ^ | ||
| - | | Drakonakis et al., CCS 2020 {[drakonakis2020_cookie]} | 25,242 accounts | + | | Drakonakis et al. registered and logged in {[drakonakis2020_cookie]} | count not given | 168,594 domains with a signup option | **13.7%** | |
| - | | Drakonakis et al., CCS 2020, of the full crawl {[drakonakis2020_cookie]} | 25,242 accounts | 1,585,964 unique domains crawled | **~1.6%** | | + | | Drakonakis et al. accounts created {[drakonakis2020_cookie]} | 25,242 accounts | 168,594 signup domains | they write " |
| + | | Drakonakis et al., of the full crawl {[drakonakis2020_cookie]} | 25,242 accounts | 1,585,964 unique domains crawled | **~1.6%** | | ||
| | Al Roomi et al., USENIX Security 2023 {[alroomi2023_login]} | 45.0K initial test accounts | Google CrUX top 1M | **4.5%** | | | Al Roomi et al., USENIX Security 2023 {[alroomi2023_login]} | 45.0K initial test accounts | Google CrUX top 1M | **4.5%** | | ||
| | Alroomi et al., CCS 2023 {[alroomi2023_password]} | 20,119 domains fully evaluated | Tranco 1M after filtering | a completed-evaluation count, not a success rate | | | Alroomi et al., CCS 2023 {[alroomi2023_password]} | 20,119 domains fully evaluated | Tranco 1M after filtering | a completed-evaluation count, not a success rate | | ||
| | Kubicek et al., TheWebConf 2024 {[kubicek2024_register]} | register-or-newsletter | 660,202 unique Tranco domains | **5.9%** | | | Kubicek et al., TheWebConf 2024 {[kubicek2024_register]} | register-or-newsletter | 660,202 unique Tranco domains | **5.9%** | | ||
| - | Kubicek et al. compare themselves to Cookie Hunter' | + | Kubicek et al. compare themselves to Cookie Hunter' |
| - | **Cookie Hunter.** XDriver on Selenium. Email verification by visiting links in mail. SMS / SSN blocked leftover of the top 1K, completed by hand; the ~25K that make the evaluation "did not require any manual intervention" | + | **Cookie Hunter.** XDriver on Selenium. Email verification by visiting links in mail. SMS / SSN blocked leftover of the top 1K, completed by hand; the ~25K that make the evaluation "did not require any manual intervention" |
| > funding human captcha-solving services to create accounts presents an ethical dilemma, we opted to not handle such cases. | > funding human captcha-solving services to create accounts presents an ethical dilemma, we opted to not handle such cases. | ||
| Line 317: | Line 359: | ||
| **Tripwire** {[deblasio2017_tripwire]}. Honey accounts to infer site compromise from password reuse. **65,413** registration attempts across **33,634** sites; **3,664** accounts on around **2,302** sites. Third-party CAPTCHA solver (DeCaptcher). "While we make no attempt to explicitly check the terms of service" | **Tripwire** {[deblasio2017_tripwire]}. Honey accounts to infer site compromise from password reuse. **65,413** registration attempts across **33,634** sites; **3,664** accounts on around **2,302** sites. Third-party CAPTCHA solver (DeCaptcher). "While we make no attempt to explicitly check the terms of service" | ||
| - | **Kubicek et al.** {[kubicek2024_register]}, | + | **Kubicek et al.** {[kubicek2024_register]}, |
| ===== Newsletter ===== | ===== Newsletter ===== | ||
| Line 347: | Line 389: | ||
| | 2020 (Cookie Hunter) | no farm; WebDriver already made Google not serve reCAPTCHA | The ethical refusal is still the argument to cite. The detection of WebDriver is not the 2026 bottleneck | | | 2020 (Cookie Hunter) | no farm; WebDriver already made Google not serve reCAPTCHA | The ethical refusal is still the argument to cite. The detection of WebDriver is not the 2026 bottleneck | | ||
| | 2022 crawl (Kubicek et al., published 2024) | human farm; mix **75 / 20 / 2 / 3** v2 / v3 / hCaptcha / image; later, research assistants | Dated snapshot of **what was on the web in 2022**. Not a 2026 vendor share | | | 2022 crawl (Kubicek et al., published 2024) | human farm; mix **75 / 20 / 2 / 3** v2 / v3 / hCaptcha / image; later, research assistants | Dated snapshot of **what was on the web in 2022**. Not a 2026 vendor share | | ||
| - | | 2023 (Alroomi / Al Roomi) | AZcaptcha, | + | | 2023 (Alroomi / Al Roomi) | AZcaptcha, |
| | 2023 (Searles et al.) {[searles2023_captcha]} | **manual** user study, 1,400 people, 14,000 CAPTCHAs; 185 of ~200 Alexa sites had account creation, **142** succeeded | Not a crawler. Useful for "will a human complete signup" | | 2023 (Searles et al.) {[searles2023_captcha]} | **manual** user study, 1,400 people, 14,000 CAPTCHAs; 185 of ~200 Alexa sites had account creation, **142** succeeded | Not a crawler. Useful for "will a human complete signup" | ||
| | 2025 (Teoh et al., Halligan) {[teoh2025_captcha]} | agentic VLM **60.7%** of 2,600 challenges; infiltrated **2Captcha** at **70.6%** | **Current.** Farms still exist in 2025. VLMs change the " | | 2025 (Teoh et al., Halligan) {[teoh2025_captcha]} | agentic VLM **60.7%** of 2,600 challenges; infiltrated **2Captcha** at **70.6%** | **Current.** Farms still exist in 2025. VLMs change the " | ||
| | 2026 (Turnstile) | Cloudflare' | | 2026 (Turnstile) | Cloudflare' | ||
| - | Do not take a share from Similarweb, wmtips, or any SEO page. The 75/20/2/3 mix is Kubicek et al.'s 2022 crawl. Google' | + | Do not take a share from Similarweb, wmtips, or any SEO page. The 75/20/2/3 mix is Kubicek et al.'s 2022 crawl. Google' |
| Email verification is the common path (login-policies ground-truth 39%; Cookie Hunter visited the link). SMS is the expensive path: SAAT used Twilio; Cookie Hunter treated phone/SSN as a leftover for the top 1K; login-policies did not do phone. Plan for email. Budget SMS only if the research question lives behind it. | Email verification is the common path (login-policies ground-truth 39%; Cookie Hunter visited the link). SMS is the expensive path: SAAT used Twilio; Cookie Hunter treated phone/SSN as a leftover for the top 1K; login-policies did not do phone. Plan for email. Budget SMS only if the research question lives behind it. | ||
| - | Human CAPTCHA farms: **name who used them, and when**. Cookie Hunter no; Kubicek et al. yes then research assistants; Tripwire | + | Human CAPTCHA farms: **name who used them, and when**. Cookie Hunter no; Kubicek et al. yes then research assistants; Tripwire |
| ===== Terms of service and ethics ===== | ===== Terms of service and ethics ===== | ||
| Line 370: | Line 412: | ||
| * Kubicek et al. {[kubicek2024_register]}: | * Kubicek et al. {[kubicek2024_register]}: | ||
| - | There is no consensus in this literature that creating test accounts is permitted, forbidden, or ToS-exempt. | + | There is no consensus in this literature that creating test accounts is permitted, forbidden, or ToS-exempt. |
| ===== Which methods are current ===== | ===== Which methods are current ===== | ||
| ^ Method ^ Status ^ | ^ Method ^ Status ^ | ||
| - | | Logged-out crawl of a ranked list | **Still the default, and still defensible** for questions that do not live behind an account. 553/ | + | | Logged-out crawl of a ranked list | **Still the default, and still defensible** for questions that do not live behind an account. 553/ |
| | Manual accounts, then scripted login (Kaizer 2016, To Auth 2024) | **Current** when the list is hundreds, not hundreds of thousands | | | Manual accounts, then scripted login (Kaizer 2016, To Auth 2024) | **Current** when the list is hundreds, not hundreds of thousands | | ||
| | Shepherd-style differential verification | **Current, and underused.** The 2020 workshop paper is out of corpus; the method is not obsolete | | | Shepherd-style differential verification | **Current, and underused.** The 2020 workshop paper is out of corpus; the method is not obsolete | | ||
| - | | Cookie Hunter-style full registration on a million-site list | **Done, expensive, and CAPTCHA-censored.** The 13.7% is of signup domains in 2020, under a no-farm constraint | | + | | Cookie Hunter-style full registration on a million-site list | **Done, expensive, and CAPTCHA-censored.** The 13.7% is registered-and-logged-in |
| - | | Human CAPTCHA farm as a measurement instrument | **Used (Kubicek 2022 crawl; Tripwire 2015). Not best practice.** Password-policies 2023 and Cookie Hunter 2020 both refused | + | | Human CAPTCHA farm as a measurement instrument | **Used (Kubicek 2022 crawl). Not best practice.** |
| - | | AZcaptcha / automated solver APIs | **Current practice** | + | | AZcaptcha / automated solver APIs | **Used in the 2023 policy crawls.** Date the OCR/ |
| | Agentic VLM solving (Halligan 2025) | **New.** 60.7% is a paper about whether the technique works, which is the stage it is at | | | Agentic VLM solving (Halligan 2025) | **New.** 60.7% is a paper about whether the technique works, which is the stage it is at | | ||
| | Turnstile / CAPTCHA-free widgets | **Current on the web, almost unmeasured in this corpus.** Date any CAPTCHA-mix figure | | | Turnstile / CAPTCHA-free widgets | **Current on the web, almost unmeasured in this corpus.** Date any CAPTCHA-mix figure | | ||
| Line 403: | Line 445: | ||
| Corpus: 5,859 extracted papers, 2010–2026, | Corpus: 5,859 extracted papers, 2010–2026, | ||
| - | The 81 is a schema enum; the 17 is a hand map ('' | + | The 81 is a schema enum; the 17 is a hand map over those 81 ('' |
| Out of corpus, and labelled so wherever they appear: Shepherd (MADWeb 2020), Chatzimpyrros et al. (ESORICS workshop), Mathur et al. (Big Data & Society). In the bibliographic index but not extracted: Kubicek et al. WWW 2024. | Out of corpus, and labelled so wherever they appear: Shepherd (MADWeb 2020), Chatzimpyrros et al. (ESORICS workshop), Mathur et al. (Big Data & Society). In the bibliographic index but not extracted: Kubicek et al. WWW 2024. | ||
programming/registration.txt · Last modified: by karel.kubicek.claude
