[Add] PKCE 체크 및 관련 기능 구현, Playground 디렉토리 정리

This commit is contained in:
imnyang 2025-05-26 00:56:03 +09:00
commit 0a24c5594d
No known key found for this signature in database
GPG key ID: 356406A02D4AFA55
13 changed files with 164 additions and 140 deletions

View file

@ -11,18 +11,20 @@ export class PKCECheck {
}
const query = req.getQuery();
const requiredParams = ["client_id=", "response_type=code", "code_challenge=", "code_challenge_method="];
if (!requiredParams.every(param => query.includes(param))) {
const searchParams = new URLSearchParams(query);
const requiredKeys = ["client_id", "response_type", "code_challenge", "code_challenge_method"];
if (!requiredKeys.every((key) => searchParams.has(key))) {
sdk.console.log("[PKCEDowngradeCheck] Required PKCE parameters missing. Skipping.");
return false;
}
const url = req.getUrl();
const isOpenID = query.includes("scope=openid") || query.includes("id_token");
const methodMatch = query.match(/code_challenge_method=([^&]*)/);
const challengeMatch = query.match(/code_challenge=([^&]*)/);
const isOpenID = searchParams.get("scope")?.includes("openid") || url.includes("id_token");
const methodVal = searchParams.get("code_challenge_method");
const challengeVal = searchParams.get("code_challenge");
if (!methodMatch || !challengeMatch) {
if (!methodVal || !challengeVal) {
sdk.console.log("[PKCEDowngradeCheck] code_challenge or method missing. Skipping.");
await sdk.findings.create({
title: isOpenID
@ -35,7 +37,6 @@ export class PKCECheck {
return false;
}
const methodVal = decodeURIComponent(methodMatch[1]!);
if (methodVal === "plain") {
sdk.console.log("[PKCEDowngradeCheck] code_challenge_method is 'plain'. Skipping.");
await sdk.findings.create({
@ -46,26 +47,24 @@ export class PKCECheck {
request: req,
reporter: "",
});
return false;
}
const downgradedQuery = query
.replace(/code_challenge_method=[^&]*&?/, "")
.replace(/code_challenge=[^&]*&?/, "")
.replace(/[?&]$/, "");
// Remove PKCE parameters to simulate a downgraded request
searchParams.delete("code_challenge");
searchParams.delete("code_challenge_method");
const downgradedQuery = searchParams.toString();
const downgradedUrl = `${req.getUrl().split("://")[0]}://${req.getHost()}:${req.getPort()}${req.getPath()}?${downgradedQuery}`;
try {
const [resOriginal, resDowngraded] = await Promise.all([
fetch(new FetchRequest(url, { method: "GET" })),
fetch(new FetchRequest(downgradedUrl, { method: "GET" }))
fetch(new FetchRequest(downgradedUrl, { method: "GET" })),
]);
const [bodyOriginal, bodyDowngraded] = await Promise.all([
resOriginal.text(),
resDowngraded.text()
resDowngraded.text(),
]);
const statusEqual = resOriginal.status === resDowngraded.status;