@instructure/platform-sanitize 0.3.12 → 0.3.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sanitizeHtml.browser.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizeHtml.browser.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/sanitizeHtml.browser.test.ts"],"names":[],"mappings":""}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import c from "dompurify";
2
- const b = /* @__PURE__ */ new Set([
2
+ const p = /* @__PURE__ */ new Set([
3
3
  // layout
4
4
  "display",
5
5
  "float",
@@ -106,6 +106,13 @@ const b = /* @__PURE__ */ new Set([
106
106
  "border-style",
107
107
  "border-width",
108
108
  "border-radius",
109
+ // Chrome's CSSOM expands border-radius to these four longhands when iterating
110
+ // element.style — the shorthand itself never appears in the iterator, so the
111
+ // hook would strip all four corners unless they are explicitly listed here.
112
+ "border-top-left-radius",
113
+ "border-top-right-radius",
114
+ "border-bottom-right-radius",
115
+ "border-bottom-left-radius",
109
116
  "border-collapse",
110
117
  "border-spacing",
111
118
  "border-top",
@@ -130,6 +137,9 @@ const b = /* @__PURE__ */ new Set([
130
137
  "outline-color",
131
138
  "outline-style",
132
139
  "outline-width",
140
+ // outline-offset is not part of the `outline` shorthand, so it must be listed
141
+ // separately or it is stripped when authored on its own (focus-ring styling).
142
+ "outline-offset",
133
143
  // list
134
144
  "list-style",
135
145
  "list-style-image",
@@ -218,10 +228,11 @@ const b = /* @__PURE__ */ new Set([
218
228
  "counter-increment",
219
229
  "content",
220
230
  // UI / interaction
221
- // pointer-events is included: RCE uses it legitimately (e.g. non-interactive
222
- // decorative overlays). It is not in the overlay-phishing class because it
223
- // cannot reposition elements — position/z-index remain blocked.
231
+ // pointer-events and z-index are safe: neither can reposition elements
232
+ // outside the container. The overlay-phishing risk comes from position:fixed/sticky,
233
+ // which SAFE_POSITION_VALUES strips.
224
234
  "pointer-events",
235
+ "z-index",
225
236
  "caret-color",
226
237
  "accent-color",
227
238
  "appearance"
@@ -279,7 +290,8 @@ const b = /* @__PURE__ */ new Set([
279
290
  // expressions; `arg` labels sub-expressions referenced by intent.
280
291
  // These are plain string annotations — no URL-loading, no code execution.
281
292
  "intent",
282
- "arg"
293
+ "arg",
294
+ "loading"
283
295
  ],
284
296
  // Rails UJS turns data-method/data-remote/etc. on clickable elements into
285
297
  // state-changing requests carrying the victim's CSRF token. Strip them so
@@ -307,7 +319,7 @@ function k() {
307
319
  const e = t.style, o = [];
308
320
  for (let n = 0; n < e.length; n++) {
309
321
  const a = e.item(n);
310
- b.has(a) || o.push(a);
322
+ p.has(a) || o.push(a);
311
323
  }
312
324
  for (const n of o) e.removeProperty(n);
313
325
  const r = /* @__PURE__ */ new Set([
@@ -348,7 +360,7 @@ function R(t, e) {
348
360
  const o = e != null && e.allowFormAttributeNames ? { ...d, SANITIZE_DOM: !1 } : d;
349
361
  return k().sanitize(t ?? "", o);
350
362
  }
351
- const f = /* @__PURE__ */ new Set(["http:", "https:", "mailto:", "tel:"]), l = "http://platform-sanitize.invalid/", g = /^\s*\/\//, p = (
363
+ const f = /* @__PURE__ */ new Set(["http:", "https:", "mailto:", "tel:"]), l = "http://platform-sanitize.invalid/", b = /^\s*\/\//, g = (
352
364
  // oxlint-disable-next-line no-control-regex -- intentional security guard
353
365
  /^[\u0000-\u0020\u007F-\u00A0\u2000-\u200F\u2028\u2029\u202F\u205F\u2060\u3000\uFEFF]*(?:javascript|data|vbscript|file):/i
354
366
  ), A = {
@@ -386,10 +398,10 @@ function E(t) {
386
398
  function S(t) {
387
399
  if (!t || !t.trim()) return "about:blank";
388
400
  const e = t.replace(/\\/g, "/");
389
- if (g.test(e) || p.test(e)) return "about:blank";
401
+ if (b.test(e) || g.test(e)) return "about:blank";
390
402
  if (/&[#A-Za-z]/.test(e)) {
391
403
  const o = E(e);
392
- if (g.test(o) || p.test(o))
404
+ if (b.test(o) || g.test(o))
393
405
  return "about:blank";
394
406
  try {
395
407
  const r = new URL(o, l);
@@ -1 +1 @@
1
- {"version":3,"file":"sanitizeHtml.d.ts","sourceRoot":"","sources":["../src/sanitizeHtml.ts"],"names":[],"mappings":"AA6aA,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,OAAO,CAAC,EAAE;IAAE,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9C,MAAM,CASR"}
1
+ {"version":3,"file":"sanitizeHtml.d.ts","sourceRoot":"","sources":["../src/sanitizeHtml.ts"],"names":[],"mappings":"AAybA,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,OAAO,CAAC,EAAE;IAAE,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9C,MAAM,CASR"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/platform-sanitize",
3
- "version": "0.3.12",
3
+ "version": "0.3.14",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -22,9 +22,12 @@
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/trusted-types": "^2.0.7",
25
+ "@vitest/browser": "^4.0.17",
26
+ "@vitest/browser-playwright": "^4.0.17",
25
27
  "@vitest/coverage-v8": "^4.0.17",
26
28
  "dompurify": "^3.4.0",
27
29
  "jsdom": "^25.0.0",
30
+ "playwright": "^1.60.0",
28
31
  "typescript": "^5.3.0",
29
32
  "vite": "^6.0.0",
30
33
  "vite-plugin-dts": "^4.0.0",
@@ -34,6 +37,7 @@
34
37
  "build": "vite build",
35
38
  "dev": "vite build --watch",
36
39
  "test": "vitest run",
40
+ "test:browser": "vitest run --config vitest.browser.config.ts",
37
41
  "test:watch": "vitest",
38
42
  "test:coverage": "vitest run --coverage",
39
43
  "type-check": "tsc --noEmit"