1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-10 21:33:27 +00:00
Files
browser/libs/eslint/platform/no-page-script-url-leakage.spec.mjs
Addison Beck ba93526965 chore: create eslint rule to catch insecure page script injection (#17437)
* chore: create eslint rule to catch insecure page script injection

* chore: ignore existing lints

* review: tighten rule scope

* review: add tests
2025-11-20 19:45:49 -05:00

152 lines
3.9 KiB
JavaScript

import { RuleTester } from "@typescript-eslint/rule-tester";
import rule, { errorMessage } from "./no-page-script-url-leakage.mjs";
const ruleTester = new RuleTester({
languageOptions: {
parserOptions: {
project: [__dirname + "/../tsconfig.spec.json"],
projectService: {
allowDefaultProject: ["*.ts*"],
},
tsconfigRootDir: __dirname + "/..",
},
},
});
ruleTester.run("no-page-script-url-leakage", rule.default, {
valid: [
{
name: "Non-script element with extension URL (iframe)",
code: `
const iframe = document.createElement("iframe");
iframe.src = chrome.runtime.getURL("popup.html");
`,
},
{
name: "Non-script element with extension URL (img)",
code: `
const img = document.createElement("img");
img.src = chrome.runtime.getURL("icon.png");
`,
},
{
name: "Script element with non-extension URL",
code: `
const script = document.createElement("script");
script.src = "https://example.com/script.js";
`,
},
{
name: "Extension URL call without DOM assignment",
code: `
const url = chrome.runtime.getURL("assets/icon.png");
console.log(url);
`,
},
{
name: "Browser runtime call without DOM assignment",
code: `
const url = browser.runtime.getURL("content/style.css");
fetch(url);
`,
},
{
name: "Script assignment with variable not from createElement",
code: `
const script = getSomeScriptElement();
script.src = chrome.runtime.getURL("script.js");
`,
},
{
name: "Assignment to different property",
code: `
const script = document.createElement("script");
script.type = "text/javascript";
`,
},
],
invalid: [
{
name: "Script element with chrome.runtime.getURL - variable declaration",
code: `
const script = document.createElement("script");
script.src = chrome.runtime.getURL("content/script.js");
`,
errors: [
{
message: errorMessage,
},
],
},
{
name: "Script element with browser.runtime.getURL - variable declaration",
code: `
const script = document.createElement("script");
script.src = browser.runtime.getURL("content/script.js");
`,
errors: [
{
message: errorMessage,
},
],
},
{
name: "Script element with chrome.runtime.getURL - assignment expression",
code: `
let script;
script = document.createElement("script");
script.src = chrome.runtime.getURL("page-script.js");
`,
errors: [
{
message: errorMessage,
},
],
},
{
name: "Script element with browser.runtime.getURL - assignment expression",
code: `
let element;
element = document.createElement("script");
element.src = browser.runtime.getURL("fido2-page-script.js");
`,
errors: [
{
message: errorMessage,
},
],
},
{
name: "Multiple script elements with different variable names",
code: `
const scriptA = document.createElement("script");
const scriptB = document.createElement("script");
scriptA.src = chrome.runtime.getURL("script-a.js");
scriptB.src = browser.runtime.getURL("script-b.js");
`,
errors: [
{
message: errorMessage,
},
{
message: errorMessage,
},
],
},
{
name: "Real-world pattern that prompted creation of this lint rule",
code: `
const script = globalThis.document.createElement("script");
script.src = chrome.runtime.getURL("content/fido2-page-script.js");
script.async = false;
`,
errors: [
{
message: errorMessage,
},
],
},
],
});