erb ruby javascript 27 lines · 3 tabs

Cross site scripting defense with output encoding and CSP

Kai Nakamura Apr 2026
3 tabs
<h1><%= @post.title %></h1>
<p><%= @post.author_name %></p>

<%# Only sanitized rich text should be rendered as HTML %>
<div class="prose"><%= sanitize(@post.body_html, tags: %w[p a ul ol li strong em code], attributes: %w[href]) %></div>
3 files · erb, ruby, javascript Explain with highlit

XSS defense works best in layers: correct output encoding, sanitization for trusted rich text only, and a restrictive Content-Security-Policy. I avoid storing untrusted HTML unless there is a strong product reason. When rich content is required, I sanitize at write time and keep CSP strict enough to limit blast radius.


Related snips

ruby
# Vulnerable: user input is concatenated directly into SQL.
email = params[:email]
password = params[:password]

sql = "SELECT * FROM users WHERE email = '#{email}' AND password_hash = '#{password}'"
user = ActiveRecord::Base.connection.execute(sql).first

SQL injection prevention with unsafe and safe query patterns

sql-injection owasp database
by Kai Nakamura 3 tabs
typescript
import { defaultSchema, type Schema } from 'hast-util-sanitize';

export const markdownSchema: Schema = {
  ...defaultSchema,
  attributes: {
    ...defaultSchema.attributes,

Safe markdown rendering (remark + rehype)

markdown security remark
by codesnips 3 tabs
ruby
Rails.application.config.content_security_policy do |policy|
  policy.default_src :self
  policy.font_src    :self, :https, :data
  policy.img_src     :self, :https, :data, "https://cdn.example.com"
  policy.object_src  :none
  policy.script_src  :self, :https

Content Security Policy (CSP) Starter

rails security csp
by codesnips 3 tabs
typescript
import { JSDOM } from 'jsdom';
import createDOMPurify, { DOMPurifyI } from 'dompurify';

const { window } = new JSDOM('');
const DOMPurify: DOMPurifyI = createDOMPurify(window as unknown as Window);

Sanitize user HTML safely (DOMPurify + JSDOM)

security html dompurify
by codesnips 2 tabs
ruby
require "loofah"

class HtmlSanitizer
  ALLOWED_TAGS  = %w[p br a strong em ul ol li blockquote code pre h2 h3].freeze
  ALLOWED_ATTRS = %w[href title].freeze
  SAFE_SCHEMES  = %w[http https mailto].freeze

Safer HTML Sanitization Pipeline

rails security xss
by codesnips 4 tabs
plaintext
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off

SecRule ARGS|REQUEST_HEADERS|XML:/* "@detectSQLi" \
  "id:1001,phase:2,deny,status:403,log,msg:'Potential SQLi detected'"

ModSecurity WAF rules for common web attack patterns

waf modsecurity web-security
by Kai Nakamura 1 tab

Share this code

Here's the card — post it anywhere.

Cross site scripting defense with output encoding and CSP — share card
Link copied