diff --git a/modules/kubernetes/f1-stream/files/internal/proxy/proxy.go b/modules/kubernetes/f1-stream/files/internal/proxy/proxy.go index 8e20fcd1..92ce5b9e 100644 --- a/modules/kubernetes/f1-stream/files/internal/proxy/proxy.go +++ b/modules/kubernetes/f1-stream/files/internal/proxy/proxy.go @@ -91,13 +91,25 @@ if(_ss&&_ss.set){Object.defineProperty(el,'src',{get:function(){return _ss.get?_ } return el; }; -/* Neutralize anti-debug: override setInterval to skip debugger-based detection */ +/* Neutralize anti-debug: override setInterval/setTimeout to skip debugger-based detection */ var _si=window.setInterval; window.setInterval=function(fn,ms){ if(typeof fn==='function'){var s=fn.toString();if(s.indexOf('debugger')!==-1||s.indexOf('devtool')!==-1)return 0;} if(typeof fn==='string'&&(fn.indexOf('debugger')!==-1||fn.indexOf('devtool')!==-1))return 0; return _si.apply(this,arguments); }; +var _st=window.setTimeout; +window.setTimeout=function(fn,ms){ +if(typeof fn==='function'){var s=fn.toString();if(s.indexOf('debugger')!==-1||s.indexOf('devtool')!==-1)return 0;} +if(typeof fn==='string'&&(fn.indexOf('debugger')!==-1||fn.indexOf('devtool')!==-1))return 0; +return _st.apply(this,arguments); +}; +/* Override eval and Function to strip debugger statements */ +var _eval=window.eval; +window.eval=function(s){if(typeof s==='string')s=s.replace(/\bdebugger\b\s*;?/g,'');return _eval.call(this,s);}; +var _Fn=Function; +window.Function=function(){var a=[].slice.call(arguments);if(a.length>0){var last=a.length-1;if(typeof a[last]==='string')a[last]=a[last].replace(/\bdebugger\b\s*;?/g,'');}return _Fn.apply(this,a);}; +window.Function.prototype=_Fn.prototype; /* Block loading of known anti-debug scripts */ var _ael=HTMLScriptElement.prototype.setAttribute; HTMLScriptElement.prototype.setAttribute=function(n,v){ @@ -259,6 +271,18 @@ func NewHandler() http.Handler { return } + // For JavaScript responses, strip debugger statements + if strings.Contains(ct, "javascript") || strings.Contains(ct, "ecmascript") { + body, err := io.ReadAll(resp.Body) + if err != nil { + log.Printf("proxy: failed to read JS body: %v", err) + return + } + cleaned := debuggerStmtRe.ReplaceAllString(string(body), "/* */") + w.Write([]byte(cleaned)) + return + } + // Stream other responses directly io.Copy(w, resp.Body) }) @@ -298,6 +322,18 @@ var crossOriginIframeSrcRe = regexp.MustCompile(`(]*\ssrc\s*=\s*["'])( // disableDevtoolRe matches )?`) +// adScriptRe matches )?`) + +// adInlineRe matches inline `) + +// contextMenuBlockRe matches inline scripts that block right-click and dev tools shortcuts. +var contextMenuBlockRe = regexp.MustCompile(`(?i)]*>\s*document\.addEventListener\(\s*'contextmenu'[\s\S]{0,500}?`) + +// debuggerStmtRe matches debugger statements in JavaScript. +var debuggerStmtRe = regexp.MustCompile(`\bdebugger\b\s*;?`) + // rewriteHTML replaces URLs and injects the JS shim to intercept runtime requests. func rewriteHTML(body, origin, b64Origin string) string { proxyPrefix := "/proxy/" + b64Origin @@ -359,6 +395,14 @@ func rewriteHTML(body, origin, b64Origin string) string { // 5. Strip anti-debugging scripts (disable-devtool, devtools-detect) body = disableDevtoolRe.ReplaceAllString(body, "") + // 5b. Strip ad/popup scripts and context menu blockers + body = adScriptRe.ReplaceAllString(body, "") + body = adInlineRe.ReplaceAllString(body, "") + body = contextMenuBlockRe.ReplaceAllString(body, "") + + // 5c. Strip debugger statements from inline scripts + body = debuggerStmtRe.ReplaceAllString(body, "/* */") + // 6. Inject JS shim right after to intercept fetch/XHR/WebSocket shim := fmt.Sprintf(jsShimTemplate, b64Origin, origin) headIdx := strings.Index(strings.ToLower(body), "") diff --git a/modules/kubernetes/f1-stream/files/static/js/streams.js b/modules/kubernetes/f1-stream/files/static/js/streams.js index 21b634f4..7ded395b 100644 --- a/modules/kubernetes/f1-stream/files/static/js/streams.js +++ b/modules/kubernetes/f1-stream/files/static/js/streams.js @@ -367,6 +367,7 @@ function openBrowserSession(streamId, streamTitle, streamURL) { iframe.src = proxyURL; iframe.className = 'browser-iframe'; iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation'); + iframe.setAttribute('allow', 'autoplay; encrypted-media; fullscreen'); iframe.setAttribute('allowfullscreen', ''); iframe.onload = function() { loader.classList.add('hidden'); diff --git a/modules/kubernetes/f1-stream/main.tf b/modules/kubernetes/f1-stream/main.tf index 86d6f2a5..5eeba860 100644 --- a/modules/kubernetes/f1-stream/main.tf +++ b/modules/kubernetes/f1-stream/main.tf @@ -37,7 +37,7 @@ resource "kubernetes_deployment" "f1-stream" { } spec { container { - image = "viktorbarzin/f1-stream:v1.2.5" + image = "viktorbarzin/f1-stream:v1.2.6" name = "f1-stream" resources { limits = {