import { Flaw } from "./index.js"; import { INTERACTIVE_EXAMPLES_BASE_URL, LIVE_SAMPLES_BASE_URL, } from "../../libs/env/index.js"; import { findMatchesInText } from "../matches.js"; import * as cheerio from "cheerio"; import { Doc } from "../../libs/types/document.js"; const safeIFrameSrcs = [ // EmbedGHLiveSample.ejs "https://mdn.github.io", // EmbedYouTube.ejs "https://www.youtube-nocookie.com", // JSFiddleEmbed.ejs "https://jsfiddle.net", // EmbedTest262ReportResultsTable.ejs "https://test262.report", ]; if (LIVE_SAMPLES_BASE_URL) { safeIFrameSrcs.push(LIVE_SAMPLES_BASE_URL.toLowerCase()); } if (INTERACTIVE_EXAMPLES_BASE_URL) { safeIFrameSrcs.push(INTERACTIVE_EXAMPLES_BASE_URL.toLowerCase()); } function getAndMarkupUnsafeHTMLFlaws( doc: Partial, $: cheerio.CheerioAPI, { rawContent, fileInfo } ) { const flaws: Flaw[] = []; function addFlaw(element: cheerio.Element, explanation: string) { const id = `unsafe_html${flaws.length + 1}`; let html = $.html($(element)); $(element).replaceWith($("").addClass("unsafe-html").text(html)); // Some nasty tags are so broken they can make the HTML become more or less // the whole page. E.g. ``. if (html.length > 100) { html = html.slice(0, Math.min(html.indexOf("\n"), 100)) + "…"; } // Perhaps in the future we can make it possibly fixable to delete it. const fixable = false; const flaw: Flaw = { explanation, id, fixable, html, suggestion: null, }; for (const { line, column } of findMatchesInText(html, rawContent)) { // This might not find anything because the HTML might have mutated // slightly because of how cheerio parses it. But it doesn't hurt to try. flaw.line = line; flaw.column = column; } flaws.push(flaw); } $("script, embed, object, iframe, style").each((i, element) => { const { tagName } = element; if (tagName === "iframe") { // For iframes we only check the 'src' value const src = $(element).attr("src"); if (!src) { console.warn( `${fileInfo.path} has an iframe without a 'src' attribute` ); return; } // Local URLs are always safe. if (!(src.startsWith("//") || src.includes("://"))) { return; } if (!safeIFrameSrcs.find((s) => src.toLowerCase().startsWith(s))) { addFlaw(element, `Unsafe