Skip to content

FAQ

Can I use OWL in a browser bundle?

Yes, including the package root now — with one deliberate, clearly-signposted exception (CryptoManager's actual encryption/derivation methods).

Background: @owasp-webshield/core's single entry point (dist/index.js) is one esbuild bundle containing every core module. Importing anything from it used to pull all of them in together, so a production browser bundler (Rollup, webpack) failed on any import from the package root — even an unrelated export like SecretPolicy — because two files had a top-level import ... from "node:crypto": CryptoManager/KDFAdapters (A02) and CSRFTokenManager (A08). The same applied to @owasp-webshield/react's root, since it re-exports those categories too.

CSRFTokenManager (A08) is fully fixed, everywhere — rewritten to use the Web Crypto API (globalThis.crypto.getRandomValues) and a hand-written constant-time comparison instead of node:crypto's randomBytes/timingSafeEqual. It has no Node-specific import left and works identically in Node 20+, every modern browser, and any other Web Crypto runtime. useSecureHttpClient benefits from this too — no swap needed for it at all.

CryptoManager/KDFAdapters (A02) remain genuinely Node-only for real encryption — AES-256-GCM and PBKDF2 have no synchronous, browser-portable equivalent (Web Crypto's subtle.encrypt/deriveBits are async-only by spec everywhere, including in Node), and making them async would be a breaking change to the existing sync API. Instead, both packages now ship a browser build (selected automatically via the "browser" exports condition that Vite, webpack 5+, and Rollup-with-node-resolve all respect) where CryptoManager/KDFAdapters/useCryptoManager are replaced with a same-shaped stub: new CryptoManager() still works, but .encrypt()/.decrypt()/.deriveKey() throw a clear SecurityError explaining the limitation instead of crashing the whole bundle at import time. Argon2Adapter and generateSalt (which don't need pbkdf2Sync) are fully real in the browser build too.

js
// This now works in a browser build, package root included:
import { SecretPolicy, CSRFTokenManager, CryptoManager } from "@owasp-webshield/core";

new CryptoManager().encrypt(...); // throws a clear SecurityError in a browser build,
                                   // works for real in Node — same code, either environment

If you'd rather avoid even constructing the stub, or want the smallest possible bundle, @owasp-webshield/core's ./modules/* subpath still lets you import individual source files directly (e.g. @owasp-webshield/core/modules/a02-crypto-integrity/SecretPolicy.js) without touching A02 at all.

This is verified against real published tarballs (not monorepo-relative paths) for both @owasp-webshield/core and @owasp-webshield/react — installed fresh, built with a real vite build, and executed in a real headless browser. See the owl-enabled-react-todo-app example.

SSRFGuard/SafeFetcher (A10) were never actually affected despite also referencing node:dns/promises: that import is a dynamic import() gated behind a typeof process !== "undefined" && process.versions?.node check, so it's never evaluated in a browser — only a build-time warning, not a failure.

Node apps (see the owl-enabled-node-secrets-app example) are fully unaffected either way — Node has node:crypto natively, so they always get the real CryptoManager.

A browser-safe . entry point (so the package root itself works without the ./modules/* subpath) is tracked as follow-up work — it would need either a breaking async CryptoManager API or a separate throwing-stub browser build.

Why is the package called @owasp-webshield/core and not @owl/core?

The library's own acronym has always been OWL (OWASP Web Shield Library) — that hasn't changed. The npm scope changed several times for availability reasons, not naming preference: @owl/*@owsl/*@owl/*@owasp-core/* (actually published, versions 0.1.01.0.4) → @owasp-js/* (renamed in-repo, never published) → @owasp-webshield/* (current). @owasp-webshield was free to claim as an npm org/scope, so the package settled on @owasp-webshield/core and @owasp-webshield/react (React adapter). See CHANGELOG for the full history.

Does OWL require React?

No. @owasp-webshield/core is framework-agnostic and has zero required dependencies. @owasp-webshield/react is a separate, optional package — install it only if you're building a React app. See Getting Started.

What Node.js version does OWL require?

Node.js 20 or later (engines.node: ">=20" in package.json).

How does OWL handle secrets in logs?

SecurityLogger (A09) redacts by field name (e.g. password, token, authorization, cookie) and by value pattern (JWT-shaped strings), even when a secret is logged under a non-sensitive-looking field name. It also detects circular references and enforces a recursion depth limit, so logging a circular object can't crash your process.

How do I report a security vulnerability in OWL itself?

Do not open a public GitHub issue. Follow the private disclosure process described in SECURITY.md.

Where do I find the full list of exports?

Every OWASP category's reference page lists its exports with runnable examples for both the core API and the React adapter. The sidebar under Reference covers A01 through A10 plus Typed Errors.

How is OWL versioned?

Semantic Versioning. Breaking changes (including behavior changes to a security default) are called out explicitly in the CHANGELOG and bump the major version.

Released under the Apache 2.0 License.