New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

safevalues

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

safevalues - npm Package Compare versions

Comparing version 1.0.1 to 1.1.0

16

dist/cjs/builders/html_sanitizer/html_sanitizer_builder.d.ts

@@ -32,5 +32,6 @@ /**

/**
* Allows the set of data attributes passed.
* Allows all or a definite set of data attributes passed.
*
* These values must be prefixed with "data-"
* When called without arguments, all data attributes are allowed.
* When a set of attributes is passed, its values must be prefixed with "data-"
*

@@ -40,3 +41,3 @@ * If called with onlyAllowElements or onlyAllowAttributes, those methods must

*/
allowDataAttributes(attributes: string[]): this;
allowDataAttributes(attributes?: string[]): this;
/**

@@ -124,5 +125,14 @@ * Preserves style attributes. Note that the sanitizer won't parse and

private transitionsAllowed;
private openShadow;
allowAnimations(): this;
allowTransitions(): this;
/**
* Sets the shadow DOM mode to 'open'.
*
* While this method is not formally restricted, it can potentially be used to
* bypass the security guarantees of the CSS sanitizer. If you need open
* shadow DOM, please contact ise-web-members@ to discuss your use case.
*/
withOpenShadow(): this;
/**
* Builds a CSS sanitizer.

@@ -129,0 +139,0 @@ *

43

dist/cjs/builders/html_sanitizer/html_sanitizer_builder.js

@@ -42,3 +42,3 @@ "use strict";

}
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(allowedElements, allowedElementPolicies, this.sanitizerTable.allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies);
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(allowedElements, allowedElementPolicies, this.sanitizerTable.allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;

@@ -70,3 +70,3 @@ }

}
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(allowedElements, allowedElementPolicies, this.sanitizerTable.allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies);
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(allowedElements, allowedElementPolicies, this.sanitizerTable.allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;

@@ -100,9 +100,10 @@ }

}
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(this.sanitizerTable.allowedElements, elementPolicies, allowedGlobalAttributes, globalAttributePolicies);
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(this.sanitizerTable.allowedElements, elementPolicies, allowedGlobalAttributes, globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;
}
/**
* Allows the set of data attributes passed.
* Allows all or a definite set of data attributes passed.
*
* These values must be prefixed with "data-"
* When called without arguments, all data attributes are allowed.
* When a set of attributes is passed, its values must be prefixed with "data-"
*

@@ -113,2 +114,8 @@ * If called with onlyAllowElements or onlyAllowAttributes, those methods must

allowDataAttributes(attributes) {
if (attributes === undefined) {
const globallyAllowedAttributePrefixes = new Set(this.sanitizerTable.globallyAllowedAttributePrefixes);
globallyAllowedAttributePrefixes.add('data-');
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, this.sanitizerTable.allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies, globallyAllowedAttributePrefixes);
return this;
}
const allowedGlobalAttributes = new Set(this.sanitizerTable.allowedGlobalAttributes);

@@ -121,3 +128,3 @@ for (const attribute of attributes) {

}
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies);
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;

@@ -137,3 +144,3 @@ }

});
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, this.sanitizerTable.allowedGlobalAttributes, globalAttributePolicies);
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, this.sanitizerTable.allowedGlobalAttributes, globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;

@@ -149,3 +156,3 @@ }

allowedGlobalAttributes.add('class');
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies);
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;

@@ -160,3 +167,3 @@ }

allowedGlobalAttributes.add('id');
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies);
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;

@@ -180,3 +187,3 @@ }

.add('list');
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies);
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;

@@ -253,2 +260,3 @@ }

this.transitionsAllowed = false;
this.openShadow = false;
}

@@ -264,2 +272,13 @@ allowAnimations() {

/**
* Sets the shadow DOM mode to 'open'.
*
* While this method is not formally restricted, it can potentially be used to
* bypass the security guarantees of the CSS sanitizer. If you need open
* shadow DOM, please contact ise-web-members@ to discuss your use case.
*/
withOpenShadow() {
this.openShadow = true;
return this;
}
/**
* Builds a CSS sanitizer.

@@ -281,3 +300,3 @@ *

const styleAttributeSanitizer = (cssText) => (0, sanitizer_js_1.sanitizeStyleAttribute)(cssText, allowlists_js_1.CSS_PROPERTY_ALLOWLIST, allowlists_js_1.CSS_FUNCTION_ALLOWLIST, this.resourceUrlPolicy, propertyDiscarders);
return new html_sanitizer_js_1.HtmlSanitizerImpl(this.sanitizerTable, secrets_js_1.secretToken, styleElementSanitizer, styleAttributeSanitizer, this.resourceUrlPolicy);
return new html_sanitizer_js_1.HtmlSanitizerImpl(this.sanitizerTable, secrets_js_1.secretToken, styleElementSanitizer, styleAttributeSanitizer, this.resourceUrlPolicy, this.openShadow);
}

@@ -295,5 +314,5 @@ extendSanitizerTableForCss() {

allowedGlobalAttributes.add('class');
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, globalAttributePolicies);
this.sanitizerTable = new sanitizer_table_js_1.SanitizerTable(allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
}
}
exports.CssSanitizerBuilder = CssSanitizerBuilder;

@@ -49,4 +49,5 @@ /**

private readonly resourceUrlPolicy?;
private readonly openShadow?;
private changes;
constructor(sanitizerTable: SanitizerTable, token: object, styleElementSanitizer?: CssSanitizationFn | undefined, styleAttributeSanitizer?: CssSanitizationFn | undefined, resourceUrlPolicy?: ResourceUrlPolicy | undefined);
constructor(sanitizerTable: SanitizerTable, token: object, styleElementSanitizer?: CssSanitizationFn | undefined, styleAttributeSanitizer?: CssSanitizationFn | undefined, resourceUrlPolicy?: ResourceUrlPolicy | undefined, openShadow?: boolean | undefined);
sanitizeAssertUnchanged(html: string): SafeHtml;

@@ -53,0 +54,0 @@ sanitize(html: string): SafeHtml;

@@ -22,3 +22,3 @@ "use strict";

class HtmlSanitizerImpl {
constructor(sanitizerTable, token, styleElementSanitizer, styleAttributeSanitizer, resourceUrlPolicy) {
constructor(sanitizerTable, token, styleElementSanitizer, styleAttributeSanitizer, resourceUrlPolicy, openShadow) {
this.sanitizerTable = sanitizerTable;

@@ -28,2 +28,3 @@ this.styleElementSanitizer = styleElementSanitizer;

this.resourceUrlPolicy = resourceUrlPolicy;
this.openShadow = openShadow;
this.changes = [];

@@ -57,3 +58,4 @@ (0, secrets_js_1.ensureTokenIsValid)(token);

const elem = document.createElement('safevalues-with-css');
const shadow = elem.attachShadow({ mode: 'closed' });
const mode = this.openShadow ? 'open' : 'closed';
const shadow = elem.attachShadow({ mode });
const sanitized = this.sanitizeToFragmentInternal(htmlWithCss, inertDocument);

@@ -60,0 +62,0 @@ const internalStyle = document.createElement('style');

@@ -271,2 +271,3 @@ "use strict";

'checked',
'cite',
'color',

@@ -276,2 +277,3 @@ 'cols',

'controls',
'controlslist',
'datetime',

@@ -302,2 +304,3 @@ 'disabled',

'placeholder',
'poster',
'preload',

@@ -356,8 +359,2 @@ 'rel',

[
'cite',
{
policyAction: sanitizer_table_js_1.AttributePolicyAction.KEEP_AND_SANITIZE_URL,
},
],
[
'loading',

@@ -374,8 +371,2 @@ {

[
'poster',
{
policyAction: sanitizer_table_js_1.AttributePolicyAction.KEEP_AND_SANITIZE_URL,
},
],
[
'target',

@@ -396,2 +387,2 @@ {

*/
exports.DEFAULT_SANITIZER_TABLE = new sanitizer_table_js_1.SanitizerTable(new Set(ALLOWED_ELEMENTS), new Map(ELEMENT_POLICIES), new Set(ALLOWED_GLOBAL_ATTRIBUTES), new Map(GLOBAL_ATTRIBUTE_POLICIES));
exports.DEFAULT_SANITIZER_TABLE = new sanitizer_table_js_1.SanitizerTable(new Set(ALLOWED_ELEMENTS), new Map(ELEMENT_POLICIES), new Set(ALLOWED_GLOBAL_ATTRIBUTES), new Map(GLOBAL_ATTRIBUTE_POLICIES), undefined);

@@ -12,4 +12,4 @@ /**

readonly globalAttributePolicies: ReadonlyMap<string, AttributePolicy>;
readonly globallyAllowedAttributePrefixes?: ReadonlySet<string> | undefined;
constructor(allowedElements: ReadonlySet<string>, elementPolicies: ReadonlyMap<string, ElementPolicy>, allowedGlobalAttributes: ReadonlySet<string>, globalAttributePolicies: ReadonlyMap<string, AttributePolicy>, globallyAllowedAttributePrefixes?: ReadonlySet<string> | undefined);
readonly globallyAllowedAttributePrefixes: ReadonlySet<string> | undefined;
constructor(allowedElements: ReadonlySet<string>, elementPolicies: ReadonlyMap<string, ElementPolicy>, allowedGlobalAttributes: ReadonlySet<string>, globalAttributePolicies: ReadonlyMap<string, AttributePolicy>, globallyAllowedAttributePrefixes: ReadonlySet<string> | undefined);
isAllowedElement(elementName: string): boolean;

@@ -16,0 +16,0 @@ getAttributePolicy(attributeName: string, elementName: string): AttributePolicy;

@@ -10,2 +10,2 @@ /**

*/
export declare const SECURITY_SENSITIVE_ATTRIBUTES: readonly ["src", "srcdoc", "codebase", "data", "href", "rel", "action", "formaction", "sandbox", "cite", "poster", "icon"];
export declare const SECURITY_SENSITIVE_ATTRIBUTES: readonly ["src", "srcdoc", "codebase", "data", "href", "rel", "action", "formaction", "sandbox", "icon"];

@@ -24,5 +24,3 @@ "use strict";

'sandbox',
'cite',
'poster',
'icon',
];

@@ -14,2 +14,3 @@ /**

import { SafeHtml } from '../../internals/html_impl.js';
import { TrustedResourceUrl } from '../../internals/resource_url_impl.js';
declare type ScriptOrStyle = HTMLScriptElement | HTMLStyleElement | SVGScriptElement | SVGStyleElement;

@@ -42,3 +43,3 @@ /**

/**
* The safe alternative to Element#setAttribute. The function takes a list of
* A safe alternative to Element#setAttribute. The function takes a list of
* `SafeAttributePrefix`, making developer intention explicit. The attribute

@@ -49,2 +50,45 @@ * to be set must has one of the safe prefixes, otherwise the function throws

export declare function setElementPrefixedAttribute(attrPrefixes: readonly SafeAttributePrefix[], e: Element, attr: string, value: string): void;
/**
* A safe alternative to Element#setAttribute.
*
* The function has essentially the same signature as `Element.setAttribute`,
* but requires a safe type (or sanitizes the value) when used with a security
* sensitive attribute. It does this by forwarding the call to the
* element-specific setters within `safevalues/dom`.
*
* Note that this function doesn't currently support elements outside of the
* html namespace & might throw if used with the wrong type of element or
* attribute value
*
* If code size is a concern, consider using `setPrefixedAttribute`, or the
* element-specific setters.
*
* The security sensitive element/attributes pairs are the following:
* - anchor#href -> forwarded to `setAnchorHref`
* - area#href -> forwarded to `setAreaHref`
* - base#href -> forwarded to `setBaseHref`
* - button#formaction -> forwarded to `setButtonFormaction`
* - embed#src -> forwarded to `setEmbedSrc`
* - form#action -> forwarded to `setFormAction`
* - iframe#src -> forwarded to `setIframeSrc`
* - iframe#srcdoc -> forwarded to `setIframeSrcdoc`
* - iframe#sandbox -> rejected, use `setIframeSrcWithIntent` or
* `setIframeSrcdocWithIntent` instead
* - input#formaction -> forwarded to `setInputFormaction`
* - link#href -> rejected, use `setLinkHrefAndRel` instead
* - link#rel -> rejected, use `setLinkHrefAndRel` instead
* - object#data -> forwarded to `setObjectData`
* - script#src -> forwarded to `setScriptSrc`
* - global attributes:
* - target -> forwarded to `el.setAttribute`
* - cite -> forwarded to `el.setAttribute`
* - poster -> forwarded to `el.setAttribute`
* - srcset -> forwarded to `el.setAttribute`
* - src -> forwarded to `el.setAttribute`
* - href -> forwarded to `el.setAttribute`
* - any attribute starting with `on` -> rejected
*
* Every other attribute is set as is using `element.setAttribute`
*/
export declare function setElementAttribute(el: HTMLElement, attr: string, value: string | TrustedResourceUrl | SafeHtml): void;
export {};

@@ -8,3 +8,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.setElementPrefixedAttribute = exports.buildPrefixedAttributeSetter = exports.elementInsertAdjacentHtml = exports.setElementOuterHtml = exports.setElementInnerHtml = void 0;
exports.setElementAttribute = exports.setElementPrefixedAttribute = exports.buildPrefixedAttributeSetter = exports.elementInsertAdjacentHtml = exports.setElementOuterHtml = exports.setElementInnerHtml = void 0;
/**

@@ -18,2 +18,12 @@ * @fileoverview This contains safe wrappers for properties that aren't specific

const html_impl_js_1 = require("../../internals/html_impl.js");
const anchor_js_1 = require("./anchor.js");
const area_js_1 = require("./area.js");
const base_js_1 = require("./base.js");
const button_js_1 = require("./button.js");
const embed_js_1 = require("./embed.js");
const form_js_1 = require("./form.js");
const iframe_js_1 = require("./iframe.js");
const input_js_1 = require("./input.js");
const object_js_1 = require("./object.js");
const script_js_1 = require("./script.js");
/**

@@ -73,3 +83,3 @@ * Safely set {@link Element.innerHTML} on a given ShadowRoot or Element which

/**
* The safe alternative to Element#setAttribute. The function takes a list of
* A safe alternative to Element#setAttribute. The function takes a list of
* `SafeAttributePrefix`, making developer intention explicit. The attribute

@@ -113,1 +123,102 @@ * to be set must has one of the safe prefixes, otherwise the function throws

}
/**
* A safe alternative to Element#setAttribute.
*
* The function has essentially the same signature as `Element.setAttribute`,
* but requires a safe type (or sanitizes the value) when used with a security
* sensitive attribute. It does this by forwarding the call to the
* element-specific setters within `safevalues/dom`.
*
* Note that this function doesn't currently support elements outside of the
* html namespace & might throw if used with the wrong type of element or
* attribute value
*
* If code size is a concern, consider using `setPrefixedAttribute`, or the
* element-specific setters.
*
* The security sensitive element/attributes pairs are the following:
* - anchor#href -> forwarded to `setAnchorHref`
* - area#href -> forwarded to `setAreaHref`
* - base#href -> forwarded to `setBaseHref`
* - button#formaction -> forwarded to `setButtonFormaction`
* - embed#src -> forwarded to `setEmbedSrc`
* - form#action -> forwarded to `setFormAction`
* - iframe#src -> forwarded to `setIframeSrc`
* - iframe#srcdoc -> forwarded to `setIframeSrcdoc`
* - iframe#sandbox -> rejected, use `setIframeSrcWithIntent` or
* `setIframeSrcdocWithIntent` instead
* - input#formaction -> forwarded to `setInputFormaction`
* - link#href -> rejected, use `setLinkHrefAndRel` instead
* - link#rel -> rejected, use `setLinkHrefAndRel` instead
* - object#data -> forwarded to `setObjectData`
* - script#src -> forwarded to `setScriptSrc`
* - global attributes:
* - target -> forwarded to `el.setAttribute`
* - cite -> forwarded to `el.setAttribute`
* - poster -> forwarded to `el.setAttribute`
* - srcset -> forwarded to `el.setAttribute`
* - src -> forwarded to `el.setAttribute`
* - href -> forwarded to `el.setAttribute`
* - any attribute starting with `on` -> rejected
*
* Every other attribute is set as is using `element.setAttribute`
*/
function setElementAttribute(el, attr, value) {
if (el.namespaceURI !== 'http://www.w3.org/1999/xhtml') {
throw new Error(`Cannot set attribute '${attr}' on '${el.tagName}'.` +
`Element is not in the HTML namespace`);
}
attr = attr.toLowerCase();
const key = `${el.tagName} ${attr}`;
switch (key) {
case 'A href':
(0, anchor_js_1.setAnchorHref)(el, value);
return;
case 'AREA href':
(0, area_js_1.setAreaHref)(el, value);
return;
case 'BASE href':
(0, base_js_1.setBaseHref)(el, value);
return;
case 'BUTTON formaction':
(0, button_js_1.setButtonFormaction)(el, value);
return;
case 'EMBED src':
(0, embed_js_1.setEmbedSrc)(el, value);
return;
case 'FORM action':
(0, form_js_1.setFormAction)(el, value);
return;
case 'IFRAME src':
(0, iframe_js_1.setIframeSrc)(el, value);
return;
case 'IFRAME srcdoc':
(0, iframe_js_1.setIframeSrcdoc)(el, value);
return;
case 'IFRAME sandbox':
throw new Error("Can't set 'sandbox' on iframe tags. " +
'Use setIframeSrcWithIntent or setIframeSrcdocWithIntent instead');
case 'INPUT formaction':
(0, input_js_1.setInputFormaction)(el, value);
return;
case 'LINK href':
throw new Error("Can't set 'href' attribute on link tags. " +
'Use setLinkHrefAndRel instead');
case 'LINK rel':
throw new Error("Can't set 'rel' attribute on link tags. " +
'Use setLinkHrefAndRel instead');
case 'OBJECT data':
(0, object_js_1.setObjectData)(el, value);
return;
case 'SCRIPT src':
(0, script_js_1.setScriptSrc)(el, value);
return;
default:
if (/^on./.test(attr)) {
throw new Error(`Attribute "${attr}" looks like an event handler attribute. ` +
`Please use a safe alternative like addEventListener instead.`);
}
el.setAttribute(attr, value);
}
}
exports.setElementAttribute = setElementAttribute;

@@ -14,3 +14,3 @@ /**

export { setButtonFormaction } from './elements/button.js';
export { buildPrefixedAttributeSetter, elementInsertAdjacentHtml, setElementInnerHtml, setElementOuterHtml, setElementPrefixedAttribute, } from './elements/element.js';
export { buildPrefixedAttributeSetter, elementInsertAdjacentHtml, setElementAttribute, setElementInnerHtml, setElementOuterHtml, setElementPrefixedAttribute, } from './elements/element.js';
export { setEmbedSrc } from './elements/embed.js';

@@ -17,0 +17,0 @@ export { setFormAction } from './elements/form.js';

@@ -8,3 +8,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.workerGlobalScopeImportScripts = exports.createWorker = exports.createSharedWorker = exports.windowOpen = exports.getStyleNonce = exports.getScriptNonce = exports.objectUrlFromSafeSource = exports.serviceWorkerContainerRegister = exports.rangeCreateContextualFragment = exports.setLocationHref = exports.locationReplace = exports.locationAssign = exports.globalEval = exports.fetchResourceUrl = exports.domParserParseXml = exports.domParserParseHtml = exports.domParserParseFromString = exports.documentWrite = exports.documentExecCommand = exports.setSvgUseHref = exports.setSvgAttribute = exports.setStyleTextContent = exports.setScriptTextContent = exports.setScriptSrc = exports.setObjectData = exports.setLinkWithResourceUrlHrefAndRel = exports.setLinkHrefAndRel = exports.setInputFormaction = exports.setIframeSrcdoc = exports.setIframeSrc = exports.setFormAction = exports.setEmbedSrc = exports.setElementPrefixedAttribute = exports.setElementOuterHtml = exports.setElementInnerHtml = exports.elementInsertAdjacentHtml = exports.buildPrefixedAttributeSetter = exports.setButtonFormaction = exports.setBaseHref = exports.setAreaHref = exports.setAnchorHref = void 0;
exports.workerGlobalScopeImportScripts = exports.createWorker = exports.createSharedWorker = exports.windowOpen = exports.getStyleNonce = exports.getScriptNonce = exports.objectUrlFromSafeSource = exports.serviceWorkerContainerRegister = exports.rangeCreateContextualFragment = exports.setLocationHref = exports.locationReplace = exports.locationAssign = exports.globalEval = exports.fetchResourceUrl = exports.domParserParseXml = exports.domParserParseHtml = exports.domParserParseFromString = exports.documentWrite = exports.documentExecCommand = exports.setSvgUseHref = exports.setSvgAttribute = exports.setStyleTextContent = exports.setScriptTextContent = exports.setScriptSrc = exports.setObjectData = exports.setLinkWithResourceUrlHrefAndRel = exports.setLinkHrefAndRel = exports.setInputFormaction = exports.setIframeSrcdoc = exports.setIframeSrc = exports.setFormAction = exports.setEmbedSrc = exports.setElementPrefixedAttribute = exports.setElementOuterHtml = exports.setElementInnerHtml = exports.setElementAttribute = exports.elementInsertAdjacentHtml = exports.buildPrefixedAttributeSetter = exports.setButtonFormaction = exports.setBaseHref = exports.setAreaHref = exports.setAnchorHref = void 0;
/**

@@ -25,2 +25,3 @@ * @fileoverview This file re-exports all of the wrappers to ensure that we have

Object.defineProperty(exports, "elementInsertAdjacentHtml", { enumerable: true, get: function () { return element_js_1.elementInsertAdjacentHtml; } });
Object.defineProperty(exports, "setElementAttribute", { enumerable: true, get: function () { return element_js_1.setElementAttribute; } });
Object.defineProperty(exports, "setElementInnerHtml", { enumerable: true, get: function () { return element_js_1.setElementInnerHtml; } });

@@ -27,0 +28,0 @@ Object.defineProperty(exports, "setElementOuterHtml", { enumerable: true, get: function () { return element_js_1.setElementOuterHtml; } });

{
"type": "commonjs",
"version": "1.0.1"
"version": "1.1.0"
}

@@ -32,5 +32,6 @@ /**

/**
* Allows the set of data attributes passed.
* Allows all or a definite set of data attributes passed.
*
* These values must be prefixed with "data-"
* When called without arguments, all data attributes are allowed.
* When a set of attributes is passed, its values must be prefixed with "data-"
*

@@ -40,3 +41,3 @@ * If called with onlyAllowElements or onlyAllowAttributes, those methods must

*/
allowDataAttributes(attributes: string[]): this;
allowDataAttributes(attributes?: string[]): this;
/**

@@ -124,5 +125,14 @@ * Preserves style attributes. Note that the sanitizer won't parse and

private transitionsAllowed;
private openShadow;
allowAnimations(): this;
allowTransitions(): this;
/**
* Sets the shadow DOM mode to 'open'.
*
* While this method is not formally restricted, it can potentially be used to
* bypass the security guarantees of the CSS sanitizer. If you need open
* shadow DOM, please contact ise-web-members@ to discuss your use case.
*/
withOpenShadow(): this;
/**
* Builds a CSS sanitizer.

@@ -129,0 +139,0 @@ *

@@ -39,3 +39,3 @@ /**

}
this.sanitizerTable = new SanitizerTable(allowedElements, allowedElementPolicies, this.sanitizerTable.allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies);
this.sanitizerTable = new SanitizerTable(allowedElements, allowedElementPolicies, this.sanitizerTable.allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;

@@ -67,3 +67,3 @@ }

}
this.sanitizerTable = new SanitizerTable(allowedElements, allowedElementPolicies, this.sanitizerTable.allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies);
this.sanitizerTable = new SanitizerTable(allowedElements, allowedElementPolicies, this.sanitizerTable.allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;

@@ -97,9 +97,10 @@ }

}
this.sanitizerTable = new SanitizerTable(this.sanitizerTable.allowedElements, elementPolicies, allowedGlobalAttributes, globalAttributePolicies);
this.sanitizerTable = new SanitizerTable(this.sanitizerTable.allowedElements, elementPolicies, allowedGlobalAttributes, globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;
}
/**
* Allows the set of data attributes passed.
* Allows all or a definite set of data attributes passed.
*
* These values must be prefixed with "data-"
* When called without arguments, all data attributes are allowed.
* When a set of attributes is passed, its values must be prefixed with "data-"
*

@@ -110,2 +111,8 @@ * If called with onlyAllowElements or onlyAllowAttributes, those methods must

allowDataAttributes(attributes) {
if (attributes === undefined) {
const globallyAllowedAttributePrefixes = new Set(this.sanitizerTable.globallyAllowedAttributePrefixes);
globallyAllowedAttributePrefixes.add('data-');
this.sanitizerTable = new SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, this.sanitizerTable.allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies, globallyAllowedAttributePrefixes);
return this;
}
const allowedGlobalAttributes = new Set(this.sanitizerTable.allowedGlobalAttributes);

@@ -118,3 +125,3 @@ for (const attribute of attributes) {

}
this.sanitizerTable = new SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies);
this.sanitizerTable = new SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;

@@ -134,3 +141,3 @@ }

});
this.sanitizerTable = new SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, this.sanitizerTable.allowedGlobalAttributes, globalAttributePolicies);
this.sanitizerTable = new SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, this.sanitizerTable.allowedGlobalAttributes, globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;

@@ -146,3 +153,3 @@ }

allowedGlobalAttributes.add('class');
this.sanitizerTable = new SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies);
this.sanitizerTable = new SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;

@@ -157,3 +164,3 @@ }

allowedGlobalAttributes.add('id');
this.sanitizerTable = new SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies);
this.sanitizerTable = new SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;

@@ -177,3 +184,3 @@ }

.add('list');
this.sanitizerTable = new SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies);
this.sanitizerTable = new SanitizerTable(this.sanitizerTable.allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, this.sanitizerTable.globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
return this;

@@ -248,2 +255,3 @@ }

this.transitionsAllowed = false;
this.openShadow = false;
}

@@ -259,2 +267,13 @@ allowAnimations() {

/**
* Sets the shadow DOM mode to 'open'.
*
* While this method is not formally restricted, it can potentially be used to
* bypass the security guarantees of the CSS sanitizer. If you need open
* shadow DOM, please contact ise-web-members@ to discuss your use case.
*/
withOpenShadow() {
this.openShadow = true;
return this;
}
/**
* Builds a CSS sanitizer.

@@ -276,3 +295,3 @@ *

const styleAttributeSanitizer = (cssText) => sanitizeStyleAttribute(cssText, CSS_PROPERTY_ALLOWLIST, CSS_FUNCTION_ALLOWLIST, this.resourceUrlPolicy, propertyDiscarders);
return new HtmlSanitizerImpl(this.sanitizerTable, secretToken, styleElementSanitizer, styleAttributeSanitizer, this.resourceUrlPolicy);
return new HtmlSanitizerImpl(this.sanitizerTable, secretToken, styleElementSanitizer, styleAttributeSanitizer, this.resourceUrlPolicy, this.openShadow);
}

@@ -290,4 +309,4 @@ extendSanitizerTableForCss() {

allowedGlobalAttributes.add('class');
this.sanitizerTable = new SanitizerTable(allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, globalAttributePolicies);
this.sanitizerTable = new SanitizerTable(allowedElements, this.sanitizerTable.elementPolicies, allowedGlobalAttributes, globalAttributePolicies, this.sanitizerTable.globallyAllowedAttributePrefixes);
}
}

@@ -49,4 +49,5 @@ /**

private readonly resourceUrlPolicy?;
private readonly openShadow?;
private changes;
constructor(sanitizerTable: SanitizerTable, token: object, styleElementSanitizer?: CssSanitizationFn | undefined, styleAttributeSanitizer?: CssSanitizationFn | undefined, resourceUrlPolicy?: ResourceUrlPolicy | undefined);
constructor(sanitizerTable: SanitizerTable, token: object, styleElementSanitizer?: CssSanitizationFn | undefined, styleAttributeSanitizer?: CssSanitizationFn | undefined, resourceUrlPolicy?: ResourceUrlPolicy | undefined, openShadow?: boolean | undefined);
sanitizeAssertUnchanged(html: string): SafeHtml;

@@ -53,0 +54,0 @@ sanitize(html: string): SafeHtml;

@@ -19,3 +19,3 @@ /**

export class HtmlSanitizerImpl {
constructor(sanitizerTable, token, styleElementSanitizer, styleAttributeSanitizer, resourceUrlPolicy) {
constructor(sanitizerTable, token, styleElementSanitizer, styleAttributeSanitizer, resourceUrlPolicy, openShadow) {
this.sanitizerTable = sanitizerTable;

@@ -25,2 +25,3 @@ this.styleElementSanitizer = styleElementSanitizer;

this.resourceUrlPolicy = resourceUrlPolicy;
this.openShadow = openShadow;
this.changes = [];

@@ -54,3 +55,4 @@ ensureTokenIsValid(token);

const elem = document.createElement('safevalues-with-css');
const shadow = elem.attachShadow({ mode: 'closed' });
const mode = this.openShadow ? 'open' : 'closed';
const shadow = elem.attachShadow({ mode });
const sanitized = this.sanitizeToFragmentInternal(htmlWithCss, inertDocument);

@@ -57,0 +59,0 @@ const internalStyle = document.createElement('style');

@@ -268,2 +268,3 @@ /**

'checked',
'cite',
'color',

@@ -273,2 +274,3 @@ 'cols',

'controls',
'controlslist',
'datetime',

@@ -299,2 +301,3 @@ 'disabled',

'placeholder',
'poster',
'preload',

@@ -353,8 +356,2 @@ 'rel',

[
'cite',
{
policyAction: AttributePolicyAction.KEEP_AND_SANITIZE_URL,
},
],
[
'loading',

@@ -371,8 +368,2 @@ {

[
'poster',
{
policyAction: AttributePolicyAction.KEEP_AND_SANITIZE_URL,
},
],
[
'target',

@@ -393,2 +384,2 @@ {

*/
export const DEFAULT_SANITIZER_TABLE = new SanitizerTable(new Set(ALLOWED_ELEMENTS), new Map(ELEMENT_POLICIES), new Set(ALLOWED_GLOBAL_ATTRIBUTES), new Map(GLOBAL_ATTRIBUTE_POLICIES));
export const DEFAULT_SANITIZER_TABLE = new SanitizerTable(new Set(ALLOWED_ELEMENTS), new Map(ELEMENT_POLICIES), new Set(ALLOWED_GLOBAL_ATTRIBUTES), new Map(GLOBAL_ATTRIBUTE_POLICIES), undefined);

@@ -12,4 +12,4 @@ /**

readonly globalAttributePolicies: ReadonlyMap<string, AttributePolicy>;
readonly globallyAllowedAttributePrefixes?: ReadonlySet<string> | undefined;
constructor(allowedElements: ReadonlySet<string>, elementPolicies: ReadonlyMap<string, ElementPolicy>, allowedGlobalAttributes: ReadonlySet<string>, globalAttributePolicies: ReadonlyMap<string, AttributePolicy>, globallyAllowedAttributePrefixes?: ReadonlySet<string> | undefined);
readonly globallyAllowedAttributePrefixes: ReadonlySet<string> | undefined;
constructor(allowedElements: ReadonlySet<string>, elementPolicies: ReadonlyMap<string, ElementPolicy>, allowedGlobalAttributes: ReadonlySet<string>, globalAttributePolicies: ReadonlyMap<string, AttributePolicy>, globallyAllowedAttributePrefixes: ReadonlySet<string> | undefined);
isAllowedElement(elementName: string): boolean;

@@ -16,0 +16,0 @@ getAttributePolicy(attributeName: string, elementName: string): AttributePolicy;

@@ -10,2 +10,2 @@ /**

*/
export declare const SECURITY_SENSITIVE_ATTRIBUTES: readonly ["src", "srcdoc", "codebase", "data", "href", "rel", "action", "formaction", "sandbox", "cite", "poster", "icon"];
export declare const SECURITY_SENSITIVE_ATTRIBUTES: readonly ["src", "srcdoc", "codebase", "data", "href", "rel", "action", "formaction", "sandbox", "icon"];

@@ -21,5 +21,3 @@ /**

'sandbox',
'cite',
'poster',
'icon',
];

@@ -14,2 +14,3 @@ /**

import { SafeHtml } from '../../internals/html_impl.js';
import { TrustedResourceUrl } from '../../internals/resource_url_impl.js';
declare type ScriptOrStyle = HTMLScriptElement | HTMLStyleElement | SVGScriptElement | SVGStyleElement;

@@ -42,3 +43,3 @@ /**

/**
* The safe alternative to Element#setAttribute. The function takes a list of
* A safe alternative to Element#setAttribute. The function takes a list of
* `SafeAttributePrefix`, making developer intention explicit. The attribute

@@ -49,2 +50,45 @@ * to be set must has one of the safe prefixes, otherwise the function throws

export declare function setElementPrefixedAttribute(attrPrefixes: readonly SafeAttributePrefix[], e: Element, attr: string, value: string): void;
/**
* A safe alternative to Element#setAttribute.
*
* The function has essentially the same signature as `Element.setAttribute`,
* but requires a safe type (or sanitizes the value) when used with a security
* sensitive attribute. It does this by forwarding the call to the
* element-specific setters within `safevalues/dom`.
*
* Note that this function doesn't currently support elements outside of the
* html namespace & might throw if used with the wrong type of element or
* attribute value
*
* If code size is a concern, consider using `setPrefixedAttribute`, or the
* element-specific setters.
*
* The security sensitive element/attributes pairs are the following:
* - anchor#href -> forwarded to `setAnchorHref`
* - area#href -> forwarded to `setAreaHref`
* - base#href -> forwarded to `setBaseHref`
* - button#formaction -> forwarded to `setButtonFormaction`
* - embed#src -> forwarded to `setEmbedSrc`
* - form#action -> forwarded to `setFormAction`
* - iframe#src -> forwarded to `setIframeSrc`
* - iframe#srcdoc -> forwarded to `setIframeSrcdoc`
* - iframe#sandbox -> rejected, use `setIframeSrcWithIntent` or
* `setIframeSrcdocWithIntent` instead
* - input#formaction -> forwarded to `setInputFormaction`
* - link#href -> rejected, use `setLinkHrefAndRel` instead
* - link#rel -> rejected, use `setLinkHrefAndRel` instead
* - object#data -> forwarded to `setObjectData`
* - script#src -> forwarded to `setScriptSrc`
* - global attributes:
* - target -> forwarded to `el.setAttribute`
* - cite -> forwarded to `el.setAttribute`
* - poster -> forwarded to `el.setAttribute`
* - srcset -> forwarded to `el.setAttribute`
* - src -> forwarded to `el.setAttribute`
* - href -> forwarded to `el.setAttribute`
* - any attribute starting with `on` -> rejected
*
* Every other attribute is set as is using `element.setAttribute`
*/
export declare function setElementAttribute(el: HTMLElement, attr: string, value: string | TrustedResourceUrl | SafeHtml): void;
export {};

@@ -14,2 +14,12 @@ /**

import { unwrapHtml } from '../../internals/html_impl.js';
import { setAnchorHref } from './anchor.js';
import { setAreaHref } from './area.js';
import { setBaseHref } from './base.js';
import { setButtonFormaction } from './button.js';
import { setEmbedSrc } from './embed.js';
import { setFormAction } from './form.js';
import { setIframeSrc, setIframeSrcdoc } from './iframe.js';
import { setInputFormaction } from './input.js';
import { setObjectData } from './object.js';
import { setScriptSrc } from './script.js';
/**

@@ -65,3 +75,3 @@ * Safely set {@link Element.innerHTML} on a given ShadowRoot or Element which

/**
* The safe alternative to Element#setAttribute. The function takes a list of
* A safe alternative to Element#setAttribute. The function takes a list of
* `SafeAttributePrefix`, making developer intention explicit. The attribute

@@ -104,1 +114,101 @@ * to be set must has one of the safe prefixes, otherwise the function throws

}
/**
* A safe alternative to Element#setAttribute.
*
* The function has essentially the same signature as `Element.setAttribute`,
* but requires a safe type (or sanitizes the value) when used with a security
* sensitive attribute. It does this by forwarding the call to the
* element-specific setters within `safevalues/dom`.
*
* Note that this function doesn't currently support elements outside of the
* html namespace & might throw if used with the wrong type of element or
* attribute value
*
* If code size is a concern, consider using `setPrefixedAttribute`, or the
* element-specific setters.
*
* The security sensitive element/attributes pairs are the following:
* - anchor#href -> forwarded to `setAnchorHref`
* - area#href -> forwarded to `setAreaHref`
* - base#href -> forwarded to `setBaseHref`
* - button#formaction -> forwarded to `setButtonFormaction`
* - embed#src -> forwarded to `setEmbedSrc`
* - form#action -> forwarded to `setFormAction`
* - iframe#src -> forwarded to `setIframeSrc`
* - iframe#srcdoc -> forwarded to `setIframeSrcdoc`
* - iframe#sandbox -> rejected, use `setIframeSrcWithIntent` or
* `setIframeSrcdocWithIntent` instead
* - input#formaction -> forwarded to `setInputFormaction`
* - link#href -> rejected, use `setLinkHrefAndRel` instead
* - link#rel -> rejected, use `setLinkHrefAndRel` instead
* - object#data -> forwarded to `setObjectData`
* - script#src -> forwarded to `setScriptSrc`
* - global attributes:
* - target -> forwarded to `el.setAttribute`
* - cite -> forwarded to `el.setAttribute`
* - poster -> forwarded to `el.setAttribute`
* - srcset -> forwarded to `el.setAttribute`
* - src -> forwarded to `el.setAttribute`
* - href -> forwarded to `el.setAttribute`
* - any attribute starting with `on` -> rejected
*
* Every other attribute is set as is using `element.setAttribute`
*/
export function setElementAttribute(el, attr, value) {
if (el.namespaceURI !== 'http://www.w3.org/1999/xhtml') {
throw new Error(`Cannot set attribute '${attr}' on '${el.tagName}'.` +
`Element is not in the HTML namespace`);
}
attr = attr.toLowerCase();
const key = `${el.tagName} ${attr}`;
switch (key) {
case 'A href':
setAnchorHref(el, value);
return;
case 'AREA href':
setAreaHref(el, value);
return;
case 'BASE href':
setBaseHref(el, value);
return;
case 'BUTTON formaction':
setButtonFormaction(el, value);
return;
case 'EMBED src':
setEmbedSrc(el, value);
return;
case 'FORM action':
setFormAction(el, value);
return;
case 'IFRAME src':
setIframeSrc(el, value);
return;
case 'IFRAME srcdoc':
setIframeSrcdoc(el, value);
return;
case 'IFRAME sandbox':
throw new Error("Can't set 'sandbox' on iframe tags. " +
'Use setIframeSrcWithIntent or setIframeSrcdocWithIntent instead');
case 'INPUT formaction':
setInputFormaction(el, value);
return;
case 'LINK href':
throw new Error("Can't set 'href' attribute on link tags. " +
'Use setLinkHrefAndRel instead');
case 'LINK rel':
throw new Error("Can't set 'rel' attribute on link tags. " +
'Use setLinkHrefAndRel instead');
case 'OBJECT data':
setObjectData(el, value);
return;
case 'SCRIPT src':
setScriptSrc(el, value);
return;
default:
if (/^on./.test(attr)) {
throw new Error(`Attribute "${attr}" looks like an event handler attribute. ` +
`Please use a safe alternative like addEventListener instead.`);
}
el.setAttribute(attr, value);
}
}

@@ -14,3 +14,3 @@ /**

export { setButtonFormaction } from './elements/button.js';
export { buildPrefixedAttributeSetter, elementInsertAdjacentHtml, setElementInnerHtml, setElementOuterHtml, setElementPrefixedAttribute, } from './elements/element.js';
export { buildPrefixedAttributeSetter, elementInsertAdjacentHtml, setElementAttribute, setElementInnerHtml, setElementOuterHtml, setElementPrefixedAttribute, } from './elements/element.js';
export { setEmbedSrc } from './elements/embed.js';

@@ -17,0 +17,0 @@ export { setFormAction } from './elements/form.js';

@@ -14,3 +14,3 @@ /**

export { setButtonFormaction } from './elements/button.js';
export { buildPrefixedAttributeSetter, elementInsertAdjacentHtml, setElementInnerHtml, setElementOuterHtml, setElementPrefixedAttribute, } from './elements/element.js';
export { buildPrefixedAttributeSetter, elementInsertAdjacentHtml, setElementAttribute, setElementInnerHtml, setElementOuterHtml, setElementPrefixedAttribute, } from './elements/element.js';
export { setEmbedSrc } from './elements/embed.js';

@@ -17,0 +17,0 @@ export { setFormAction } from './elements/form.js';

{
"type": "module",
"version": "1.0.1"
"version": "1.1.0"
}
{
"name": "safevalues",
"version": "1.0.1",
"version": "1.1.0",
"description": "Safe builders for Trusted Types values",

@@ -5,0 +5,0 @@ "repository": "https://github.com/google/safevalues",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc