[Update] feature

This commit is contained in:
tv0924@icloud.com 2025-05-28 16:49:48 +09:00
commit ef1d8f40b3
7 changed files with 464 additions and 36 deletions

View file

@ -148,7 +148,7 @@ export class CsrfCheck {
sdk: SDK<DefineAPI<{}>, {}>,
request: Request,
response: Response
): Promise<string | 0> {
): Promise<void> {
let result = ``;
// 쿼리에 state 파라미터가 없으면 CSRF 위험
@ -170,9 +170,12 @@ export class CsrfCheck {
// }
if (result) {
return result; // CSRF risk detected
} else {
return 0; // No CSRF risk detected
await sdk.findings.create({
title: "csrf vuln",
description: `SSO-related parameters detected in response:\n\n${request.getMethod()} ${request.getUrl()} : ${result}`,
request,
reporter: "csrf reporter",
});
}
}
}

View file

@ -25,20 +25,7 @@ export function init(sdk: SDK<API>) {
sdk.events.onInterceptResponse(
async (sdk: SDK<DefineAPI<{}>, {}>, req: Request, resp: Response) => {
const funcList: Promise<string | 0>[] = [
csrfCheck.checker(sdk, req, resp),
];
let result = await Promise.all(funcList);
if (result) {
await sdk.findings.create({
title: "Possible SSO Response Detected",
description: `SSO-related parameters detected in response:\n\n${req.getMethod()} ${req.getUrl()} : ${result}`,
request: req,
reporter: "",
});
}
await csrfCheck.checker(sdk, req, resp);
await pkceCheck.test(sdk, req);
}
);

View file

@ -11,6 +11,19 @@ export class HttpUtils {
return instance;
}
/**
* URI
* @param value -
* @returns
*/
decodeAndLower(value: string): string {
try {
return decodeURIComponent(value).toLowerCase();
} catch {
return value.toLowerCase();
}
}
/**
* .
* @param headers - Record<string, string | string[]>
@ -22,14 +35,12 @@ export class HttpUtils {
const result: Record<string, string | string[]> = {};
for (const [rawKey, rawValue] of Object.entries(headers)) {
const key = rawKey.toLowerCase();
const key = this.decodeAndLower(rawKey);
if (Array.isArray(rawValue)) {
// 배열이면 각 요소를 소문자로
result[key] = rawValue.map((v) => v.toLowerCase());
result[key] = rawValue.map((v) => this.decodeAndLower(v));
} else {
// 단일 문자열이면 바로 소문자로
result[key] = rawValue.toLowerCase();
result[key] = this.decodeAndLower(rawValue);
}
}
@ -107,23 +118,29 @@ export class HttpUtils {
headers: Record<string, string | string[]>,
name: string
): string | null {
headers = this.lowerCaseAllHeaders(headers);
const normalized = this.lowerCaseAllHeaders(headers);
const target = name.toLowerCase();
for (const [key, value] of Object.entries(headers)) {
if (key.toLowerCase() === target) {
for (const [key, value] of Object.entries(normalized)) {
if (key === target) {
let rawValue: string | null = null;
if (Array.isArray(value)) {
// 배열 형태일 때 첫 번째 요소가 비어있을 수도 있으니 안전하게 처리
return value.length > 0 &&
value[0] !== undefined &&
value[0].length > 0
? value[0]
: null;
rawValue = value.length > 0 && value[0] ? value[0] : null;
} else {
rawValue = value.length > 0 ? value : null;
}
if (rawValue !== null) {
try {
return decodeURIComponent(rawValue);
} catch {
return rawValue;
}
}
// 문자열일 때
return value.length > 0 ? value : null;
}
}
return null;
}