security: 环境变量密钥、密码加盐哈希、CSRF 防护
- config.py/web_server.py 支持环境变量注入 STF_TOKEN/WEB_SECRET_KEY,新增 .env 加载和 .env.example;.env 加入 gitignore - 用户密码从裸 SHA-256 改为 werkzeug 加盐哈希(scrypt),旧哈希登录时自动升级 - CSRF:session token + X-CSRF-Token 请求头校验非 GET 请求,前端自动携带
This commit is contained in:
+19
-3
@@ -6,18 +6,32 @@ const APP_NAMES={'com.ss.android.ugc.aweme':'抖音','com.ss.android.ugc.aweme.l
|
||||
|
||||
function esc(s){return String(s||'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));}
|
||||
|
||||
// ===== CSRF =====
|
||||
let _csrfToken='';
|
||||
// 页面加载后调用:获取 CSRF token,非 GET 请求需携带
|
||||
async function initCsrf(){
|
||||
try{
|
||||
const r=await fetch('/api/csrf');
|
||||
const d=await r.json();
|
||||
_csrfToken=d.token||'';
|
||||
}catch(e){}
|
||||
}
|
||||
function _csrfHeaders(){
|
||||
return _csrfToken?{'X-CSRF-Token':_csrfToken}:{};
|
||||
}
|
||||
|
||||
async function apiGet(url){
|
||||
const r=await fetch(url);
|
||||
if(r.status===401){window.location='/login';return null;}
|
||||
return r.json();
|
||||
}
|
||||
async function apiPost(url,body){
|
||||
const r=await fetch(url,{method:'POST',headers:{'Content-Type':'application/json'},body:body?JSON.stringify(body):'{}'});
|
||||
const r=await fetch(url,{method:'POST',headers:{'Content-Type':'application/json',..._csrfHeaders()},body:body?JSON.stringify(body):'{}'});
|
||||
if(r.status===401){window.location='/login';return null;}
|
||||
return r.json();
|
||||
}
|
||||
async function apiPut(url,body){
|
||||
const r=await fetch(url,{method:'PUT',headers:{'Content-Type':'application/json'},body:body?JSON.stringify(body):'{}'});
|
||||
const r=await fetch(url,{method:'PUT',headers:{'Content-Type':'application/json',..._csrfHeaders()},body:body?JSON.stringify(body):'{}'});
|
||||
if(r.status===401){window.location='/login';return null;}
|
||||
return r.json();
|
||||
}
|
||||
@@ -204,7 +218,7 @@ async function refreshShot(){
|
||||
}
|
||||
}
|
||||
async function apiDelete(url){
|
||||
const r=await fetch(url,{method:'DELETE'});
|
||||
const r=await fetch(url,{method:'DELETE',headers:_csrfHeaders()});
|
||||
if(r.status===401){window.location='/login';return null;}
|
||||
return r.json();
|
||||
}
|
||||
@@ -1856,6 +1870,7 @@ async function uploadApk(input){
|
||||
// 用 XMLHttpRequest 才能拿到上传进度(fetch 不支持上传进度事件)
|
||||
const xhr=new XMLHttpRequest();
|
||||
xhr.open('POST','/api/apks/upload');
|
||||
if(_csrfToken)xhr.setRequestHeader('X-CSRF-Token',_csrfToken);
|
||||
xhr.upload.onprogress=function(e){
|
||||
if(e.lengthComputable){
|
||||
const pct=Math.round(e.loaded*100/e.total);
|
||||
@@ -2053,4 +2068,5 @@ async function scanForeground(){
|
||||
}
|
||||
|
||||
// ================== 初始化 ==================
|
||||
initCsrf(); // 获取 CSRF token(非 GET 请求需携带)
|
||||
showTab('monitor');
|
||||
|
||||
Reference in New Issue
Block a user