Fix Trusted Types violation in manifest interceptor injection, which fixes data not showing for YouTube DRM

This commit is contained in:
voldemort 2025-07-20 17:43:13 +07:00
parent 889a4c63f3
commit 6e22837047
2 changed files with 202 additions and 160 deletions

View File

@ -70,9 +70,8 @@ function safeHeaderShellEscape(str) {
// Intercep network to find manifest // Intercep network to find manifest
function injectManifestInterceptor() { function injectManifestInterceptor() {
const script = document.createElement("script"); // Execute the interceptor code directly instead of injecting a script
script.textContent = ` (function () {
(function() {
function isProbablyManifest(text = "", contentType = "") { function isProbablyManifest(text = "", contentType = "") {
const lowerCT = contentType?.toLowerCase() ?? ""; const lowerCT = contentType?.toLowerCase() ?? "";
const sample = text.slice(0, 2000); const sample = text.slice(0, 2000);
@ -87,13 +86,18 @@ function injectManifestInterceptor() {
const isJsonManifest = sample.includes('"playlist"') && sample.includes('"segments"'); const isJsonManifest = sample.includes('"playlist"') && sample.includes('"segments"');
return ( return (
isHLSMime || isDASHMime || isSmoothMime || isHLSMime ||
isHLSKeyword || isDASHKeyword || isSmoothKeyword || isJsonManifest isDASHMime ||
isSmoothMime ||
isHLSKeyword ||
isDASHKeyword ||
isSmoothKeyword ||
isJsonManifest
); );
} }
const originalFetch = window.fetch; const originalFetch = window.fetch;
window.fetch = async function(input, init) { window.fetch = async function (input, init) {
const response = await originalFetch.apply(this, arguments); const response = await originalFetch.apply(this, arguments);
try { try {
@ -113,14 +117,24 @@ function injectManifestInterceptor() {
}); });
const headerFlags = Object.entries(headersObj) const headerFlags = Object.entries(headersObj)
.map(([key, val]) => '--add-headers "' + safeHeaderShellEscape(key) + ': ' + safeHeaderShellEscape(val) + '"') .map(
([key, val]) =>
'--add-headers "' +
safeHeaderShellEscape(key) +
": " +
safeHeaderShellEscape(val) +
'"'
)
.join(" "); .join(" ");
window.postMessage({ window.postMessage(
{
type: "__MANIFEST_HEADERS__", type: "__MANIFEST_HEADERS__",
url, url,
headers: headerFlags headers: headerFlags,
}, "*"); },
"*"
);
} }
} catch (e) {} } catch (e) {}
@ -130,12 +144,12 @@ function injectManifestInterceptor() {
const originalXHROpen = XMLHttpRequest.prototype.open; const originalXHROpen = XMLHttpRequest.prototype.open;
const originalXHRSend = XMLHttpRequest.prototype.send; const originalXHRSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function(method, url) { XMLHttpRequest.prototype.open = function (method, url) {
this.__url = url; this.__url = url;
return originalXHROpen.apply(this, arguments); return originalXHROpen.apply(this, arguments);
}; };
XMLHttpRequest.prototype.send = function(body) { XMLHttpRequest.prototype.send = function (body) {
this.addEventListener("load", function () { this.addEventListener("load", function () {
try { try {
const contentType = this.getResponseHeader("content-type") || ""; const contentType = this.getResponseHeader("content-type") || "";
@ -146,8 +160,8 @@ function injectManifestInterceptor() {
console.log("[Manifest][xhr]", this.__url, contentType); console.log("[Manifest][xhr]", this.__url, contentType);
const xhrHeaders = {}; const xhrHeaders = {};
const rawHeaders = this.getAllResponseHeaders().trim().split(/\\r?\\n/); const rawHeaders = this.getAllResponseHeaders().trim().split(/\r?\n/);
rawHeaders.forEach(line => { rawHeaders.forEach((line) => {
const parts = line.split(": "); const parts = line.split(": ");
if (parts.length === 2) { if (parts.length === 2) {
xhrHeaders[parts[0]] = parts[1]; xhrHeaders[parts[0]] = parts[1];
@ -155,23 +169,30 @@ function injectManifestInterceptor() {
}); });
const headerFlags = Object.entries(xhrHeaders) const headerFlags = Object.entries(xhrHeaders)
.map(([key, val]) => '--add-headers "' + safeHeaderShellEscape(key) + ': ' + safeHeaderShellEscape(val) + '"') .map(
([key, val]) =>
'--add-headers "' +
safeHeaderShellEscape(key) +
": " +
safeHeaderShellEscape(val) +
'"'
)
.join(" "); .join(" ");
window.postMessage({ window.postMessage(
{
type: "__MANIFEST_HEADERS__", type: "__MANIFEST_HEADERS__",
url: this.__url, url: this.__url,
headers: headerFlags headers: headerFlags,
}, "*"); },
"*"
);
} }
} catch (e) {} } catch (e) {}
}); });
return originalXHRSend.apply(this, arguments); return originalXHRSend.apply(this, arguments);
}; };
})(); })();
`;
document.documentElement.appendChild(script);
script.remove();
} }
injectManifestInterceptor(); injectManifestInterceptor();

View File

@ -70,9 +70,8 @@ function safeHeaderShellEscape(str) {
// Intercep network to find manifest // Intercep network to find manifest
function injectManifestInterceptor() { function injectManifestInterceptor() {
const script = document.createElement("script"); // Execute the interceptor code directly instead of injecting a script
script.textContent = ` (function () {
(function() {
function isProbablyManifest(text = "", contentType = "") { function isProbablyManifest(text = "", contentType = "") {
const lowerCT = contentType?.toLowerCase() ?? ""; const lowerCT = contentType?.toLowerCase() ?? "";
const sample = text.slice(0, 2000); const sample = text.slice(0, 2000);
@ -87,13 +86,18 @@ function injectManifestInterceptor() {
const isJsonManifest = sample.includes('"playlist"') && sample.includes('"segments"'); const isJsonManifest = sample.includes('"playlist"') && sample.includes('"segments"');
return ( return (
isHLSMime || isDASHMime || isSmoothMime || isHLSMime ||
isHLSKeyword || isDASHKeyword || isSmoothKeyword || isJsonManifest isDASHMime ||
isSmoothMime ||
isHLSKeyword ||
isDASHKeyword ||
isSmoothKeyword ||
isJsonManifest
); );
} }
const originalFetch = window.fetch; const originalFetch = window.fetch;
window.fetch = async function(input, init) { window.fetch = async function (input, init) {
const response = await originalFetch.apply(this, arguments); const response = await originalFetch.apply(this, arguments);
try { try {
@ -113,14 +117,24 @@ function injectManifestInterceptor() {
}); });
const headerFlags = Object.entries(headersObj) const headerFlags = Object.entries(headersObj)
.map(([key, val]) => '--add-headers "' + safeHeaderShellEscape(key) + ': ' + safeHeaderShellEscape(val) + '"') .map(
([key, val]) =>
'--add-headers "' +
safeHeaderShellEscape(key) +
": " +
safeHeaderShellEscape(val) +
'"'
)
.join(" "); .join(" ");
window.postMessage({ window.postMessage(
{
type: "__MANIFEST_HEADERS__", type: "__MANIFEST_HEADERS__",
url, url,
headers: headerFlags headers: headerFlags,
}, "*"); },
"*"
);
} }
} catch (e) {} } catch (e) {}
@ -130,12 +144,12 @@ function injectManifestInterceptor() {
const originalXHROpen = XMLHttpRequest.prototype.open; const originalXHROpen = XMLHttpRequest.prototype.open;
const originalXHRSend = XMLHttpRequest.prototype.send; const originalXHRSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function(method, url) { XMLHttpRequest.prototype.open = function (method, url) {
this.__url = url; this.__url = url;
return originalXHROpen.apply(this, arguments); return originalXHROpen.apply(this, arguments);
}; };
XMLHttpRequest.prototype.send = function(body) { XMLHttpRequest.prototype.send = function (body) {
this.addEventListener("load", function () { this.addEventListener("load", function () {
try { try {
const contentType = this.getResponseHeader("content-type") || ""; const contentType = this.getResponseHeader("content-type") || "";
@ -146,8 +160,8 @@ function injectManifestInterceptor() {
console.log("[Manifest][xhr]", this.__url, contentType); console.log("[Manifest][xhr]", this.__url, contentType);
const xhrHeaders = {}; const xhrHeaders = {};
const rawHeaders = this.getAllResponseHeaders().trim().split(/\\r?\\n/); const rawHeaders = this.getAllResponseHeaders().trim().split(/\r?\n/);
rawHeaders.forEach(line => { rawHeaders.forEach((line) => {
const parts = line.split(": "); const parts = line.split(": ");
if (parts.length === 2) { if (parts.length === 2) {
xhrHeaders[parts[0]] = parts[1]; xhrHeaders[parts[0]] = parts[1];
@ -155,23 +169,30 @@ function injectManifestInterceptor() {
}); });
const headerFlags = Object.entries(xhrHeaders) const headerFlags = Object.entries(xhrHeaders)
.map(([key, val]) => '--add-headers "' + safeHeaderShellEscape(key) + ': ' + safeHeaderShellEscape(val) + '"') .map(
([key, val]) =>
'--add-headers "' +
safeHeaderShellEscape(key) +
": " +
safeHeaderShellEscape(val) +
'"'
)
.join(" "); .join(" ");
window.postMessage({ window.postMessage(
{
type: "__MANIFEST_HEADERS__", type: "__MANIFEST_HEADERS__",
url: this.__url, url: this.__url,
headers: headerFlags headers: headerFlags,
}, "*"); },
"*"
);
} }
} catch (e) {} } catch (e) {}
}); });
return originalXHRSend.apply(this, arguments); return originalXHRSend.apply(this, arguments);
}; };
})(); })();
`;
document.documentElement.appendChild(script);
script.remove();
} }
injectManifestInterceptor(); injectManifestInterceptor();