Docs · Security

How components are checked

Every component in the library is written for Fieldbook, and every one goes through the same gates before it ships: a type check, a lint pass, a native render in a headless browser, the anti-slop score, and a static security scan over all of its files (tsx, vue, svelte, astro, html and css). The scan executes nothing; it reads text and matches known-unsafe patterns. The result is stored on the component and shown on its determination label.

The three verdicts

Each rule carries a severity. A variant’s verdict is the worst severity that fired across all its files; nothing averages away a single serious finding.

  • flaggedany block-severity rule: A blocking finding, the security equivalent of a hard fail.
  • reviewa warn rule, no block: Worth a human glance before you paste it in.
  • cleanonly info rules, or nothing: Noted for context: expected, normal behaviour.

Red is used for a flagged verdict only, the same discipline the rest of the site follows: red marks a hard failure and nothing softer.

What the scan looks for

Ruleset 2026.09.1, 34 rules. Highlights: dynamic code evaluation (eval, new Function, a code string in a timer); HTML injection sinks (innerHTML/outerHTML/insertAdjacentHTML, React dangerouslySetInnerHTML, Vue v-html, Svelte {@html}) fed a non-literal value; remote script, iframe and stylesheet injection (well-known CDNs noted as informational); network calls to unrecognized hosts; reads of tokens from cookies or storage; postMessage to "*"; obfuscation signals (long base64 or hex-escaped blobs, atob(unescape(…)), fromCharCode chains); hardcoded credentials and secret-shaped env reads; camera / mic / geolocation / service-worker requests; and prototype-pollution patterns.

  • atob-decodeinfoclean

    atob on its own is benign (decoding an image or a small blob). Flagged as info so a reviewer can confirm it is not the first step of an obfuscated payload.

  • base64-blobinfoclean

    A large base64 string is usually an inlined image or font, but can also be a concealed script. Info so a reviewer can glance at what it decodes to.

  • clipboard-writeinfoclean

    Copy-to-clipboard is a normal UI affordance. Info only, so a reviewer is aware the component can set clipboard contents.

  • cookie-readwarnreview

    The cookie jar usually holds session identifiers. A UI component has no reason to read it; when it does, a reviewer should confirm where the value goes.

  • crypto-miningblockflagged

    Names of known browser crypto-miners. A component that pulls in a miner steals a visitor's CPU. There is no benign reason for these strings to appear.

  • document-writewarnreview

    document.write injects markup into the page as it parses and is a common vehicle for smuggling in remote scripts. Modern components never need it.

  • env-secretwarnreview

    A client component reading process.env.*_KEY / *_SECRET risks baking a server secret into shipped JS. Surfaced so a reviewer can confirm the value is public (NEXT_PUBLIC_) or server-only.

  • evalblockflagged

    eval executes an arbitrary string as code, defeating every static guarantee about what the component does. A pasted component that calls eval can run anything the page can.

  • exfil-sinkblockflagged

    Concatenating cookies or storage into a URL, image source, beacon or socket is the classic credential-exfiltration shape. Blocked outright.

  • geolocationwarnreview

    Reading the visitor's location is a privacy-sensitive capability that most UI components have no need for. Warn so its use is deliberate.

  • hardcoded-secretblockflagged

    A live-looking API key, GitHub token, AWS access key id, or private key committed into component source. Even if a placeholder, it must not ship in the catalog.

  • hex-obfuscationwarnreview

    A long run of \xNN escapes hides a string's contents from anyone reading the source. It is a strong signal of a deliberately concealed payload.

  • innerhtml-dynamicwarnreview

    Assigning a variable or interpolated string to innerHTML/outerHTML/insertAdjacentHTML/dangerouslySetInnerHTML renders it as live HTML. If any part comes from data or props it is an XSS sink.

  • innerhtml-literalinfoclean

    A plain string constant assigned to innerHTML carries no external input, so it cannot be an injection point. Noted for completeness, not a concern.

  • media-capturewarnreview

    getUserMedia / getDisplayMedia turn on the camera, mic, or screen capture. A high-consequence capability that must be intentional, not a hidden side effect of a widget.

  • network-externalwarnreview

    fetch / XMLHttpRequest / WebSocket / sendBeacon to an external origin sends data off the page. To a host that is not a known public API, it can be exfiltration or unwanted tracking.

  • network-public-apiinfoclean

    A call to a recognized public, read-only API (GitHub, placeholder image or avatar services, demo JSON). Common in example components; noted, not a concern.

  • new-functionblockflagged

    new Function(...) compiles a string into executable code, an eval by another name. There is no legitimate reason for a UI component to build functions from strings.

  • obfuscation-decodewarnreview

    atob(unescape(...)) and long String.fromCharCode(...) chains are classic ways to hide a string from a reader so it can be turned back into code or a URL at runtime. Legitimate components have no reason to obfuscate.

  • postmessage-wildcardwarnreview

    postMessage(data, '*') sends the message to whatever origin currently frames the page, so any embedder can read it. Name the target origin instead.

  • prototype-pollutionwarnreview

    Assigning through __proto__ or constructor.prototype[...] can poison every object in the runtime, a known privilege-escalation and denial-of-service vector. No presentational component needs this.

  • remote-framewarnreview

    An <iframe src> to an external origin embeds a page you do not control; it can frame trackers or phishing content. Recognized embed hosts (YouTube, Vimeo) are treated as informational.

  • remote-frame-cdninfoclean

    An <iframe src> to a recognized embed host (YouTube, Vimeo). Expected for media components; noted, not a concern.

  • remote-scriptwarnreview

    A <script src> (or a script element pointed at a URL) loads and runs code from another origin. From a host not on the CDN allowlist, that code is unaudited and can change under you.

  • remote-script-cdninfoclean

    A <script src> pointed at a well-known CDN (jsdelivr, unpkg, cdnjs, Tailwind play CDN...). Common and expected for html/uiverse specimens; noted, not a concern.

  • remote-styleinfoclean

    A <link rel=stylesheet> from an external origin can restyle the page and, via url() and font loads, leak referer traffic. Low severity because CSS cannot execute script.

  • remote-style-cdninfoclean

    A <link rel=stylesheet> from a well-known CDN or the Google Fonts host. Expected; noted, not a concern.

  • service-workerwarnreview

    A service worker persists in the background and can intercept every request the origin makes, long after the component is gone. Out of scope for a catalog component and worth flagging.

  • settimeout-stringwarnreview

    setTimeout/setInterval with a string first argument evaluates that string as code, the same risk as eval. Pass a function instead.

  • storage-accessinfoclean

    General use of cookies / localStorage / sessionStorage / IndexedDB (e.g. remembering a theme or a dismissed banner). Expected for stateful widgets; noted, not a concern.

  • storage-tokenwarnreview

    Touching document.cookie / localStorage / sessionStorage / IndexedDB with a token-, auth- or secret-shaped key is how credentials get harvested from a host page. A presentational component should not read them.

  • svelte-htmlwarnreview

    {@html expr} injects the expression as raw HTML, bypassing Svelte's escaping. Safe only for values the component itself controls.

  • vue-htmlwarnreview

    v-html (and an :innerHTML bind) renders the bound expression as raw HTML with no escaping. Bound to anything but a trusted constant it is an XSS sink.

  • window-openinfoclean

    window.open navigates a new tab. Usually benign, but worth surfacing since a hardcoded external URL can be an ad or a redirect. Pair new tabs with rel=noopener.

What it does not promise

This is a static, best-effort screen, not a proof of safety. It reads patterns, not intent: a clean verdict means no known-unsafe pattern was found, not that the component is guaranteed benign. Obfuscation can hide behaviour a text scan cannot see, and a warn verdict is often a perfectly legitimate capability (a copy-to-clipboard button, a fetch to a public API). Always read the source of anything you paste into your project; the MCP tools and the detail page both give you the full code and the list of flags to make that judgement.