safehtml

package module
v0.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 8, 2023 License: BSD-3-Clause Imports: 14 Imported by: 0

README

Safe HTML for Go

safehtml provides immutable string-like types that wrap web types such as HTML, JavaScript and CSS. These wrappers are safe by construction against XSS and similar web vulnerabilities, and they can only be interpolated in safe ways. You can read more about our approach to web security in our whitepaper, or this OWASP talk.

Additional subpackages provide APIs for managing exceptions to the safety rules, and a template engine with a syntax and interface that closely matches html/template. You can refer to the godoc for each (sub)package for the API documentation and code examples. More end-to-end demos are available in example_test.go.

This is not an officially supported Google product.

Documentation

Overview

Package safehtml provides immutable string-like types which represent values that are guaranteed to be safe, by construction or by escaping or sanitization, to use in various HTML contexts and with various DOM APIs.

Index

Constants

View Source
const InnocuousPropertyValue = "zGoSafezInvalidPropertyValue"

InnocuousPropertyValue is an innocuous property generated by filter when its input unsafe.

View Source
const InnocuousURL = "about:invalid#zGoSafez"

InnocuousURL is an innocuous URL generated by URLSanitized when passed an unsafe URL.

about:invalid is registered in http://www.w3.org/TR/css3-values/#about-invalid, and "references a non-existent document with a generic error condition. It can be used when a URI is necessary, but the default value shouldn't be resolveable as any type of document."

http://tools.ietf.org/html/rfc6694#section-2.1 permits about URLs to contain a fragment, which is not to be considered when determining if an about URL is well-known.

Variables

This section is empty.

Functions

This section is empty.

Types

type HTML

type HTML struct {
	// contains filtered or unexported fields
}

An HTML is an immutable string-like type that is safe to use in HTML contexts in DOM APIs and HTML documents.

HTML guarantees that its value as a string will not cause untrusted script execution when evaluated as HTML in a browser.

Values of this type are guaranteed to be safe to use in HTML contexts, such as assignment to the innerHTML DOM property, or interpolation into an HTML template in HTML PC_DATA context, in the sense that the use will not result in a Cross-site Scripting (XSS) vulnerability.

func HTMLConcat

func HTMLConcat(htmls ...HTML) HTML

HTMLConcat returns an HTML which contains, in order, the string representations of the given htmls.

func HTMLEscaped

func HTMLEscaped(text string) HTML

HTMLEscaped returns an HTML whose value is text, with the characters [&<>"'] escaped.

text is coerced to interchange valid, so the resulting HTML contains only valid UTF-8 characters which are legal in HTML and XML.

func (HTML) String

func (h HTML) String() string

String returns the string form of the HTML.

type HTMLer

type HTMLer interface {
	HTML() HTML
}

HTMLer is implemented by any value that has an HTML method, which defines the safe HTML format for that value.

type Identifier

type Identifier struct {
	// contains filtered or unexported fields
}

A Identifier is an immutable string-like type that is safe to use in HTML contexts as an identifier for HTML elements. For example, it is unsafe to insert an untrusted string into a

<img name="..."></img>

context since the string may be controlled by an attacker who can assign it a value that masks existing DOM properties (i.e. DOM Clobbering). An attacker may also be able to force legitimate Javascript code, which uses document.getElementsByName(...) to read DOM elements, to refer to this element. This may lead to unintended side effects, particularly if that element contains attacker-controlled data. It is, however, safe to use an Identifier in this context since its value is known to be partially or fully under application control.

In order to ensure that an attacker cannot influence the Identifier value, an Identifier can only be instantiated from a compile-time constant string literal prefix.

Note that Identifier is Go-specific and therefore does not have a Proto form for cross-language use.

func IdentifierFromConstant

func IdentifierFromConstant(value stringConstant) Identifier

IdentifierFromConstant constructs an Identifier with its underlying identifier set to the given string value, which must be an untyped string constant. It panics if value does not start with an alphabetic rune or contains any non-alphanumeric runes other than '-' and '_'.

func IdentifierFromConstantPrefix

func IdentifierFromConstantPrefix(prefix stringConstant, value string) Identifier

IdentifierFromConstantPrefix constructs an Identifier with its underlying string set to the string formed by joining prefix, which must be an untyped string constant, and value with a hyphen. It panics if prefix or value contain any non-alphanumeric runes other than '-' and '_', or if prefix does not start with an alphabetic rune.

func (Identifier) String

func (i Identifier) String() string

String returns the string form of the Identifier.

type Script

type Script struct {
	// contains filtered or unexported fields
}

A Script is an immutable string-like type which represents JavaScript code and guarantees that its value, as a string, will not cause execution of unconstrained attacker controlled code (cross-site scripting) when evaluated as JavaScript in a browser.

Script's string representation can safely be interpolated as the content of a script element within HTML, and can safely be passed to DOM properties and functions which expect JavaScript. In these cases, the Script string should not be escaped. Script's string representation can also be safely used as the value for on* attribute handlers in HTML, though the Script string must be escaped before such use.

Note that the Script might contain text that is attacker-controlled but that text should have been interpolated with appropriate escaping, sanitization and/or validation into the right location in the script, such that it is highly constrained in its effect (for example, it had to match a set of allowed words).

In order to ensure that an attacker cannot influence the Script value, a Script can only be instantiated from compile-time constant string literals or security-reviewed unchecked conversions, but never from arbitrary string values potentially representing untrusted user input.

func ScriptFromConstant

func ScriptFromConstant(script stringConstant) Script

ScriptFromConstant constructs a Script with its underlying script set to the given script, which must be an untyped string constant.

No runtime validation or sanitization is performed on script; being under application control, it is simply assumed to comply with the Script contract.

func ScriptFromDataAndConstant

func ScriptFromDataAndConstant(name stringConstant, data interface{}, script stringConstant) (Script, error)

ScriptFromDataAndConstant constructs a Script of the form

var name = data; script

where name is the supplied variable name, data is the supplied data value encoded as JSON using encoding/json.Marshal, and script is the supplied JavaScript statement or sequence of statements. The supplied name and script must both be untyped string constants. It returns an error if name is not a valid Javascript identifier or JSON encoding fails.

No runtime validation or sanitization is performed on script; being under application control, it is simply assumed to comply with the Script contract.

func (Script) String

func (s Script) String() string

String returns the string form of the Script.

type Style

type Style struct {
	// contains filtered or unexported fields
}

A Style is an immutable string-like type which represents a sequence of CSS declarations (property_name1: property_value1; property_name2: property_value2; ...) and guarantees that its value will not cause untrusted script execution (cross-site scripting) when evaluated as CSS in a browser.

Style's string representation can safely be:

  • Interpolated as the content of a quoted HTML style attribute. However, the Style string must be HTML-attribute-escaped before interpolation.
  • Interpolated as the content of a {}-wrapped block within a StyleSheet. '<' runes in the Style string must be CSS-escaped before interpolation. The Style string is also guaranteed not to be able to introduce new properties or elide existing ones.
  • Interpolated as the content of a {}-wrapped block within an HTML <style> element. '<' runes in the Style string must be CSS-escaped before interpolation.
  • Assigned to the style property of a DOM node. The Style string should not be escaped before being assigned to the property.

In addition, values of this type are composable, that is, for any two Style values |style1| and |style2|, style1.style() + style2.style() is itself a value that satisfies the Style type constraint.

func StyleFromConstant

func StyleFromConstant(style stringConstant) Style

StyleFromConstant constructs a Style with its underlying style set to the given style, which must be an untyped string constant, and panics if the style string does not pass basic syntax checks.

Users of this function must ensure themselves that the style:

  • Does not contain unsafe CSS.
  • Does not contain literal angle brackets. Otherwise, it could be unsafe to place a Style into the contents of a <style> element where it can't be HTML escaped (see http://www.w3.org/International/questions/qa-escapes). For example, if the Style containing "font: 'foo <style/><script>evil</script>'" was interpolated within a <style> tag, it would then break out of the style context into HTML.
  • Does not end in a property value or property name context. For example, a value of "background:url(\"" or "font-" does not satisfy the Style type contract. This rule is enforced to ensure composability: concatenating two incomplete strings that themselves do not contain unsafe CSS can result in an overall string that does. For example, if "javascript:evil())\"" is appended to "background:url(\"", the resulting string may result in the execution of a malicious script.

The style may, however, contain literal single or double quotes (for example, in the "content" property). Therefore, the entire style string must be escaped when used in a style attribute.

The following example values comply with Style's type contract:

width: 1em;
height:1em;
width: 1em;height: 1em;
background:url('http://url');

In addition, the empty string is safe for use in a style attribute.

The following example values do NOT comply with this type's contract:

background: red    --- missing a trailing semi-colon
background:        --- missing a value and a trailing semi-colon
1em                --- missing an attribute name, which provides context
                       for the value

See also http://www.w3.org/TR/css3-syntax/.

func StyleFromProperties

func StyleFromProperties(properties StyleProperties) Style

StyleFromProperties constructs a Style containining properties whose values are set in properties. The contents of the returned Style will be of the form

property_1:val_1;property2:val_2; ... ;property_n:val_n;

This syntax is defined in https://www.w3.org/TR/css-style-attr/.

All property values are validated and, if necessary, modified to ensure that their inclusion in a HTML style attribute does not result in untrusted script execution, the addition of new properties, or the removal of existing properties. Please refer to the StyleProperties documentation for validation rules.

The constructed Style is guaranteed to fulfill its type contract, but is not guaranteed to be semantically valid CSS.

func (Style) String

func (s Style) String() string

String returns the string form of the Style.

type StyleProperties

type StyleProperties struct {
	// BackgroundImageURLs contains URL values for the background-image property.
	// These values val_1, val_2, ..., val_n will be passed through URLSanitized and CSS-escaped in
	// StyleFromProperties, then interpolated into to a comma-separated list of CSS URLs of the form
	//    url("val_1"), url("val_2"), ..., url("val_n")
	// See https://www.w3.org/TR/CSS2/syndata.html#value-def-uri and https://drafts.csswg.org/css-backgrounds-3/#layering.
	BackgroundImageURLs []string
	// FontFamily values are used, comma-separated, as the font-family property.
	//    * Names starting with a Latin alphabet runes and containing only Latin alphabets and hyphens will be included unquoted.
	//    * Names enclosed in double quote literals (e.g. `"21st Century"`) will be CSS-escaped without the outermost quotes,
	//      then included within double quotes.
	//    * All other names will be CSS-escaped, and included within double quotes.
	// See https://drafts.csswg.org/css-fonts-3/#font-family-prop.
	FontFamily []string
	// Display must consist of only ASCII alphabetic or '-' runes.
	// Non-conforming values will be replaced by InnocuousPropertyValue in
	// StyleFromProperties.
	Display string
	// The following values can only contain allowed runes, that is, alphanumerics,
	// space, tab, and the set [+-.!#%_/*]. In addition, comment markers "//", "/*",
	// and "*/" are disallowed. Non-conforming values will be replaced by
	// InnocuousPropertyValue in StyleFromProperties.
	BackgroundColor    string
	BackgroundPosition string
	BackgroundRepeat   string
	BackgroundSize     string
	Color              string
	Height             string
	Width              string
	Left               string
	Right              string
	Top                string
	Bottom             string
	FontWeight         string
	Padding            string
	// Note: this property might allow clickjacking, but the risk is limited without
	// the ability to set the position property to "absolute" or "fixed".
	ZIndex string
}

StyleProperties contains property values for CSS properties whose names are the hyphen-separated form of the field names. These values will be validated by StyleFromProperties before being included in a Style.

For example, BackgroundPosition contains the value for the "background-position" property, and Display contains the value for the "display" property.

type StyleSheet

type StyleSheet struct {
	// contains filtered or unexported fields
}

A StyleSheet is an immutable string-like type which represents a CSS style sheet and guarantees that its value, as a string, will not cause untrusted script execution (cross-site scripting) when evaluated as CSS in a browser.

StyleSheet's string representation can safely be interpolated as the content of a style element within HTML. The StyleSheet string should not be escaped before interpolation.

func CSSRule

func CSSRule(selector string, style Style) (StyleSheet, error)

CSSRule constructs a StyleSheet containng a CSS rule of the form:

selector{style}

It returns an error if selector contains disallowed characters or unbalanced brackets.

The constructed StyleSheet value is guaranteed to fulfill its type contract, but is not guaranteed to be semantically valid CSS.

func StyleSheetFromConstant

func StyleSheetFromConstant(styleSheet stringConstant) StyleSheet

StyleSheetFromConstant constructs a StyleSheet with the underlying stylesheet set to the given styleSheet, which must be an untyped string constant.

No runtime validation or sanitization is performed on script; being under application control, it is simply assumed to comply with the StyleSheet contract.

func (StyleSheet) String

func (s StyleSheet) String() string

String returns the string form of the StyleSheet.

type TrustedResourceURL

type TrustedResourceURL struct {
	// contains filtered or unexported fields
}

A TrustedResourceURL is an immutable string-like type referencing the application’s own, trusted resources. It can be used to safely load scripts, CSS and other sensitive resources without the risk of untrusted code execution. For example, it is unsafe to insert a plain string in a

<script src=“...”></script>

context since the URL may originate from untrusted user input and the script it is pointing to may thus be controlled by an attacker. It is, however, safe to use a TrustedResourceURL since its value is known to never have left application control.

In order to ensure that an attacker cannot influence the TrustedResourceURL value, a TrustedResourceURL can only be instantiated from compile-time constant string literals, command-line flags or a combination of the two, but never from arbitrary string values potentially representing untrusted user input.

Additionally, TrustedResourceURLs can be serialized and passed along within the application via protocol buffers. It is the application’s responsibility to ensure that the protocol buffers originate from within the application itself and not from an external entity outside its trust domain.

Note that TrustedResourceURLs can also use absolute paths (starting with '/') and relative paths. This allows the same binary to be used for different hosts without hard-coding the hostname in a string literal.

func TrustedResourceURLAppend

func TrustedResourceURLAppend(t TrustedResourceURL, s string) (TrustedResourceURL, error)

TrustedResourceURLAppend URL-escapes a string and appends it to the TrustedResourceURL.

This function can only be used if the TrustedResourceURL has a prefix of one of the following forms:

  • `https://<origin>/`
  • `//<origin>/`
  • `/<pathStart>`
  • `about:blank#`

`<origin>` must contain only alphanumerics, '.', ':', '[', ']', or '-', and `<pathStart>` is any character except `/` and `\`.

func TrustedResourceURLFormatFromConstant

func TrustedResourceURLFormatFromConstant(format stringConstant, args map[string]string) (TrustedResourceURL, error)

TrustedResourceURLFormatFromConstant constructs a TrustedResourceURL from a format string, which must be an untyped string constant, and string arguments.

Arguments are specified as a map of labels, which must contain only alphanumeric and '_' runes, to string values. Each `%{<label>}` marker in the format string is replaced by the string value identified by <label> after it has been URL-escaped. Arguments that do not match any label in the format string are ignored.

The format string must have a prefix of one of the following forms:

  • `https://<origin>/`
  • `//<origin>/`
  • `/<pathStart>`
  • `about:blank#`

`<origin>` must contain only alphanumerics, '.', ':', '[', ']', or '-', and `<pathStart>` is any character except `/` and `\`.

func TrustedResourceURLFormatFromFlag

func TrustedResourceURLFormatFromFlag(format flag.Value, args map[string]string) (TrustedResourceURL, error)

TrustedResourceURLFormatFromFlag is a variant of TrustedResourceURLFormatFromConstant that constructs a TrustedResourceURL from a format string, which is given as a flag.Value, and string arguments.

See TrustedResourceURLFormatFromConstant for more details about format string markers and validation.

func TrustedResourceURLFromConstant

func TrustedResourceURLFromConstant(url stringConstant) TrustedResourceURL

TrustedResourceURLFromConstant constructs a TrustedResourceURL with its underlying URL set to the given url, which must be an untyped string constant.

No runtime validation or sanitization is performed on url; being under application control, it is simply assumed to comply with the TrustedResourceURL type contract.

func TrustedResourceURLFromFlag

func TrustedResourceURLFromFlag(value flag.Value) TrustedResourceURL

TrustedResourceURLFromFlag returns a TrustedResourceURL containing the string representation of the retrieved value of the flag.

In a server setting, flags are part of the application's deployment configuration and are hence considered application-controlled.

func TrustedResourceURLWithParams

func TrustedResourceURLWithParams(t TrustedResourceURL, params map[string]string) TrustedResourceURL

TrustedResourceURLWithParams constructs a new TrustedResourceURL with the given key-value pairs added as query parameters.

Map entries with empty keys or values are ignored. The order of appended keys is guaranteed to be stable but may differ from the order in input.

func (TrustedResourceURL) String

func (t TrustedResourceURL) String() string

String returns the string form of the TrustedResourceURL.

type URL

type URL struct {
	// contains filtered or unexported fields
}

A URL is an immutable string-like type that is safe to use in URL contexts in DOM APIs and HTML documents.

URL guarantees that its value as a string will not cause untrusted script execution when evaluated as a hyperlink URL in a browser.

Values of this type are guaranteed to be safe to use in URL/hyperlink contexts, such as assignment to URL-valued DOM properties, in the sense that the use will not result in a Cross-site Scripting (XSS) vulnerability. Similarly, URLs can be interpolated into the URL context of an HTML template (e.g. inside a href attribute). However, appropriate HTML-escaping must still be applied.

Note that this type's contract does not imply any guarantees regarding the resource the URL refers to. In particular, URLs are not safe to use in a context where the referred-to resource is interpreted as trusted code, e.g., as the src of a script tag. For safely loading trusted resources, use the TrustedResourceURL type.

func URLSanitized

func URLSanitized(url string) URL

URLSanitized returns a URL whose value is url, validating that the input string matches a pattern of commonly used safe URLs. If url fails validation, this method returns a URL containing InnocuousURL.

url may be a URL with an explicit scheme that is not javascript, or a relative URL, i.e. a URL without a scheme. Specifically, a relative URL may be scheme-relative, absolute-path-relative, or path-relative. See http://url.spec.whatwg.org/#concept-relative-url.

If the URL has an explicit scheme, it should only contain characters allowed by the URL specification, i.e. alphanumeric or [+-.].

No attempt is made at validating that the URL percent-decodes to structurally valid or interchange-valid UTF-8 since the percent-decoded representation is unsafe to use in an HTML context regardless of UTF-8 validity.

func (URL) String

func (u URL) String() string

String returns the string form of the URL.

type URLSet

type URLSet struct {
	// contains filtered or unexported fields
}

URLSet corresponds to the value of a srcset attribute outside a TrustedResourceURL context.

func URLSetSanitized

func URLSetSanitized(str string) URLSet

URLSetSanitized returns a safe srcset by individually vetting each substring that specifies a URL.

https://html.spec.whatwg.org/multipage/images.html#srcset-attributes

func (URLSet) String

func (s URLSet) String() string

String returns the string content of a URLSet

Directories

Path Synopsis
internal
raw
Package raw provides a coordination point for package safehtml, package uncheckedconversions, package legacyconversions, and package testconversions.
Package raw provides a coordination point for package safehtml, package uncheckedconversions, package legacyconversions, and package testconversions.
safehtmlutil
Package safehtmlutil contains functions shared by package safehtml and safehtml/template.
Package safehtmlutil contains functions shared by package safehtml and safehtml/template.
template/raw
Package raw provides a coordination point for package safehtml/template and package safehtml/template/uncheckedconversions.
Package raw provides a coordination point for package safehtml/template and package safehtml/template/uncheckedconversions.
Package legacyconversions provides functions to create values of package safehtml types from plain strings.
Package legacyconversions provides functions to create values of package safehtml types from plain strings.
Package template (safehtml/template) implements data-driven templates for generating HTML output safe against code injection.
Package template (safehtml/template) implements data-driven templates for generating HTML output safe against code injection.
uncheckedconversions
Package uncheckedconversions provides functions to create values of safehtml/template types from plain strings.
Package uncheckedconversions provides functions to create values of safehtml/template types from plain strings.
Package testconversions provides functions to to create arbitrary values of package safehtml types for use by tests only.
Package testconversions provides functions to to create arbitrary values of package safehtml types for use by tests only.
Package uncheckedconversions provides functions to create values of package safehtml types from plain strings.
Package uncheckedconversions provides functions to create values of package safehtml types from plain strings.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL