agentsclimarketplace

Web security

Skill Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack/plugins/devtools-pack/skills/web-security

When to activate: CSP, CORS, XSS prevention, CSRF, SRI, iframe sandbox, Trusted Types, web security headersFrom its SKILL.md

Install
npx -y skills add Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack --skill web-security

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

3.7 KB, 909 tokens by cl100k_base, as published. Nobody here has run it

Web Security Patterns

Content Security Policy (CSP)

# Strict nonce-based CSP (recommended)
Content-Security-Policy:
  default-src 'self';
  script-src 'nonce-{RANDOM_BASE64}' 'strict-dynamic';
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: https:;
  font-src 'self';
  connect-src 'self' https://api.example.com;
  frame-src 'none';
  object-src 'none';
  base-uri 'self';
  upgrade-insecure-requests;
// Next.js: generate nonce per request
import crypto from 'crypto';

export function middleware(req) {
  const nonce = crypto.randomBytes(16).toString('base64');
  const csp = `script-src 'nonce-${nonce}' 'strict-dynamic'; object-src 'none';`;
  const res = NextResponse.next();
  res.headers.set('Content-Security-Policy', csp);
  res.headers.set('x-nonce', nonce);
  return res;
}

Security Headers

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin

XSS Prevention

// WRONG: direct innerHTML injection
element.innerHTML = userInput;

// RIGHT: textContent for plain text
element.textContent = userInput;

// RIGHT: sanitize HTML when HTML is needed
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput, {
  ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a'],
  ALLOWED_ATTR: ['href', 'title']
});

// React: dangerouslySetInnerHTML must always sanitize
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(html) }} />

Trusted Types

// Enforce via CSP: require-trusted-types-for 'script'
if (window.trustedTypes && window.trustedTypes.createPolicy) {
  const policy = trustedTypes.createPolicy('default', {
    createHTML: (input) => DOMPurify.sanitize(input),
    createScriptURL: (url) => {
      if (new URL(url).origin === location.origin) return url;
      throw new Error('Untrusted script URL');
    }
  });
  element.innerHTML = policy.createHTML(userInput);
}

CORS

// Server (Express)
import cors from 'cors';
app.use(cors({
  origin: ['https://app.example.com'],
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true,
  maxAge: 86400
}));

CSRF Protection

// Double-submit cookie pattern
// Server sets csrf cookie on login
// Client reads cookie and sends as header

async function fetchWithCSRF(url, options = {}) {
  const token = document.cookie.match(/csrf=([^;]+)/)?.[1];
  return fetch(url, {
    ...options,
    headers: { ...options.headers, 'X-CSRF-Token': token }
  });
}

Subresource Integrity (SRI)

<!-- Hash ensures CDN file hasn't been tampered with -->
<script
  src="https://cdn.example.com/lib.min.js"
  integrity="sha384-abc123..."
  crossorigin="anonymous">
</script>
# Generate SRI hash
openssl dgst -sha384 -binary lib.min.js | openssl base64 -A

iframe Sandbox

<!-- Allow only what's needed -->
<iframe
  src="https://widget.example.com"
  sandbox="allow-scripts allow-same-origin"
  allow="payment"
  referrerpolicy="no-referrer"
  loading="lazy">
</iframe>

Cookie Security

Set-Cookie: session=abc; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=3600

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,851. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.