[Update] feature
This commit is contained in:
parent
f775282e91
commit
ef1d8f40b3
7 changed files with 464 additions and 36 deletions
|
|
@ -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",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue