npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@skydevlab/securejs

v0.1.0

Published

Secure-by-default browser utilities for JavaScript.

Readme

SecureJS

Secure-by-default browser utilities for JavaScript.

CI npm version License: MIT TypeScript Tree Shakeable

SecureJS (@skydevlab/securejs by SkyDevLab) is a lightweight, framework-independent TypeScript library providing composable, secure-by-default browser utilities. It helps developers avoid common browser-side security mistakes—such as Open Redirects, javascript: XSS, Reverse Tabnabbing, prototype pollution in web storage, clipboard bombs, and wildcard postMessage leaks.

npm install @skydevlab/securejs

Works Seamlessly With

SecureJS has zero runtime dependencies on any frontend framework. It works across modern and legacy web stacks:

  • Vanilla JavaScript & TypeScript
  • React & Next.js
  • Vue & Nuxt
  • Angular
  • Svelte & SvelteKit
  • jQuery
  • ASP.NET MVC & ASP.NET Core Razor Pages
  • Any browser-based web application

Core Philosophy

"SecureJS helps developers reduce common browser-side security mistakes."

SecureJS NEVER claims to secure your entire application. True application security requires defense-in-depth across server controls, browser headers, and strict development practices.

  • Secure by Default: Safe fallbacks over surprising mutations or silent failures.
  • Framework Agnostic: Pure browser/DOM utilities with zero framework baggage.
  • TypeScript First: Written in strict TypeScript with comprehensive .d.ts declaration maps and source maps.
  • Modular & Tree-Shakeable: Import only what you need, either from the root or via dedicated subpaths (@skydevlab/securejs/url).
  • No Global Monkey-Patching: Never alters native prototypes (window, Document, Element.prototype, fetch) by default.
  • Actionable Dev Warnings: Opt-in development security checker that identifies dangerous inputs without logging sensitive user data.

Quick Start

import { safeURL, safeExternalLink, safeStorage } from "@skydevlab/securejs";

// 1. Sanitize untrusted URLs
const userLink = safeURL(userInput); // returns safe URL string or null

// 2. Safe external link props (mitigating Reverse Tabnabbing)
const linkProps = safeExternalLink(userInput);
// -> { href: "https://...", rel: "noopener noreferrer", target: "_blank", isExternal: true }

// 3. Hardened storage with prototype pollution protection
safeStorage.setItem("user-settings", { theme: "dark" });
const settings = safeStorage.getItem("user-settings");

Table of Contents


Modular Subpath Imports

SecureJS supports modern package exports. If bundle size is critical, you can import individual modules directly:

import { safeURL } from "@skydevlab/securejs/url";
import { safeRedirect } from "@skydevlab/securejs/redirect";
import { isAllowedOrigin } from "@skydevlab/securejs/origin";
import { safeExternalLink } from "@skydevlab/securejs/links";
import { safeHTML } from "@skydevlab/securejs/html";
import { safeSetAttribute } from "@skydevlab/securejs/attributes";
import { safePostMessage } from "@skydevlab/securejs/messaging";
import { safePaste } from "@skydevlab/securejs/clipboard";
import { validateFile } from "@skydevlab/securejs/files";
import { safeStorage } from "@skydevlab/securejs/storage";
import { enableDevWarnings } from "@skydevlab/securejs/warnings";

API Reference

1. URL Security

Protects against XSS vectors via dangerous schemes (javascript:, data:, vbscript:, blob:), null bytes, and protocol-relative bypasses.

import { safeURL, isSafeURL } from "@skydevlab/securejs";

// Returns sanitized URL string or null
safeURL("https://example.com"); // "https://example.com/"
safeURL("javascript:alert(1)"); // null
safeURL("//attacker.com"); // null (blocked protocol-relative bypass)

// Advanced Configuration
const clean = safeURL(untrustedInput, {
  allowedProtocols: ["https:"], // Restrict protocols (default: ['https:', 'http:'])
  allowedOrigins: ["https://example.com", "https://*.example.com"], // Restrict origins
  allowRelative: true, // Allow relative URLs (default: false)
  fallback: "/error", // Fallback returned on failure (default: null)
});

// Boolean check
if (isSafeURL(untrustedInput)) {
  // Safe to proceed
}

2. Safe Redirect

Prevents Open Redirect vulnerabilities (CWE-601) where untrusted destinations deceive users into navigating to malicious external sites.

import { safeRedirect } from "@skydevlab/securejs";

const result = safeRedirect(redirectParam, {
  allowRelative: true, // Allow safe relative paths like /dashboard (default: true)
  allowedOrigins: ["https://auth.company.com"], // Whitelist external redirect destinations
  action: "replace", // Optional: 'assign' | 'replace' | 'none'
  fallback: "/home",
});

if (result.ok) {
  // Automatically navigates window.location if action is set, or manually:
  result.execute();
} else {
  console.error("Open redirect blocked:", result.reason);
}

3. Origin Validation

Provides strict WHATWG origin matching. Protects against common substring confusion attacks (example.com.attacker.com or fake-example.com).

import { isAllowedOrigin, validateOrigin } from "@skydevlab/securejs";

const allowed = isAllowedOrigin(window.location.origin, {
  allowedOrigins: [
    "https://example.com",
    "https://*.example.com", // RFC wildcard subdomain matching
    /^https:\/\/app-[a-z]+\.example\.com$/, // Regular expression
    (origin) => origin.startsWith("https://trusted-"), // Custom predicate
  ],
});

// Detailed diagnostic inspection
const status = validateOrigin(incomingOrigin, { allowedOrigins: ["https://example.com"] });
if (!status.valid) {
  console.warn("Origin rejected because:", status.reason);
}

4. External Links

Prepares safe HTML attributes for external links (<a>), mitigating Reverse Tabnabbing by enforcing rel="noopener noreferrer".

import { safeExternalLink } from "@skydevlab/securejs";

// React example:
const linkProps = safeExternalLink(userUrl);
return linkProps ? <a {...linkProps}>Visit Link</a> : null;

// Vanilla JS:
const props = safeExternalLink(userUrl);
if (props) {
  linkEl.href = props.href;
  linkEl.rel = props.rel; // "noopener noreferrer" if external
  if (props.target) linkEl.target = props.target; // "_blank" if external
}

5. HTML Sanitization

Integrates enterprise-grade HTML sanitization powered by DOMPurify with secure, defense-in-depth defaults.

import { safeHTML } from "@skydevlab/securejs";

// Strips scripts, event handlers, iframes, styles, and dangerous protocols
const cleanHTML = safeHTML(untrustedUserContent);
element.innerHTML = cleanHTML;

// Custom overrides
const customClean = safeHTML(untrustedUserContent, {
  allowedTags: ["b", "i", "strong", "em", "p"],
  allowDataURI: false, // Disallows data:* URIs in src attributes (default: false)
});

6. Attribute Handling

Provides safe DOM attribute assignment. Blocks on* inline event handlers (onclick, onerror), dangerous attributes (srcdoc), and sanitizes URL-valued attributes (href, src).

Why safeSetAttribute instead of raw string interpolation? A generic string function safeAttribute(name, value) creates a false sense of security because raw HTML strings depend heavily on surrounding quotes and contexts. safeSetAttribute operates directly on DOM elements with strict contracts.

import { safeSetAttribute, validateAttributeName } from "@skydevlab/securejs";

const btn = document.createElement("button");
safeSetAttribute(btn, "data-id", "user-123"); // true
safeSetAttribute(btn, "onclick", "alert(1)"); // false (rejected!)
safeSetAttribute(btn, "srcdoc", "evil"); // false (rejected!)

const link = document.createElement("a");
safeSetAttribute(link, "href", "javascript:alert(1)"); // false (rejected!)
safeSetAttribute(link, "href", "https://example.com"); // true

7. postMessage Security

Protects cross-window messaging from eavesdropping by enforcing strict destination origins and disallowing wildcard "*" targets.

import { safePostMessage, validateMessageOrigin } from "@skydevlab/securejs";

// 1. Sending: Disallows wildcard '*' by default
safePostMessage(iframeEl.contentWindow, { token: "secret" }, {
  targetOrigin: "https://trusted-partner.com", // Required
});

// 2. Receiving: Validates origin and optional payload schema
window.addEventListener("message", (event) => {
  const isValid = validateMessageOrigin(event, {
    allowedOrigins: ["https://trusted-partner.com"],
    validatePayload: (data): data is { status: string } =>
      typeof data === "object" && data !== null && "status" in data,
  });

  if (!isValid) return; // Discard untrusted message
  handleMessage(event.data);
});

8. Clipboard / Paste Security

Sanitizes pasted text by stripping hidden ASCII control characters, neutralizing Trojan Source bidirectional override characters (\u202E), and truncating oversized payloads to mitigate clipboard bomb DoS.

import { safePaste } from "@skydevlab/securejs";

inputElement.addEventListener("paste", (event) => {
  event.preventDefault();

  const result = safePaste(event, {
    maxLength: 50_000, // Max character limit
    stripControlChars: true, // Strips ASCII 0x00-0x1F (preserves \n, \t)
    stripBidiOverrides: true, // Neutralizes RLO/LRO Trojan Source overrides
  });

  insertText(result.text);
});

9. File & Filename Validation

Client-side file validation to improve user experience and catch spoofing attempts before uploading.

[!IMPORTANT] Client-side file validation is for UX and defense-in-depth only. It does NOT replace server-side validation, MIME sniffing, virus scanning, and sandboxing.

import { validateFile, sanitizeFileName } from "@skydevlab/securejs";

// 1. File Validation
const validation = validateFile(fileInput.files[0], {
  maxSizeBytes: 5 * 1024 * 1024, // 5MB
  minSizeBytes: 1, // Disallow empty files
  allowedTypes: ["image/png", "image/jpeg"],
  allowedExtensions: ["png", "jpg", "jpeg"],
  enforceMimeExtensionConsistency: true, // Catches malware disguised as photo.png
});

if (!validation.valid) {
  alert(validation.errors[0].message);
}

// 2. Filename Sanitization (cross-platform, stripping ../ and Windows reserved device names)
const safeName = sanitizeFileName("../../user<upload>.pdf.exe");
// -> "user-upload.pdf.exe"

10. Safe Web Storage

Hardened wrapper around localStorage and sessionStorage. Protects against Prototype Pollution by stripping __proto__, constructor, and prototype keys during JSON deserialization. Gracefully handles QuotaExceededError and disabled storage (private browsing mode).

[!CAUTION] Web storage is unencrypted and accessible to any script on your origin. NEVER store passwords or cryptographic private keys in localStorage.

import { safeStorage, createSafeStorage } from "@skydevlab/securejs";

// Default pre-configured instance wrapping localStorage
safeStorage.setItem("user", { name: "Alice", role: "admin" });
const user = safeStorage.getItem("user");

// Custom scoped storage instance
const sessionStore = createSafeStorage("session", {
  prefix: "app:v1:", // Automatic key namespacing
  preventPrototypePollution: true, // Default true
  onError: (error, key, op) => {
    console.error(`Storage ${op} failed for key "${key}"`, error);
  },
});

11. Development Warnings

Opt-in diagnostic assistant that reports actionable security warnings in development console without leaking sensitive user data.

import { enableDevWarnings } from "@skydevlab/securejs";

if (process.env.NODE_ENV === "development") {
  enableDevWarnings();
}

What SecureJS Does NOT Replace

SecureJS is designed to complement existing security standards, not replace them. SecureJS does NOT replace:

| Mechanism | Why It Is Still Required | | --------- | ------------------------- | | Content Security Policy (CSP) | Only a strict CSP enforced by the browser can neutralize inline script execution and restrict network exfiltration. | | Server-Side Validation | Any client-side check can be bypassed by an attacker submitting direct HTTP requests. | | Trusted Types | Trusted Types enforce browser-level compile-time guarantees for sink injection. | | HTTPS & Secure Cookies | Transport encryption and HttpOnly; Secure; SameSite cookies are required to protect data in transit and session tokens. | | Authentication & Authorization | Access controls, password hashing, and role checks must be enforced on the server. | | Dependency Auditing | Regular npm package scanning (npm audit) is required to prevent supply chain attacks. |


Package Bundle Size & Footprint

SecureJS is compiled with modern ES modules, full tree-shaking support, and zero framework runtime dependencies:

  • Root bundle: ~9.5 KB gzipped (includes all modules + DOMPurify)
  • Subpath imports:
    • @skydevlab/securejs/url: ~1.4 KB gzipped
    • @skydevlab/securejs/redirect: ~1.6 KB gzipped
    • @skydevlab/securejs/storage: ~1.2 KB gzipped
    • @skydevlab/securejs/files: ~1.8 KB gzipped
    • @skydevlab/securejs/links: ~1.5 KB gzipped

Contributing

We welcome contributions! Please review CONTRIBUTING.md for development setup, testing requirements, and pull request guidelines.


Security Policy

For vulnerability reporting, please see SECURITY.md.


License

MIT © SkyDevLab