Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion _worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,21 @@ export default {
return new Response(读取日志内容, { status: 200, headers: { 'Content-Type': 'application/json;charset=utf-8' } });
} else if (区分大小写访问路径 === 'admin/getCloudflareUsage') {// 查询请求量
try {
const Usage_JSON = await getCloudflareUsage(url.searchParams.get('Email'), url.searchParams.get('GlobalAPIKey'), url.searchParams.get('AccountID'), url.searchParams.get('APIToken'));
// 优先从 POST body 读取凭据(避免敏感信息暴露在 URL / 服务器日志中)
// 兼容旧版 GET query 参数作为降级方案
let Email, GlobalAPIKey, AccountID, APIToken;
if (request.method === 'POST') {
try {
const body = await request.json();
Email = body.Email; GlobalAPIKey = body.GlobalAPIKey;
AccountID = body.AccountID; APIToken = body.APIToken;
} catch (_) { }
Comment on lines +89 to +96

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For POST requests, this attempts request.json() unconditionally and silently ignores parse errors. That means non-JSON/empty/malformed bodies fall back to query params with no signal, and the common case relies on exceptions for control flow. Consider gating parsing on Content-Type: application/json (you already compute contentType earlier) and returning a 400 for invalid JSON when method is POST, instead of swallowing the error.

Suggested change
try {
const body = await request.json();
Email = body.Email; GlobalAPIKey = body.GlobalAPIKey;
AccountID = body.AccountID; APIToken = body.APIToken;
} catch (_) { }
const contentType = request.headers.get('Content-Type') || '';
if (contentType.toLowerCase().startsWith('application/json')) {
let body;
try {
body = await request.json();
} catch (err) {
const errorResponse = { msg: '请求体不是有效的 JSON', error: err.message };
return new Response(JSON.stringify(errorResponse, null, 2), { status: 400, headers: { 'Content-Type': 'application/json;charset=utf-8' } });
}
Email = body.Email; GlobalAPIKey = body.GlobalAPIKey;
AccountID = body.AccountID; APIToken = body.APIToken;
}

Copilot uses AI. Check for mistakes.
}
Email = Email ?? url.searchParams.get('Email');
GlobalAPIKey = GlobalAPIKey ?? url.searchParams.get('GlobalAPIKey');
AccountID = AccountID ?? url.searchParams.get('AccountID');
APIToken = APIToken ?? url.searchParams.get('APIToken');

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still accepts credentials via GET query params as a fallback, which keeps the original leakage vector for any legacy callers. To help migration and reduce ongoing risk, consider adding an explicit deprecation signal when query params are used (e.g., a warning field in the JSON response or a Warning/Deprecation response header) so clients can detect and update.

Copilot uses AI. Check for mistakes.
const Usage_JSON = await getCloudflareUsage(Email, GlobalAPIKey, AccountID, APIToken);
Comment on lines +90 to +106

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Values read from JSON body may not be strings (e.g., AccountID could be a number). getCloudflareUsage sends AccountID to GraphQL as a String!, so a non-string value can cause the Cloudflare API to reject the request. Consider normalizing Email/GlobalAPIKey/AccountID/APIToken to strings (or validating types) before calling getCloudflareUsage.

Copilot uses AI. Check for mistakes.
return new Response(JSON.stringify(Usage_JSON, null, 2), { status: 200, headers: { 'Content-Type': 'application/json' } });
} catch (err) {
const errorResponse = { msg: '查询请求量失败,失败原因:' + err.message, error: err.message };
Expand Down