51 lines
1.3 KiB
TypeScript
51 lines
1.3 KiB
TypeScript
import type { Request, Response } from "caido:utils";
|
||
|
||
export class NonceCheckController {
|
||
/**
|
||
* OIDC 플로우 탐지 로직 (OAuth 2.0과 구분)
|
||
*/
|
||
public static isOidcFlow(req: Request, res: Response): boolean {
|
||
const url = req.getUrl();
|
||
const query = req.getQuery();
|
||
const location = res.getHeader("Location");
|
||
const contentType = res.getHeader("Content-Type");
|
||
|
||
// 1️⃣ Authorization 요청: scope=openid 포함
|
||
if (url.includes("/authorize") && /response_type=/.test(query) && (/scope=openid/.test(query)) ){
|
||
return true;
|
||
}
|
||
|
||
// 2️⃣ Token 응답: id_token 필드 포함
|
||
if (contentType?.includes("application/json")) {
|
||
const body = res.getBody();
|
||
const bodyStr = typeof body === "string" ? body : body?.toString?.() ?? "";
|
||
if (bodyStr && /id_token/.test(bodyStr)) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
// 3️⃣ Redirect 응답: Location 헤더에 id_token 포함
|
||
if (
|
||
(res.getCode() === 302 || res.getCode() === 303) &&
|
||
location &&
|
||
/id_token=/.test(Array.isArray(location) ? location[0] ?? "" : location ?? "")
|
||
) {
|
||
return true;
|
||
}
|
||
|
||
// 4️⃣ Authorization 요청 + nonce 파라미터 포함
|
||
if (url.includes("/authorize") && /nonce=/.test(query)) {
|
||
return true;
|
||
}
|
||
|
||
|
||
|
||
return false;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
}
|