mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 17:43:47 +00:00
fix(security): validate the deep-link url in miniapp/redirect.html (open redirect + DOM-XSS)
public/miniapp/redirect.html read the `url` query param and assigned it to both the manual <a href> and window.location.href with no validation. Served on the cabinet's own origin, this was an open redirect (phishing) and — in Telegram / WebView contexts that execute javascript: URIs in top-level navigation — a DOM-XSS able to exfiltrate the refresh_token from localStorage (account takeover). Add isSafeAppLink(): only a custom app deep link passes (scheme://, excluding http/https/file/blob/about/intent/content and the javascript/data/vbscript script schemes); anything else renders the no-URL state instead of navigating or setting href. Mirrors the validation already in src/pages/DeepLinkRedirect.tsx.
This commit is contained in:
@@ -124,7 +124,21 @@
|
|||||||
document.getElementById('errorText').textContent = t.error;
|
document.getElementById('errorText').textContent = t.error;
|
||||||
document.getElementById('manualBtn').textContent = t.btn;
|
document.getElementById('manualBtn').textContent = t.btn;
|
||||||
|
|
||||||
if (!url) {
|
// SECURITY: this page navigates to a user-supplied `url`. Only open
|
||||||
|
// a custom app deep link. A bare `javascript:`/`data:`/`vbscript:`/
|
||||||
|
// `file:` URI (DOM-XSS) is not scheme://-shaped, and http(s)/intent
|
||||||
|
// are blocked (open redirect / intent abuse) — so only VPN app
|
||||||
|
// schemes (happ://, vless://, ...) pass. Mirrors the validation in
|
||||||
|
// src/pages/DeepLinkRedirect.tsx.
|
||||||
|
function isSafeAppLink(raw) {
|
||||||
|
var s = String(raw || '').trim().toLowerCase();
|
||||||
|
var m = s.match(/^([a-z][a-z0-9+.\-]*):\/\//);
|
||||||
|
if (!m) return false;
|
||||||
|
var blocked = ['http', 'https', 'file', 'blob', 'about', 'javascript', 'data', 'vbscript', 'intent', 'content'];
|
||||||
|
return blocked.indexOf(m[1]) === -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!url || !isSafeAppLink(url)) {
|
||||||
document.getElementById('title').textContent = t.noUrl;
|
document.getElementById('title').textContent = t.noUrl;
|
||||||
document.getElementById('subtitle').textContent = '';
|
document.getElementById('subtitle').textContent = '';
|
||||||
document.querySelector('.spinner').style.display = 'none';
|
document.querySelector('.spinner').style.display = 'none';
|
||||||
|
|||||||
Reference in New Issue
Block a user