--- name: exploiting-auth-session description: >- SQIsoft 웹 애플리케이션에서 인증·세션·JWT 취약점의 실제 악용 가능성을 동적으로 확정한다. 정상 토큰을 base64로 변조(alg=none·서명 제거·역할 변조·만료)해 보호 엔드포인트에 발사하고, 로그아웃 후 토큰 재사용과 로그인 응답 쿠키 보안속성(Secure/HttpOnly/SameSite)을 점검한다. 발사 전 scope_guard를 fail-closed로 강제 통과하며 비파괴가 기본이다. 변조 토큰이 4xx로 거부되면 안전(정상)으로 판정한다. domain: cybersecurity subdomain: web-application-security tags: - authentication - session - jwt - dast - cwe-287 - cwe-613 - cwe-614 - owasp-a07 - sqisoft cwe: - CWE-287 - CWE-613 - CWE-614 owasp: - A07:2021-Identification-and-Authentication-Failures stacks: - spring-modern - jsp-legacy version: "0.3.0" author: sqisoft-security license: Proprietary --- # 동적 인증·세션 침투 (JWT 변조 · 토큰 재사용 · 쿠키 속성) > ⚠️ **권한 있는 사내 보안 테스트(펜테스트) 전용.** 자사 소유 + 격리된 스테이징/로컬만 대상. > `tools/scope_guard.py`가 운영·공인·IP 위장을 코드로 차단한다. ## When to Use - `detecting-auth-session-weaknesses` 정적 진단에서 JWT 서명검증·세션 폐기·쿠키 속성 후보가 나왔고, 실제 악용 가능 여부를 확정하고 싶을 때 - JWT가 실제로 서명을 검증하는지(변조 토큰 거부) 실증할 때 - 로그아웃이 토큰을 실제로 폐기하는지 실증할 때 - 로그인 응답 쿠키의 Secure/HttpOnly/SameSite 누락을 확인할 때 ## Prerequisites - 실행 중인 스테이징/로컬 대상 - **테스트 계정 1개(A)** — 정상 로그인용. `--token-a`로 토큰 직접 주입 가능(단 이 경우 쿠키 검사는 불가) - (선택) 정적 결과 `--scan ` — probe(보호 엔드포인트) 후보 자동 추출용. 또는 `--probe`로 직접 지정 ## Workflow ### 0단계 — 안전 범위 확인 (강제) ```bash python tools/scope_guard.py ``` ### 1단계 — 실제 발사 ```bash python skills/exploiting-auth-session/scripts/attack_auth.py \ http://localhost:7171 \ --user-a-id --user-a-pw \ --scan reports/scan_access.json \ --json # 또는 보호 엔드포인트 직접 지정: # --probe /api/v1/users/me # 로그인 형식이 다르면: --login-path · --body-template '{"lgnId":"{id}","password":"{pw}"}' · --token-path data.accessToken # 로그아웃 경로: --logout-path (기본 /api/v1/auth/logout) ``` 흐름: scope 확인 → 로그인(토큰 + Set-Cookie) → probe 선택(정상 토큰으로 200 나는 GET) → JWT 변조 4변형·토큰 재사용·쿠키 점검 → JSON ### 2단계 — 판정 | 검사 | 결과 | |---|---| | JWT 변조 4변형(alg=none·서명제거·역할·만료) | `2xx` = **서명 미검증 취약** / `401·403` = 방어(정상) | | 로그아웃 후 토큰 재사용 | `2xx` = **폐기 안 됨(취약)** / `401` = 정상 | | 쿠키 속성 | Secure/HttpOnly/SameSite **누락 = 취약** | > 변조 토큰이 **4xx로 거부되면 안전**이다 — 거부를 취약으로 오해하지 않는다. STATELESS JWT는 access가 헤더라 쿠키 속성은 refresh 쿠키만 대상. 신뢰도는 동적 발사 결과이므로 `dynamic`. ### 3단계 — AI 검증 + 리포트 `2xx` 취약 후보만 실제 코드(JWT 검증 로직·세션 폐기·쿠키 설정)로 재확인 후, 확정 항목을 4요소로 `reports/pentest-auth-<대상>.md`에 저장한다. ## 비파괴 정책 - probe는 GET, logout(POST)은 **본인 토큰의 세션 종료**라 비파괴 범주. - 데이터 변조/삭제 페이로드 없음. - **로그아웃 병렬 금지**: 토큰 재사용 검사(`run_token_reuse`)는 대상 계정을 로그아웃시켜 세션을 무효화한다. 서버가 전체 세션 로그아웃(모든 기기 무효화)·refresh 회전 방식이면 같은 계정을 쓰는 다른 세션이 끊긴다. **동일 테스트 계정을 여러 프로세스(병렬 audit 등)가 동시에 사용하지 않는다.** ## Output Format ```markdown # 동적 인증·세션 침투 리포트 - 대상: | probe: <경로> | 점검일: | 신뢰도: 동적 확정(dynamic) ## 확정 취약점 ### [High] JWT 서명 미검증 — alg=none 토큰 수용 — GET /api/v1/users/me - **① 취약한 점**: alg=none 변조 토큰으로 200 반환(서명 검증 안 함) - **② 이유**: 서명 미검증 시 임의 사용자/권한 토큰 위조 가능 - **③ Evidence**: `alg_none` 토큰 → HTTP 200 - **④ 해결방법**: 서명 알고리즘 고정(HS256/RS256), alg=none 거부, jjwt parseSignedClaims 사용 ``` ## 안전 (ATTACK_SAFETY.md 계승) - 모든 발사 전 `scope_guard.assert_in_scope()` 강제(fail-closed). - 토큰·자격은 출력 시 마스킹(`dyn_session.mask_token`). - **자격 노출 주의**: 토큰·비밀번호를 CLI 인자(`--token-a`·`--user-a-pw`)로 넘기면 프로세스 목록 (작업관리자/`ps`)에 노출될 수 있다. 공유·멀티유저 호스트를 피하고 단일 운영자 환경에서 테스트 계정으로만 실행한다. ## Tools & Systems - 공용 엔진: `tools/dyn_session.py` (로그인·인증 HTTP·응답 헤더·scope 위임) - 안전 게이트: `tools/scope_guard.py` - 정적 연계: `detecting-auth-session-weaknesses` - 시나리오: `references/payloads.md`