Skip to content

dgknbtl/jaga

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🛡️ Jaga

npm version bundle size license typed

Jaga (named after the word for "guard" or "protect") is an ultra-lightweight, zero-dependency security engine that brings Context-Aware XSS Protection to your HTML templates. It's the invisible guardian between your user's data and your application's DOM.

"Don't audit your security. Write it."


Features

  • Smart Context Awareness: Automatically identifies if data is in a <div>, an href, or an onclick.
  • Built-in URL Sanitization: Proactively blocks javascript: and other dangerous protocols.
  • HTML Sanitizer: SSR-native allowlist sanitizer (jagajs/sanitize) — zero dependencies, works in Node.js, Bun, Deno.
  • Secure JSON Injection: j.json(data) safely embeds state into <script> tags, preventing breakout attacks.
  • Smart Minifier: Automatically cleans up unnecessary whitespace between HTML tags (intelligently preserves <pre> and <textarea>).
  • DX Guardrails: Helpful console warnings during development when a security risk or non-CSP-compliant pattern is detected.
  • Nano-sized: Less than 3KB gzipped (Core + Sanitizer). No dependencies, no bloat.

Why Jaga?

Modern frameworks (React, Vue, Angular) are great at escaping data in their templates, but they have blind spots where they leave security entirely to the developer. Jaga is built to fill those gaps.

Environment Secure Context Blind Spot (XSS Risk) Jaga's Solution
SSR / Node.js - String Templates j template tag ✅ Native
React JSX {} dangerouslySetInnerHTML sanitize(html).toString()
Vue {{ }} v-html sanitize(html).toString()
Angular {{ }} bypassSecurityTrustHtml() sanitize(html).toString()
Vanilla JS - element.innerHTML j tag or sanitize().toString()

Note: sanitize() returns a JagaHTML object (not a raw string). This is intentional — it prevents double-escaping when used with Jaga's j tag. When passing to React, Vue, or Angular APIs that expect a plain string, call .toString() explicitly. Jaga is most powerful in SSR and Vanilla JS environments where it works natively without ceremony.


Getting Started

Installation

npm install jagajs

Basic Usage

Jaga uses Context-Aware Escaping. It knows where your data is going and applies the correct security rules automatically.

import { j } from "jagajs";

const userUrl = "javascript:alert(1)";
const userName = '"><img src=x onerror=alert(1)>';

// Jaga handles everything:
const html = j`
  <div title="${userName}">
    <a href="${userUrl}">Profile</a>
  </div>
`;

// Result:
// <div title="&quot;&gt;&lt;img src=x onerror=alert(1)&gt;">
//   <a href="about:blank">Profile</a>
// </div>

Advanced Features

1. HTML Sanitizer (SSR-Ready)

Use this for dangerouslySetInnerHTML or whenever you need to permit some HTML (like from a rich text editor) but block the dangerous parts.

import { sanitize } from "jagajs/sanitize";

// Strip dangerous tags/attrs but keep formatting
const clean = sanitize(userRichText, {
  allowedTags: ["b", "i", "p", "a"],
  allowedAttrs: { a: ["href"] },
});

// Works perfectly with Jaga core
const article = j`<div class="content">${clean}</div>`;

2. Secure JSON Injection

Safely inject server-side state into your frontend without worrying about </script> breakouts.

const state = {
  user: "Admin",
  bio: "</script><script>alert('pwned')</script>",
};

const html = j`
  <script>
    window.__INITIAL_STATE__ = ${j.json(state)};
  </script>
`;

3. List Rendering

Jaga handles arrays seamlessly and securely:

const items = ["Safe", "<b>Bold</b>", "<i>Italic</i>"];
const list = j`<ul>${items.map((i) => j`<li>${i}</li>`)}</ul>`;

4. Smart Minifier

Jaga's j tag automatically minifies your HTML by removing unnecessary whitespace, but it's smart enough to ignore <pre> and <textarea> tags.

const html = j`
  <div>
    <span>Compact but...</span>
    <pre>  This space is preserved!  </pre>
  </div>
`;

5. Secure Nonce for CSP

Easy injection of CSP nonces for inline scripts:

import { j, nonce } from "jagajs";

const myNonce = nonce();
const script = j`<script nonce="${myNonce}">console.log('Safe script');</script>`;

Trusted Types Compatible

Jaga's JagaHTML wrapper is designed to integrate cleanly with the browser's Trusted Types API. When your CSP enforces require-trusted-types-for 'script', you can wrap Jaga's output with your own policy:

const policy = trustedTypes.createPolicy("jaga", {
  // Best Practice: Always sanitize inside the policy itself!
  createHTML: (html) => sanitize(html).toString(),
});

// Now you can safely pass even untrusted strings:
element.innerHTML = policy.createHTML(untrustedHtml);

Native TrustedTypePolicy integration (auto-wrapping) is planned for a future release.


License

MIT © Dogukan Batal

About

The lightweight, context-aware security engine for HTML templates. Zero-dependency XSS protection for modern web apps.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors