struct Components::SafeURL

Overview

SafeURL is a typed, validated URL for the representative URL-bearing attribute sinks the hardening proposal §3.3 calls out: href, src, action, formaction, poster, cite, ping, SVG href/xlink:href, and <meta http-equiv="refresh" content>.

HTML-escaping does not neutralize this class of sink — javascript:, vbscript:, and similar script-executing schemes survive HTML-escaping unchanged. SafeURL closes that gap with an explicit scheme allowlist.

srcset is NOT covered by SafeURL — it is a URL list with descriptors ("a.jpg 1x, b.jpg 2x"), not a single URL, and needs its own parser. See SafeSrcSet.

Defined in:

components/safe/safe_url.cr

Constant Summary

ALLOWED_SCHEMES = {"http", "https", "mailto", "tel"}

Schemes permitted in a URL-bearing attribute. Everything else (javascript:, data:, vbscript:, file:, blob:, ...) is rejected. Relative URLs (no scheme — paths, fragments, queries, protocol-relative //host/...) are always allowed: the browser resolves them against the current document/scheme, so they cannot smuggle a script-executing scheme.

Constructors

Class Method Summary

Instance Method Summary

Constructor Detail

def self.parse!(url : String) : SafeURL #

Validates and returns a SafeURL, or raises UnsafeURLError explaining why. This is the construction-time ban: passing SafeURL.parse!("javascript:alert(1)") raises instead of silently producing a value that would render into an href.


[View source]
def self.unsafe(url : String, reason : String) : SafeURL #

Explicit, loud opt-out for an intended-but-not-yet-allowlisted scheme (e.g. an app-specific custom URI scheme). Mirrors SafeHTML.unsafereason: is mandatory and this is the one auditable hole in SafeURL.


[View source]

Class Method Detail

def self.parse(url : String) : SafeURL | Nil #

Validates and returns a SafeURL, or nil if the URL is unsafe.


[View source]

Instance Method Detail

def ==(other : SafeURL) : Bool #

[View source]
def to_s(io : IO) : Nil #
Description copied from struct Struct

Same as #inspect(io).


[View source]
def to_s : String #
Description copied from class Object

Returns a nicely readable and concise string representation of this object, typically intended for users.

This method should usually not be overridden. It delegates to #to_s(IO) which can be overridden for custom implementations.

Also see #inspect.


[View source]