Skip to content

[Skill Upgrade]: security/deceptive_ui_guard v2 — render diff, zone weighting, allowlists, golden corpus #314

Description

@rosspeili

Skill ID

security/deceptive_ui_guard

Current manifest version

0.1.0

Proposed change

Context (v1 baseline — merged via #313)

v1 ships a deterministic, HTML-first deceptive UI scanner:

  • Dual DOM vs visible-surface extraction (BeautifulSoup)
  • Structural detectors: hidden styles, mislabeled CTAs, low-contrast (strict/checkout)
  • Lexical KB (kb/deception_lexicon.json) with corroboration gates
  • Trust score, agent_guidance, sanitized_excerpt, SSRF-safe optional URL fetch
  • Warn-only constitution; composable with security/prompt_injection_firewall

Known v1 gaps (documented in catalog + manifest constitution):

  • Web HTML only — no render/computed-style diff
  • Semantic manipulation without structural/lexical signals may not publish
  • Aggressive but legitimate marketing / CMP / sr-only accessibility text can false-positive
  • Catalog has Gemini snippet only; category table in install_extras.md omits skill in security row
  • No golden HTML corpus for regression beyond inline fixtures

v2 goal: industry-grade surface-integrity guard — still deterministic core, optional render lane, dramatically lower false positives, higher recall on checkout/modal zones, test corpus that locks behavior.


v2 scope (manifest 0.2.0)

1. Render / computed-style diff lane (high priority)

Add an optional render path when inline HTML/CSS heuristics are insufficient (PhantomLint / visual-diff class of bugs):

  • New optional pip extra: security_deceptive_ui_guard_renderplaywright (or document host-browser hook; Playwright preferred for CI reproducibility)
  • New optional input: render_mode: off (default), auto, force
  • When enabled: load HTML in headless Chromium, extract computed visible text + bounding boxes for interactive elements
  • Compare render lane vs DOM lane → publish render_dom_divergence findings when text exists in DOM/computed tree but not in pixel-visible surface (or vice versa for overlay traps)
  • Catch: external-stylesheet white-on-white, opacity:0 without inline style, off-viewport position:absolute, zero-size click targets over CTAs

Acceptance:

  • Golden fixture: external CSS hidden fee in checkout zone → publishes at balanced
  • Default path (render_mode=off) unchanged vs v1 outputs for existing tests

2. Zone weighting & context model

Introduce deterministic zone classifier on DOM subtrees:

Zone Examples Weight
checkout #checkout, payment forms, cart totals Highest
modal dialog, overlay, cookie wall High
cmp consent banner containers Medium (allowlist-aware)
navigation nav, footer links Low
general body copy Baseline
  • Severity multiplier per zone (checkout mislabeled CTA > footer link)
  • intended_action boosts relevant zones (already partial in v1 — formalize)
  • Output: findings[].zone always populated; optional zone_summary object in outputs

3. Allowlists & false-positive reduction (critical for production)

Bundled KB additions under kb/:

  • allowlist_sr_only.json — patterns/classes for legitimate screen-reader-only text (sr-only, visually-hidden, WAI-ARIA boilerplate)
  • allowlist_cmp.json — known CMP vendor selectors + benign copy fingerprints (OneTrust, Cookiebot, generic “Accept cookies” without channel mismatch)
  • allowlist_seo.json — meta/JSON-LD/script hidden content not shown to users

Rules:

  • Allowlisted nodes suppress channel_mismatch unless corroborated by imperative lexicon or mislabeled CTA on same control
  • Document allowlist maintenance in instructions.md (community PR path for new CMP vendors)

Acceptance: v1 false-positive fixtures (sr-only legal link, standard cookie banner) → ok at balanced

4. Expanded deception taxonomy & lexicon

Extend detectors + deception_lexicon.json:

  • Pre-checked opt-in boxes (checked default on subscribe)
  • Nag /roach motel patterns (dismiss vs decline asymmetry in copy)
  • Drip pricing signals (subtotal vs “due today” divergence in checkout zone)
  • Fake scarcity timers (deterministic regex + structural: timer in hidden branch)
  • “Continue” vs “Buy now” mislabel variants beyond aria-label ( value vs innerText on <input type="submit"> )

Each new subtype:

  • Corroboration rule documented in code comments
  • At least one positive + one negative fixture

5. Golden HTML corpus & regression harness

  • tests/fixtures/deceptive_ui/**/*.html — categorized: clean, cmp_ok, checkout_trap, anti_agent, mislabeled_cta, render_css_hidden
  • Maintainer test: parametrized scan over corpus; snapshot status, trust_score, finding types (not full JSON — stable fields only)
  • Optional: scripts/validate_deceptive_ui_fixtures.py for contributors

Target: ≥20 fixtures, zero flaky network (HTML-only default; render fixtures gated on extra)

6. Mobile / WebView HTML profile (medium)

  • Heuristics for mobile snapshots: viewport meta, -webkit-tap-highlight, small touch targets stacked on primary CTA
  • Input flag: surface_profile: desktop (default), mobile, auto (infer from viewport meta)
  • No native app OCR in v2 — HTML/WebView only

7. Session nag memory (optional, backward compatible)

Optional input session_fingerprint (string) + output session_recommendation:

  • When same fingerprint rescans with escalating urgency copy across pages → publish nag_loop finding
  • Host browser agent supplies stable origin+path hash; skill remains stateless (no disk persistence)

8. Catalog & docs parity (ship with v2 code)

  • Full Claude / OpenAI / DeepSeek / Ollama snippets in docs/skills/deceptive_ui_guard.md (match prompt_injection_firewall quality)
  • Fix docs/usage/install_extras.md security category row to include both security skills
  • Add browse/checkout chain paragraph to docs/security/skill-trust-model.md
  • Update docs/usage/agent_loops.md when new demo flags exist
  • Skill history row for v2 bump

9. Explicit non-goals (v2)

  • No LLM-in-the-loop detection (constitution preserved)
  • No auto-click, form submit, or checkout completion
  • No legal ToS judgment (stay paired with compliance/tos_evaluator)
  • Native app UI / PDF / email HTML templates — defer to v3 RFC unless trivial

Architecture sketch

# guard.py lanes (v2)
# 1. dom_lane(html) -> RawSignal[]
# 2. visible_lane(html) -> RawSignal[]      # v1
# 3. render_lane(html, mode) -> RawSignal[] # optional Playwright
# 4. zone_classifier(soup) -> zone map
# 5. apply_allowlists(signals, kb/) -> signals
# 6. corroborate(signals) -> findings
# 7. score(findings, zones, sensitivity) -> trust_score, status

Keep scan_surface() pure; render lane behind lazy import so default install stays lightweight.


Version & compatibility

  • Bump manifest to 0.2.0
  • All new inputs optional with v1 defaults
  • Existing execute({html_content, sensitivity}) contracts unchanged
  • New extra is opt-in; core extra remains security_deceptive_ui_guard = []

Test plan

  1. All v1 bundle + maintainer tests pass unchanged
  2. New parametrized golden corpus tests
  3. Render lane tests skipped when Playwright not installed (pytest.importorskip)
  4. Allowlist regression: CMP + sr-only fixtures stay clean
  5. python scripts/sync_extras.py --check after new extra
  6. pytest tests/test_registry_docs.py
  7. black --check / flake8 on touched files

Success criteria (top-tier bar)

  • Recall: catches CSS-only hidden checkout fees (render fixture)
  • Precision: standard CMP + sr-only pages ok at balanced
  • Deterministic: identical inputs → identical outputs (render lane included when enabled)
  • Explainable: every finding has selector, snippet, channels, zone, evidence
  • Docs: five-provider catalog snippets + trust-model chain documented
  • Zero network in default CI path for corpus tests

Breaking change?

No — backward compatible

Likely touch points

  • manifest.yaml version bump
  • skill.py logic
  • instructions.md
  • test_skill.py
  • docs/skills/.md and catalog row
  • examples/*.py or examples/README.md
  • data/ bundled files (address book, config templates)
  • manifest.yaml env_vars and docs/usage/api_keys.md

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

cat: securityRegistry skill category — security (`skills/security/`).enhancementNew feature or request.help wantedExtra attention is needed.skill upgradeEnhance an existing registry skill (not a new skill).

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions