fix: security hardening and code review improvements
Build and Push Docker Image / build (push) Successful in 12s

- hls proxy now signs full URL instead of hostname only (SSRF)
- viewer token required to start session (prevents stats forgery and password bypass)
- weak SECRET_KEY placeholder replaced with REPLACE_ME, startup warning added
- api key auth drops query-string fallback, Bearer header only
- hls variant playlist DRM detection fetches first variant
- dash manifest DRM detection added
- android webview detection restricted to Telegram only
- privacy comment removed from ip hash (ip is stored in plaintext)
- csv export adds range filter (today/7d/30d/all), defaults to 30d
- analytics export button integrated as dropdown with range selection
- docker-compose placeholder defaults updated
- readme and readme.zh-cn updated for v1.2.0 changes
This commit is contained in:
Stardream
2026-05-24 01:40:03 +10:00
parent 601eb0247f
commit 2b0aaf3a5d
7 changed files with 162 additions and 50 deletions
+6 -2
View File
@@ -402,7 +402,7 @@
function isAndroidRestrictedWebView() {
const ua = navigator.userAgent || '';
if (!/Android/i.test(ua)) return false;
return /Telegram/i.test(ua) || /; wv\)/i.test(ua) || /\bwv\b/i.test(ua);
return /Telegram/i.test(ua);
}
function selectDrmConfig(link) {
@@ -555,6 +555,7 @@
let viewerHeartbeatTimer = null;
let viewerSessionId = '';
let viewerVisitorId = localStorage.getItem('streamhall_visitor_id') || '';
let viewerToken = '';
let playerInstance = null;
let playbackMisses = 0;
if (!viewerVisitorId) {
@@ -632,6 +633,7 @@
const data = await postViewerEvent('viewer_start', {
id: streamId,
visitorId: viewerVisitorId,
viewerToken,
referer: document.referrer || '',
state: viewerState()
});
@@ -739,6 +741,7 @@
els.pwdModal.classList.remove('hidden');
document.getElementById('pwd-in').focus();
} else {
viewerToken = data.viewerToken || '';
startViewerStats();
waitForLiveAndStart(data);
}
@@ -754,6 +757,7 @@
applyPlayerTitle(data);
applySiteIcon(data.siteIconUrl || '');
els.pwdModal.classList.add('hidden');
viewerToken = data.viewerToken || '';
startViewerStats();
waitForLiveAndStart(data, pwd);
} catch (err) {
@@ -814,7 +818,7 @@
quality: quality,
title: data.eventName,
autoplay: true,
isLive: linkUsesShakaDrm(initialLink),
isLive: data.streamLabel === 'LIVE',
volume: 0.5,
autoSize: true,
fullscreen: true,