webshield.js — Full Architecture Plan

Date: 2026-05-29


Threat Model

Attacker Skill Goal
Casual None View source → copy
Developer Medium DevTools → extract + reuse
Determined High Deobfuscate → full clone
Automated Medium Headless scrape + clone

Target: Tier 1-2 impossible, Tier 3 multi-week project, Tier 4 structurally broken.


Dual API Design

Simple API (drop-in, zero config)

<script src="webshield.min.js"></script>
<script>
  WebShield.init({
    domains: ['techiediaries.com', 'localhost'],
    protections: {
      domainLock: true,
      devtools: true,
      antiDebug: true,
      antiHeadless: true,
      antiIframe: true,
      envAnomaly: true,
      timingAnalysis: true,
      contentEncryption: true,
      nonExtractableKeys: true,
      blobServing: true,
      shadowEncapsulation: true,
      opfsBinding: true,
      proxyShield: true,
      swGatekeeper: true,
      domTamper: true,
      decoyTraps: true,
      trustedTypes: true,
      reporting: true,
    },
    onViolation: 'degrade',
    reportUrl: 'https://your-worker.dev/violations',
    redirectUrl: 'https://techiediaries.com',
    violationThreshold: 2,
    debug: false,
  })
</script>

use* Composable API (framework-friendly)

import {
  useDomainLock,
  useDevtools,
  useAntiDebug,
  useAntiHeadless,
  useContentEncryption,
  useDecoyTraps,
  useProxyShield,
} from 'webshield'

// Vanilla JS — each returns a cleanup fn
const stopDomainLock = useDomainLock({ domains: ['techiediaries.com'] })
const stopDevtools   = useDevtools({ threshold: 2, onDetect: 'degrade' })
const stopAntiDebug  = useAntiDebug()

// React
function App() {
  useDomainLock({ domains: ['techiediaries.com'] })
  useDevtools()
  useAntiDebug()
  return <div>...</div>
}

// Vue composable
export function useShield() {
  onMounted(() => {
    const stops = [
      useDomainLock({ domains: ['techiediaries.com'] }),
      useDevtools(),
    ]
    onUnmounted(() => stops.forEach(s => s()))
  })
}

Each use* function:


2026 Browser APIs Exploited

API How
SubtleCrypto (HKDF + AES-GCM) Domain binding, content encryption, integrity hashing
IndexedDB + non-extractable CryptoKey Key exists in browser, JS cannot read it back
Origin Private File System (OPFS) Per-origin private install token, can’t be copied cross-origin
SharedArrayBuffer + Atomics High-res timing for debugger detection (bypasses throttled performance.now)
Web Workers Isolated check threads, hard to tamper from main thread
Closed ShadowDOM querySelector-proof content rendering
Proxy + Reflect Wrap app objects — unexpected access = violation
FinalizationRegistry Detect if shield objects are being GC’d (tamper signal)
Trusted Types Block injected scripts via CSP policy
MutationObserver Watch <head>/
ResizeObserver DevTools dock changes window dimensions
Reporting API Silent violation telemetry
CSS Houdini Paint Worklet Critical render logic in worklet — opaque to JS DevTools panel
WebGL fingerprint Environment anomaly scoring
Canvas fingerprint Hardware-bound fingerprint component
AudioContext fingerprint Third fingerprint vector
Blob URLs (revokable) Decrypted content served as temp blob, revoked after render
navigator.getInstalledRelatedApps() Detect PWA vs raw copy
Atomics.waitAsync Precision timing without blocking

Module Registry

Detection Layer

domain-lock          HKDF domain binding — key derivation fails on wrong domain
devtools-detect      resize delta + console timing + toString trap + element getter
anti-debug           SharedArrayBuffer timing + debugger loop + stack trace origin check
anti-headless        webdriver flag + plugin count + rAF cadence + connection type
anti-iframe          top !== self + Permissions-Policy + frame-busting
env-anomaly          hardwareConcurrency + deviceMemory + screen.isExtended + VM heuristics
timing-analysis      detect automation via requestIdleCallback starvation pattern

Content Protection Layer

content-encryption   AES-GCM encrypted JSON, key from domain + install token
non-extractable-keys SubtleCrypto non-extractable key in IDB — usable, never readable
blob-serving         decrypt → blob URL → render → revoke
shadow-encapsulation render content in closed ShadowDOM
opfs-binding         install timestamp in OPFS as key derivation component

Active Defense Layer

proxy-shield         Proxy wraps all app objects, unexpected access = violation
dom-tamper           MutationObserver on <head>/<script> + FinalizationRegistry on shield objects
decoy-traps          fake window.__lessons, window.__config via Proxy get traps
trusted-types        Trusted Types policy blocks injected scripts
sw-gatekeeper        Service Worker validates integrity headers on every asset request
worker-isolation     core logic in Web Worker, main thread is render-only shell
houdini-core         critical render logic in CSS Paint Worklet (experimental, Chrome)

Reporting Layer

reporting            Reporting API + custom endpoint, silent violation telemetry
self-destruct        shutdown | degrade | redirect | honeypot | custom fn

Violation Modes

Mode Effect Best for
shutdown Body cleared, all timers killed Maximum aggression
degrade Features silently break, looks like bugs Most psychologically effective
redirect Push to official site User-friendly
honeypot App “works” but logs everything Intel gathering
fn Your callback Full control

degrade is the strongest — the copier debugs their broken clone for days.


File Structure

webshield/
  src/
    core/
      index.js           # init(), use* factory, config validator, module runner
      registry.js        # module registration + dependency graph
      reporter.js        # Reporting API + custom endpoint
      violation.js       # threshold counter + response modes

    modules/
      detection/
        domain-lock.js
        devtools-detect.js
        anti-debug.js
        anti-headless.js
        anti-iframe.js
        env-anomaly.js
        timing-analysis.js

      content/
        content-encryption.js
        non-extractable-keys.js
        blob-serving.js
        shadow-encapsulation.js
        opfs-binding.js

      active/
        proxy-shield.js
        dom-tamper.js
        decoy-traps.js
        trusted-types.js
        sw-gatekeeper.js
        worker-isolation.js
        houdini-core.js

    workers/
      shield-worker.js   # Web Worker for isolated checks
      sw-template.js     # Service Worker template

    cli/
      encrypt.js         # encrypt content files at build time
      hash.js            # generate integrity hashes
      bundle.js          # generate configured single-file output

  tests/
    unit/
      core/
      modules/           # one file per module
    integration/
      combinations/      # protection combo tests
      attacker-sims/     # simulate attack scenarios
    e2e/
      playwright/        # headless, devtools, wrong domain, injection

  decisions/
    feasibility-webshield.md
    use-api-design.md    # to be written in Phase 1

  responses/             # this file + future session responses

  docs/
    tutorial/            # series source files

  dist/
    webshield.min.js
    webshield.esm.js
    webshield.cjs.js

  TODO.md
  KNOWLEDGE.md
  memory.md
  package.json

Module Interface Contract

Every module exports:

export default {
  name: 'domain-lock',          // unique slug
  deps: [],                      // other module names required before this
  supported: () => Boolean,      // feature detection — returns false if API unavailable
  start: (config, report) => fn, // activates protection, returns stop()
  // start() returns cleanup function: () => void
}

Core calls supported() first — if false, skips gracefully. Never crashes.


Build Phases + Test Gates

Phase Modules Exit criteria
1 Core engine, registry, violation handler, reporter, use* factory 24 unit, 8 integration
2 domain-lock, anti-iframe, env-anomaly +36 unit, +12 integration, 2 e2e
3 devtools-detect, anti-debug, timing-analysis +42 unit, +15 integration, 3 e2e
4 anti-headless, dom-tamper, decoy-traps +36 unit, +12 integration, 3 e2e
5 content-encryption, non-extractable-keys, opfs-binding, CLI +48 unit, +16 integration, 2 e2e
6 proxy-shield, trusted-types, blob-serving, shadow-encapsulation +40 unit, +14 integration, 3 e2e
7 sw-gatekeeper, worker-isolation +30 unit, +10 integration, 2 e2e
8 houdini-core, reporting, bundle, TypeScript types, publish full suite green

Tutorial Series — “Hardening Client-Side Web Apps in 2026”

Part 1: The Lie of Client-Side Security (and What's Actually True)
Part 2: Cryptographic Domain Binding with SubtleCrypto
Part 3: Detecting DevTools, Debuggers, and Headless Browsers
Part 4: Using Proxy and FinalizationRegistry as Tamper Sensors
Part 5: The Origin Private File System as a Security Primitive
Part 6: Closed ShadowDOM and Blob URLs for Content Protection
Part 7: Service Workers as Security Gatekeepers
Part 8: Building a Modular Flag-Based Protection Library
Part 9: Automated Attacker Simulation with Playwright

Each part: 1500-2500 words, working code samples, linked to webshield repo. Primary SEO target: “client side protection 2026”, “javascript domain lock”.