Kaynağa Gözat

feat: add setInnerHtmlTrusted to plugin interface

Sv443 8 ay önce
ebeveyn
işleme
1cf9314b77
3 değiştirilmiş dosya ile 33 ekleme ve 2 silme
  1. 28 0
      contributing.md
  2. 2 1
      src/interface.ts
  3. 3 1
      src/types.ts

+ 28 - 0
contributing.md

@@ -376,6 +376,7 @@ Functions marked with 🔒 need to be passed a per-session and per-plugin authen
   - [BytmDialog](#bytmdialog) - A class for creating and managing modal, fully customizable dialogs
   - [ExImDialog](#eximdialog) - Subclass of BytmDialog for allowing users to export and import serializable data
   - [MarkdownDialog](#markdowndialog) - Subclass of BytmDialog for displaying markdown content
+  - [setInnerHtmlTrusted()](#setinnerhtmltrusted) - Sets the innerHTML property of the specified element to the provided string, after sanitizing it (for compatibility with the [Trusted Types API](https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API))
   - [addSelectorListener()](#addselectorlistener) - Adds a listener that checks for changes in DOM elements matching a CSS selector
   - [onInteraction()](#oninteraction) - Adds accessible event listeners to the specified element for button or link-like keyboard and mouse interactions
   - [getVideoTime()](#getvideotime) - Returns the current video time (on both YT and YTM)
@@ -653,6 +654,33 @@ Functions marked with 🔒 need to be passed a per-session and per-plugin authen
 
 <br>
 
+> #### setInnerHtmlTrusted()
+> Usage:  
+> ```ts
+> unsafeWindow.BYTM.setInnerHtmlTrusted(element: HTMLElement, html: string): void
+> ```
+>   
+> Description:  
+> Sets the innerHTML property of the specified element to the provided string, after sanitizing it.  
+> This is done for compatibility with the [Trusted Types API](https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API) and to prevent XSS attacks.  
+> Uses the library [DOMPurify](https://github.com/cure53/DOMPurify) on default settings to sanitize the HTML.  
+>   
+> Arguments:  
+> - `element` - The element to set the innerHTML property of
+> - `html` - The HTML string to sanitize and set as the innerHTML property
+>   
+> <details><summary><b>Example <i>(click to expand)</i></b></summary>
+> 
+> ```ts
+> const myElement = document.querySelector("#myElement");
+> const htmlString = "<img onload='alert(\"XSS attack!\")' src='https://picsum.photos/100/100'>";
+> 
+> unsafeWindow.BYTM.setInnerHtmlTrusted(myElement, htmlString);
+> ```
+> </details>
+
+<br>
+
 > #### addSelectorListener()
 > Usage:  
 > ```ts

+ 2 - 1
src/interface.ts

@@ -1,7 +1,7 @@
 import * as UserUtils from "@sv443-network/userutils";
 import * as compareVersions from "compare-versions";
 import { mode, branch, host, buildNumber, compressionFormat, scriptInfo } from "./constants.js";
-import { getDomain, waitVideoElementReady, getResourceUrl, getSessionId, getVideoTime, log, setLocale, getLocale, hasKey, hasKeyFor, t, tp, type TrLocale, info, error, onInteraction, getThumbnailUrl, getBestThumbnailUrl, fetchVideoVotes } from "./utils/index.js";
+import { getDomain, waitVideoElementReady, getResourceUrl, getSessionId, getVideoTime, log, setLocale, getLocale, hasKey, hasKeyFor, t, tp, type TrLocale, info, error, onInteraction, getThumbnailUrl, getBestThumbnailUrl, fetchVideoVotes, setInnerHtmlTrusted } from "./utils/index.js";
 import { addSelectorListener } from "./observers.js";
 import { getFeatures, setFeatures } from "./config.js";
 import { autoLikeStore, featInfo, fetchLyricsUrlTop, getLyricsCacheEntry, sanitizeArtists, sanitizeSong } from "./features/index.js";
@@ -120,6 +120,7 @@ const globalFuncs: InterfaceFunctions = {
   getSessionId,
 
   // dom:
+  setInnerHtmlTrusted,
   addSelectorListener,
   onInteraction,
   getVideoTime,

+ 3 - 1
src/types.ts

@@ -4,7 +4,7 @@ import type { scriptInfo } from "./constants.js";
 import type { addSelectorListener } from "./observers.js";
 import type resources from "../assets/resources.json";
 import type locales from "../assets/locales.json";
-import type { getResourceUrl, getSessionId, getVideoTime, TrLocale, t, tp, fetchVideoVotes, onInteraction, getThumbnailUrl, getBestThumbnailUrl, getLocale, hasKey, hasKeyFor, getDomain, waitVideoElementReady } from "./utils/index.js";
+import type { getResourceUrl, getSessionId, getVideoTime, TrLocale, t, tp, fetchVideoVotes, onInteraction, getThumbnailUrl, getBestThumbnailUrl, getLocale, hasKey, hasKeyFor, getDomain, waitVideoElementReady, setInnerHtmlTrusted } from "./utils/index.js";
 import type { SiteEventsMap } from "./siteEvents.js";
 import type { InterfaceEventsMap, getAutoLikeDataInterface, getFeaturesInterface, getPluginInfo, registerPlugin, saveAutoLikeDataInterface, saveFeaturesInterface, setLocaleInterface } from "./interface.js";
 import type { BytmDialog, ExImDialog, createCircularBtn, createHotkeyInput, createRipple, createToggleInput, showIconToast, showToast } from "./components/index.js";
@@ -280,6 +280,8 @@ export type InterfaceFunctions = {
   getSessionId: typeof getSessionId;
 
   // dom:
+  /** Sets the innerHTML property of the provided element to a sanitized version of the provided HTML string */
+  setInnerHtmlTrusted: typeof setInnerHtmlTrusted;
   /** Adds a listener to one of the already present SelectorObserver instances */
   addSelectorListener: typeof addSelectorListener;
   /** Registers accessible interaction listeners (click, enter, space) on the provided element */