diff --git a/packages/backend/src/controller/nonceCheck.ts b/packages/backend/src/controller/nonceCheck.ts new file mode 100644 index 0000000..383ca90 --- /dev/null +++ b/packages/backend/src/controller/nonceCheck.ts @@ -0,0 +1,33 @@ +import type { Request } from "caido:utils"; +import { TokenLeakCheck } from "./tokenLeakCheck"; + +export class NonceCheckController{ + /** + * 응답이 OIDC(OpenID Connect) 플로우인지 확인하는 메서드 + */ + + public static isOidcFlow(req: Request): boolean { + if(TokenLeakCheck.extractIdToken(req)) { + return true; + } + return false; + } + + + public static isNonceCheckRequest(req: Request): boolean { + const id_token = decodeIdToken(req); + + // 1. nonce 파라미터가 포함된 요청인지 확인 + if (id_token.includes("nonce=")) { + return true; + } + + return false; + } +} + +function decodeIdToken(req: Request): string { + // Implement actual decoding logic here. For now, return an empty string or mock value. + return ""; +} + diff --git a/packages/backend/src/controller/tokenLeakCheck.ts b/packages/backend/src/controller/tokenLeakCheck.ts new file mode 100644 index 0000000..2248b49 --- /dev/null +++ b/packages/backend/src/controller/tokenLeakCheck.ts @@ -0,0 +1,42 @@ +import type { Request } from "caido:utils"; +import jwt from "jsonwebtoken"; + +export class TokenLeakCheck { + public static extractIdToken(req: Request): string | null { + // 1. Authorization 헤더 확인\\ + const header = req.getHeaders() as Record; + const authHeader = header["authorization"] || header["Authorization"]; + if (typeof authHeader === "string" && authHeader.startsWith("Bearer ")) { + return authHeader.slice(7).trim(); + } + + // 2. 쿼리 파라미터 + const query = req.getQuery(); + if (query && typeof query === "object" && "id_token" in query) { + return (query as Record).id_token; + } + + // 3. POST 바디 안에 id_token이 있을 경우 + const rawBody = req.getRaw(); + const body = rawBody ? rawBody.toString() : ""; + const match = body.match(/id_token=([^&\s]+)/); + if (match && typeof match[1] === "string") { + return decodeURIComponent(match[1]); + } + + return null; + } + + public static decodeIdToken(req: Request): Record | null { + const token = this.extractIdToken(req); + if (!token) return null; + + const decoded = jwt.decode(token, { complete: true }); + if (!decoded || typeof decoded !== "object") return null; + + return { + header: decoded.header, + payload: decoded.payload, + }; + } +}