Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
enforcement-coverage — 자신의 형제 라우트보다 약한 권한 부여를 가진 API 라우트를 찾아냅니다. 소스에서 CVE-2026-45316을 복구했습니다. 부정적 결과를 포함합니다. | Kitploit
도구/GitHubGitHub/arian-gogani/enforcement-coverage
Static Code Analysis (SAST)Vulnerability AnalysisCode AnalysisPenetration TestingDevSecOpsAPI Security
GitHubarian-gogani/enforcement-coverage

enforcement-coverage

자신의 형제 라우트보다 약한 권한 부여를 가진 API 라우트를 찾아냅니다. 소스에서 CVE-2026-45316을 복구했습니다. 부정적 결과를 포함합니다.

저장소 보기
15시간 48분 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

시행 범위

형제 라우트보다 더 약한 권한 제어를 가진 API 라우트를 찾습니다.

보안 권고에 대한 사전 지식 없이 소스만으로 Open WebUI에서 CVE-2026-45316을 발견했습니다:

root@kitploit:~
[MISMATCH] POST /notes/{id}/pin  (notes.py:pin_note_by_id)
  3/3 comparable write operations on note require has_access(write);
  this route requires only has_access(read)

    POST   /notes/{id}/update          has_access(write)
    POST   /notes/{id}/access/update   has_access(write)
    DELETE /notes/{id}/delete          has_access(write)

5개의 프로덕션 코드베이스에 걸친 2,568개 라우트에서 4건의 발견을 산출했습니다. 그중 2건은 실제였습니다. 이 README는 두 숫자를 모두 설명합니다.

아이디어

권한 부여 버그의 큰 부류는 깨진 검사가 아닙니다. 형제 라우트가 모두 올바르게 처리한 라우트에서 누락되거나 약화된 검사입니다.

Portainer는 4개의 형제 템플릿 엔드포인트에는 권한 검사를 적용했지만 다섯 번째에는 적용하지 않았습니다. Signal K는 HTTP 로그인에는 속도 제한을 적용했지만 WebSocket 로그인에는 적용하지 않았습니다. Open WebUI의 note-pin 라우트는 다른 모든 노트 변경 작업이 쓰기 권한을 검사하는데, 읽기 권한만 검사하면서 노트를 변경했습니다.

항상 같은 형태입니다:

root@kitploit:~
✓ ✓ ✓ ✓ ✗

저장소에는 이미 규칙이 들어 있습니다. 하나의 라우트가 그 규칙을 어겼습니다. 따라서 코드에서 규칙을 재구성하고 예외를 보고합니다. 정책 파일도, 구성도, 어노테이션도 없습니다. 증거 집합은 바로 형제 라우트들입니다.

실행

root@kitploit:~
python3 enforcement_coverage.py /path/to/repo
python3 enforcement_coverage.py /path/to/repo --density
python3 enforcement_coverage.py /path/to/repo --json

Python 3.10+, 의존성 없음. FastAPI 전용.

판정은 MISSING, MISMATCH, PRESERVED, UNKNOWN입니다. UNKNOWN은 판단을 보류하며 절대 보고되지 않습니다.

동작 방식

추출. 시그니처 Depends(), 데코레이터 dependencies=[], 라우터 레벨 의존성, 함수 본문, 래퍼 함수, 권한 클래스 목록에서 제어를 해석합니다.

함수 본문 추출은 필수입니다. Open WebUI의 608개 핸들러 중 216개가 결정적인 검사를 함수 내부에 포함합니다:

root@kitploit:~
if user.role != 'admin' and not await AccessGrants.has_access(
    user_id=user.id, resource_type='note',
    resource_id=note.id, permission='write', db=db,
):
    raise HTTPException(status_code=403)

연산 클래스는 HTTP 동사가 아니라 핸들러가 리소스에 수행하는 작업에서 비롯됩니다. POST /notes/{id}/chat은 노트를 읽는 POST입니다.

어휘 분류. 하나의 제어 계열에 속한 두 값이 반드시 강도 척도를 구성하지는 않습니다:

root@kitploit:~
has_access             {read, write}                      LEVEL
ensure_flow_permission {create,delete,execute,read,write}  ACTION
has_permission         {features.notes, workspace.tools}   SCOPE

LEVEL 어휘만 강도 비교를 지원합니다. FlowAction.CREATE를 지배적인 WRITE와 비교하면 Langflow에서 6개의 오탐이 발생했는데, 이는 수정되었습니다.

방향 필터. 덜 제한적인 제어 쪽으로의 편차만 보고됩니다. 선례보다 더 엄격한 것은 취약점이 아닙니다.

발견 결과

2건의 정탐.

Open WebUI의 POST /notes/{id}/pin — CVE-2026-45316.

추가 발견 하나는 Netflix Dispatch의 권한 비대칭입니다: POST /{incident_id}/resources는 IncidentViewPermission을 사용하는 반면, 6개의 형제 쓰기 연산은 IncidentEditPermission을 사용합니다. IncidentViewPermission은 제한되지 않은 모든 인시던트에 대해 True를 반환하며, IncidentEditPermission은 admin, commander 또는 reporter 권한을 요구합니다. 핸들러는 추가 검사 없이 티켓 및 그룹 생성 작업을 큐에 넣습니다.

보고할 곳이 없기 때문에 보고되지 않았습니다: 저장소는 2025년 9월 3일 Netflix에 의해 보관되었고 읽기 전용이며, SECURITY.md가 없고, 보관된 저장소는 비공개 취약점 보고가 비활성화되어 있으며, Dispatch는 Netflix 버그 바운티 프로그램에서 명시적으로 범위 외(out of scope)로 나열되어 있습니다. 여기에 게시하는 것이 남은 유일한 공개 채널입니다. 심각도는 낮습니다 — 인증된 조직 구성원이 필요하며 제한되지 않은 인시던트에만 영향을 미칩니다 — 그리고 프로젝트는 더 이상 유지 관리되지 않습니다.

2건의 오탐. POST /tools/{id}/valves/user/update는 사용자 자신의 valve 설정을 쓰므로 도구에 대한 읽기 권한만 정당하게 필요합니다 — 변경 대상이 권한 부여 주체와 다른 엔티티이기 때문입니다. 또한 형제 가드가 필요하지 않은 Langflow 지식 베이스 라우트도 있습니다.

왜 대체로 작동하지 않는가

이것이 유용한 부분입니다.

밀도는 발견을 예측하지 못합니다

Danswer는 95.9%의 제어 적용률을 가지며 80.7%의 UNKNOWN으로 0건의 발견을 산출했습니다. 그 어휘는 require_permission('basic_access'), ('manage_connectors') — 권한 네임스페이스이지 강도 척도가 아닙니다. manage_connectors가 read_connectors보다 약하다고 말할 수 없습니다.

발견을 예측하는 것은 has_access(resource, read|write)와 같은 정렬된 강도 인자를 가진 리소스 범위 권한 호출입니다. 5개 중 1개 코드베이스만이 그것을 가졌습니다.

모든 코드베이스는 서로 다른 추출이 필요했습니다

5개 저장소에 걸친 5가지 관용구. 분석이 전혀 실행되기 전에 각각 추출기 작업이 필요했습니다.

UNKNOWN은 결코 72% 아래로 떨어지지 않았습니다

어떤 저장소에서도, 어떤 구성에서도 마찬가지입니다. 대부분의 라우트는 일관된 제어를 가진 3개 이상의 형제 계열에 속하지 않습니다.

실제 코드 실행으로 발견된 결함

이 중 어느 것도 사전에 예상되지 않았습니다.

  1. 권한 부여는 Depends()가 아닌 함수 본문에 존재
  2. 라우트는 여러 제어 계열을 동시에 포함
  3. HTTP 동사는 연산 클래스가 아님
  4. 권한 부여 관용구는 저장소마다 다름
  5. 액션 어휘는 강도 척도가 아님
  6. 선례보다 더 엄격한 것은 취약점이 아님
  7. 선례만으로 분류된 어휘는 단일 값 계열을 숨김
  8. 422를 발생시키는 검증 헬퍼는 권한 부여가 아님
  9. 래퍼 함수는 실제 제어를 숨김
  10. 권한 클래스 목록 관용구는 이름 분할이 필요
  11. 형제 계열을 완화하면 발견이 7.5배 증가하고 정밀도가 50%에서 13%로 하락
  12. 다른 충분한 제어를 가진 라우트는 제어가 누락된 것이 아님
  13. 의존성이 아닌 인라인으로 구현된 동등한 시행 — 미해결

결함 13이 흥미로운 사례입니다. Dispatch의 태그 추천 라우트는 형제들이 가진 CaseViewPermission이 없습니다. 그러나 그 권한은 제한되지 않은 모든 케이스에 대해 True를 반환하며, 서비스는 이미 visibility == restricted를 인라인으로 검사합니다. 두 경로는 동등합니다. 이를 감지하려면 구조가 아닌 의미론적 동등성 분석이 필요합니다.

솔직한 평가

이 메커니즘은 작동합니다. 취약한 커밋이 병합되기 전에 사용 가능한 정보만 사용하여, 감사 가능한 증거 집합과 함께 소스에서 공개된 CVE 1건과 미보고된 권한 부여 공백 1건을 찾아냈습니다.

수확량은 대략 라우트 1,000개당 발견 1건이며, 5개의 상당한 코드베이스 중 하나가 가졌던 아키텍처가 필요합니다.

리소스 범위 권한 어휘를 가진 코드베이스의 감사 도구로는 유용합니다. 이 증거에 비추어 볼 때, 범용 스캐너는 아닙니다.

선행 연구

암묵적 가정을 추론하여 접근 제어 취약점을 정적으로 탐지하는 것은 USENIX Security 2011로 거슬러 올라갑니다. ACMiner는 Android 미들웨어에서 권한 부여 검사를 마이닝했습니다. Semgrep은 누락된 권한 부여를 대상으로 하는 AI 기반 탐지 기능을 제공하며, 한 고객 평가에서 61%의 정밀도를 보고했습니다. OWASP는 Authorization Regression Testing cheat sheet를 게시하며, 권장 접근 방식은 Actor × Resource × Action 매트릭스를 수동으로 유지 관리하는 것입니다.

이것은 좁고 결정론적인 접근 방식입니다: 형제 라우트가 증명하는 것만 도출하고, 그 외에는 판단을 보류합니다.

MIT 라이선스.

도구 다운로드
저장소라우트 수제어율발견
LiteLLM80887.1%0
Danswer / Onyx65395.9%0
Open WebUI52997.2%2
Netflix Dispatch29136.1%1
Langflow28747.4%1
저장소관용구
Open WebUIAccessGrants.has_access(resource_type=, permission=)
Langflowensure_<resource>_permission(user, Action.X)
LiteLLMuser_api_key_dict.user_role에 대한 역할 비교
Netflix DispatchDepends(PermissionsDependency([CaseEditPermission]))
Danswerrequire_permission('basic_access')