Web Bot Auth 검증 (Web Bot Auth verification)
이 스킬은 기존 서비스에 서명된 에이전트 트래픽 검증 기능을 추가합니다. 어려운 부분은 암호화 자체가 아니라, 서명의 의미를 약화시키는 작은 세부 사항들(서명되지 않은 컴포넌트, 재사용된 nonce, fetch를 유발하는 헤더, 클라이언트가 서명한 방식과 다르게 재구성된 URL)을 처리하는 것입니다. 여기에 포함된 참조 코드와 테스트는 이러한 세부 사항을 정확히 구현합니다. 여러분의 역할은 이 코드를 사용자의 스택에 통합하면서 보안을 약화시키지 않는 것입니다.
명세 상태: draft-meunier-web-bot-auth-architecture-05(IETF 인터넷 초안, 표준 아님)를 대상으로 하며, 많은 배포된 에이전트가 여전히 보내는 레거시 quoted-string Signature-Agent를 허용합니다. 사용자에게 이 초안은 변경될 수 있음을 알리십시오.
작업 흐름
-
요청 진입점을 찾습니다. 프레임워크와 요청이 들어오는 위치(미들웨어, 엣지 핸들러, 리버스 프록시 훅)를 식별합니다. 서비스가 프록시나 CDN 뒤에 있는지 여부를 확인합니다. 이는 URL 재구성 방식을 결정하기 때문입니다(
references/adapters.md참조). -
사용자와 정책 결정을 확정합니다.
references/policy-decisions.md를 읽고 대화에서 아직 결정되지 않은 사항(허용할 연산자, 요청 바인딩 및 논스 필요 여부, 논스 저장소, 각 결과에 대한 대응)을 질문합니다. 엄격한 설정을 조용히 선택하지 마십시오. 엄격한 기본값은 현재 배포된 대부분의 에이전트를 거부합니다. 느슨한 설정도 조용히 선택하지 마십시오. 어떤 보안 허점이 남는지 설명하십시오. -
검증기를 추가합니다.
- Python:
scripts/web_bot_auth.py를 변경 없이 프로젝트에 복사하고(라이선스 헤더 유지),cryptography를 의존성에 추가한 후Request를 빌드하는 작은 어댑터를 작성합니다. - 다른 언어:
scripts/web_bot_auth.py를 포팅합니다. 해당 언어의 검증된 Ed25519 라이브러리(직접 구현하지 말 것)와 유지 관리되는 RFC 8941 구조화된 필드 파서(존재하는 경우)를 사용합니다.assets/test-vectors.json의 모든 테스트 케이스를 통과해야 포팅이 완료된 것입니다.
- Python:
-
어댑터를 주의 깊게 작성합니다. 대부분의 통합이 실패하는 지점입니다.
Request는 전송된 그대로의 메서드, 클라이언트가 요청한 절대 URL, 모든 헤더 발생, 구문 분석 또는 압축 해제 전의 원시 본문 바이트를 전달해야 합니다. 프레임워크별 참고 사항은references/adapters.md를 참조하십시오. -
논스 저장소를 선택합니다. 단일 프로세스에서만 인메모리를 사용합니다. 둘 이상의 워커나 노드가 있는 경우 공유되고 강력하게 일관된 저장소가 필요합니다.
references/nonce-stores.md를 참조하십시오. -
결과를 조치에 매핑합니다. 사용자가 달리 결정하지 않은 경우 아래 표를 사용합니다.
-
엔드 투 엔드 통합을 테스트합니다. 실제 프레임워크(테스트 클라이언트)를 통해
sign_request를 사용하여 서명된 요청(유효한 요청 1개, 변조된 본문 1개, 재전송 1개, 만료된 요청 1개)을 생성하고 테스트합니다. 파일을 복사한 경우scripts/test_web_bot_auth.py도 실행합니다. -
로그 전용 롤아웃을 권장합니다. 적용하기 전에 일정 기간 동안 모든 요청에 대해
outcome,reason,operator,keyid,binds_request,replay_protected를 기록합니다.
결과
| 결과 | 의미 | 기본 조치 |
|---|---|---|
unsigned | web-bot-auth 서명 없음 | 기존 봇 처리 / 위험 점수 |
verified | 유효한 서명, 허용된 운영자 | 해당 에이전트로 인정; 여전히 사용자별 인증 및 속도 제한 적용 |
signed_untrusted | 유효한 서명, 알려졌지만 허용되지 않은 운영자 | 미서명으로 처리, 선택적으로 낮은 위험도 적용 |
unknown_operator | 형식은 올바르지만 키를 사용할 수 없음 | 미서명으로 처리; 선택적으로 백그라운드 디렉터리 가져오기 큐에 추가 |
invalid | 서명이 존재하지만 잘못됨 | 차단. 합법적인 클라이언트는 잘못된 서명을 보내지 않습니다. |
expired | 시간 창을 벗어남 | 차단 |
replay | 논스가 이미 사용됨 | 차단 |
Result.hostile은 마지막 세 가지 결과에 대해 true입니다. verified의 경우 두 플래그도 확인합니다. binds_request가 false이면 서명이 메서드, 경로, 쿼리 및 본문을 포함하지 않습니다. replay_protected가 false이면 논스가 없거나 저장소를 사용할 수 없는 것입니다. 합리적인 기본값은 안전한 메서드(GET, HEAD)에 대해서만 플래그 중 하나가 false인 verified 요청을 허용하는 것입니다.
위반하기 쉬운 규칙
이 규칙들은 각각 구체적인 공격이 뒷받침되기 때문에 존재합니다. 사용자의 제약 조건이 이 규칙 중 하나를 위반해야 하는 것처럼 보이면, 위험을 설명하고 사용자에게 결정을 맡기십시오.
- 허용 목록에 없는 운영자에 대해 키 디렉터리를 인라인으로 가져오지 마십시오.
Signature-Agent는 공격자가 제어할 수 있으므로, 이를 가져오면 SSRF가 발생하고 누구든지 요청 경로를 지연시킬 수 있습니다. 알려지지 않은 운영자는 백그라운드 작업에서safe_fetch_directory로 가져오거나 전혀 가져오지 마십시오. - 본문이 포함될 때마다 Content-Digest를 본문에 대해 확인하십시오. 헤더 서명은 아무도 수신된 바이트와 일치하는지 확인하지 않으면 의미가 없습니다.
- 서명이 검증된 후에만 논스를 기록하십시오. 그렇지 않으면 누구나 저장소를 채우거나 합법적인 에이전트의 논스를 미리 소진시킬 수 있습니다.
- 인스턴스 간에 공유되고 원자적인 논스 저장소를 사용하십시오. 프로세스별 캐시는 재전송이 다른 워커에 도달할 수 있게 합니다.
- 만료 시간만이 아닌 생성 시간으로 신선도를 제한하십시오. 에이전트는 긴 만료 시간으로 서명할 수 있습니다.
Policy.max_age는 만료 시간과 관계없이 재전송 창과 논스 캐시를 작게 유지합니다. - 클라이언트가 실제로 요청한 URL을 재구성하십시오. 프록시 뒤에 있는 경우, 신뢰하는 프록시에서만 전달된 스키마와 호스트를 사용하십시오. 잘못 재구성하면 유효한 서명이 검증에 실패하거나 변조된 호스트 헤더가 신뢰될 수 있습니다.
- 검증된 서명은 에이전트(운영자)를 식별할 뿐, 사용자를 식별하지 않습니다. 일반 인증 및 사용자별 권한 부여와 속도 제한을 그 뒤에 유지하십시오. 민감한 작업에 대해 서명을 사용자 동의 대신 사용하지 마십시오.
- 검증된 에이전트에는 인간 행동 검사를 적용하지 마십시오. 이들은 설계상 자동화된 존재입니다.
파일
scripts/web_bot_auth.py: 검증기, 키 리졸버, 논스 저장소 및sign_request. 단일 파일이며cryptography에만 의존합니다.scripts/test_web_bot_auth.py: 공격 케이스 테스트와 RFC 9421 부록 B.2.6 적합성 벡터.scripts/디렉터리에서python -m unittest -v test_web_bot_auth로 실행합니다.scripts/generate_vectors.py:assets/test-vectors.json을 재생성합니다.assets/test-vectors.json: 언어 중립적인 포팅용 벡터(테스트 키만 포함).references/policy-decisions.md: 사용자와 함께 결정해야 할 선택 사항과 절충점. 2단계에서 읽습니다.references/adapters.md: 일반적인 프레임워크와 프록시 뒤에서Request를 올바르게 구성하는 방법. 4단계에서 읽습니다.references/nonce-stores.md: 안전한 저장소와 크기 조정 방법. 5단계에서 읽습니다.