Skip to content

A03 — Injection

Allowlist-based HTML sanitization (InputSanitizer) plus schema, email, URL, and length validation (InputValidator).

Core API (@owasp-webshield/core)

js
import {
  INJECTION_DEFENSE_TYPES,
  InputSanitizer,
  InputValidator
} from "@owasp-webshield/core";

const sanitizer = new InputSanitizer("moderate");
const cleanHtml = sanitizer.sanitizeHTML('<a href="javascript:alert(1)" onclick="alert(1)">safe</a>');

const validator = new InputValidator();
const validation = validator.validateSchema(
  { email: "user@example.com", password: "secret-123" },
  {
    email: { required: true, pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/ },
    password: { required: true, minLength: 8 }
  }
);

validator.validateEmail("user@example.com");
validator.validateUrl("https://example.com/profile");
validator.validateLength("secret-123", { min: 8, max: 64 });
console.log(cleanHtml, validation.valid, INJECTION_DEFENSE_TYPES);

strict vs moderate

InputSanitizer is tokenizer-based, not regex-based — it closes bypasses via unclosed <script> tags, /-separated event handlers (e.g. <svg/onload=...>), and obfuscated javascript: URLs. The moderate profile allows a fixed set of formatting tags; strict strips all markup.

React Adapter (@owasp-webshield/react)

jsx
import React from "react";
import { SanitizedText, useInputSanitizer } from "@owasp-webshield/react";

export function CommentPreview({ rawHtml }) {
  const sanitizer = useInputSanitizer("moderate");
  const clean = sanitizer.sanitizeHTML(rawHtml);

  return (
    <div>
      <div>{clean}</div>
      <SanitizedText profile="strict" html={rawHtml} />
    </div>
  );
}

Released under the Apache 2.0 License.