diff --git a/.eslintrc b/.eslintrc index 4b22eee7..ccb78fd5 100644 --- a/.eslintrc +++ b/.eslintrc @@ -26,7 +26,7 @@ "@typescript-eslint/no-explicit-any": "off", "no-param-reassign": "off", - "max-len": ["error", { "code": 80, "ignoreComments": true }], + "max-len": ["error", { "code": 120, "ignoreComments": true }], // 不要求对 import 进行排序 "import/order": "off", diff --git a/.github/workflows/lint-and-test-code.yml b/.github/workflows/lint-and-test-code.yml index b761e5ea..50181fcf 100644 --- a/.github/workflows/lint-and-test-code.yml +++ b/.github/workflows/lint-and-test-code.yml @@ -16,7 +16,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@master with: - node-version: '12.x' + node-version: '22.x' - name: Install Dependencies run: yarn - name: Commit Linter diff --git a/lib/core/runtime/capture/index.ts b/lib/core/runtime/capture/index.ts index 6bdb6bbd..312eabc7 100644 --- a/lib/core/runtime/capture/index.ts +++ b/lib/core/runtime/capture/index.ts @@ -20,6 +20,52 @@ import logger from "../../logger/index"; type requestProtocol = "http:" | "https:"; +const SENSITIVE_HEADERS = new Set([ + "authorization", + "proxy-authorization", + "x-api-key", + "cookie", + "set-cookie" +]); + +/** + * Mask sensitive header values in a header string. + * e.g. "cookie: abc123" => "cookie: ***" + */ +const maskSensitiveHeaders = (headerStr: string): string => { + if (!headerStr) return headerStr; + + return headerStr.replace( + /^([^:]+):\s*(.+)$/gm, + (match, key: string) => { + if (SENSITIVE_HEADERS.has(key.trim().toLowerCase())) { + return `${key}: ***`; + } + + return match; + } + ); +}; + +/** + * Create a sanitized copy of requestLog for safe logging. + */ +const sanitizeRequestLog = ( + log: Partial +): Partial => { + const sanitized = { ...log }; + + if (sanitized.requestHeader) { + sanitized.requestHeader = maskSensitiveHeaders(sanitized.requestHeader); + } + + if (sanitized.responseHeader) { + sanitized.responseHeader = maskSensitiveHeaders(sanitized.responseHeader); + } + + return sanitized; +}; + /** * Convert a URL instance to a http.request options * https://github.com/nodejs/node/blob/afa9a7206c26a29a2af226696c145c924a6d3754/lib/internal/url.js#L1270 @@ -133,13 +179,9 @@ export const hack = ( address || "null"}. Cost ${timestamps.dnsTime}ms`); if (err) { - if (logger.getCleanLog()) { - logger.error(`${logPre} Request: - ${JSON.stringify(requestLog)}`); - } + logger.error(`${logPre} Lookup ${host} -> ${address || "null"}, error ${err.stack}`); - logger.error(`${logPre} Lookup ${host} -> ${ - address || "null"}, error ${err.stack}`); + logger.error(`${logPre} Request: ${JSON.stringify(sanitizeRequestLog(requestLog))}`); } }); } @@ -164,11 +206,10 @@ export const hack = ( }); request.once("error", (error: Error) => { - if (logger.getCleanLog()) { - logger.error(`${logPre} Request: ${JSON.stringify(requestLog)}`); - } - logger.error(`${logPre} Request error. Stack: ${error.stack}`); + + logger.error(`${logPre} Request: ${JSON.stringify(sanitizeRequestLog(requestLog))}`); + finishRequest(); clearDomain(); });