
Requests를 사용하여 웹 애플리케이션의 레이스 컨디션을 쉽게 악용할 수 있게 해주는 소형 Python 라이브러리
Requests-Racer는 Requests 라이브러리를 사용하여, 서로 다른 대상을 가지거나 페이로드 크기가 다르더라도 대상 서버에서 거의 동시에 처리될 여러 요청을 제출할 수 있게 해주는 작은 Python 라이브러리입니다. 이는 웹 애플리케이션의 경쟁 조건(race condition) 취약점을 탐지하고 악용하는 데 유용할 수 있습니다. (자세한 내용은 motivation.md를 참조하십시오.)
Requests(그리고 Requests가 내부적으로 사용하는 urllib3)는 이와 같은 일을 허용하도록 설계된 적이 없습니다. 따라서 Requests-Racer는 요청이 제출되는 방식을 세밀하게 제어하기 위해 상당히 좋지 않은 꼼수에 의존할 수밖에 없습니다.
이러한 꼼수에는 일부 urllib3 객체의 비공개 상태를 건드리는 것이 포함되므로, 공개 API와 관련하여 이전 버전과 호환되는 urllib3 업데이트라도 Requests-Racer를 깨뜨릴 수 있습니다. 따라서 virtualenv에서 Requests-Racer를 사용하고 Requests 또는 urllib3 이전에 설치하여 알려진 호환 버전의 라이브러리가 의존성으로 설치되도록 권장합니다.
Requests-Racer를 사용하려면 Python 3.5 이상이 필요합니다. 먼저 Python 가상 환경을 생성하고 활성화하십시오:
python3 -m venv env
source env/bin/activate
그런 다음 라이브러리 사본을 다운로드하여 설치하십시오:
git clone https://github.com/nccgroup/requests-racer.git
cd requests-racer
python setup.py install
Requests-Racer는 Requests용 대체 Transport Adapter인 SynchronizedAdapter를 제공하는 방식으로 동작합니다. 이 어댑터를 통해 만든 모든 요청을 수집하고 finish_all() 메서드가 호출될 때만 요청을 완료합니다:
import requests
from requests_racer import SynchronizedAdapter
s = requests.Session()
sync = SynchronizedAdapter()
s.mount('http://', sync)
s.mount('https://', sync)
resp1 = s.get('http://example.com/a', params={'hello': 'world'})
resp2 = s.post('https://example.net/b', data={'one': 'two'})
# at this point, the requests have been started but not finished.
# resp1 and resp2 should *not* be used.
sync.finish_all()
print(resp1.status_code)
print(resp2.text)
코드를 더 간단하게 만들려면 SynchronizedSession을 사용할 수도 있습니다. SynchronizedSession은 HTTP[S]용 SynchronizedAdapter를 자동으로 마운트하고 finish_all() 메서드를 프록시하는 requests.Session 객체일 뿐이므로, 위 코드는 다음과 같이 다시 작성할 수 있습니다:
from requests_racer import SynchronizedSession
s = SynchronizedSession()
resp1 = s.get('http://example.com/a', params={'hello': 'world'})
resp2 = s.post('https://example.net/b', data={'one': 'two'})
# at this point, the requests have been started but not finished.
# resp1 and resp2 should *not* be used.
s.finish_all()
print(resp1.status_code)
print(resp2.text)
명심해야 할 몇 가지 주의사항과 사용할 수 있는 더 고급 기능은 다음과 같습니다:
SynchronizedAdapter는 스레드 안전하지 않습니다.SynchronizedAdapter를 통해 만든 요청은 세션 객체를 업데이트하지 않습니다 (예: Set-Cookie 헤더의 쿠키는 세션의 쿠키 저장소에 추가되지 않습니다).999를 가지며 .text 속성에 traceback이 포함됩니다.SynchronizedSession.from_regular_session은 requests.Session 인스턴스에서 SynchronizedSession을 구성합니다. 이는 예를 들어 서비스에 로그인하고 동기화된 요청에 필요한 세션 쿠키를 얻기 위해 몇 가지 간단한 요청을 수행해야 하는 경우 유용합니다.SynchronizedAdapter 및 SynchronizedSession은 어댑터가 사용할 최대 스레드 수를 지정하는 선택적 매개변수 num_threads를 허용합니다. 지정하지 않으면 어댑터는 요청당 하나의 스레드를 사용합니다.finish_all()은 어댑터가 스레드가 완료될 때까지 기다릴 최대 시간(초)을 지정하는 선택적 매개변수 을 허용합니다.성능에 대한 참고 사항은 benchmark/를 참조하십시오.
Copyright (C) 2019 Aleksejs Popovs, NCC Group
이 프로그램은 자유 소프트웨어입니다: 이 프로그램은 자유 소프트웨어 재단(Free Software Foundation)이 발표한 GNU 일반 공중 사용 허가서(GNU General Public License) 버전 3 또는 (선택에 따라) 이후 버전의 조건에 따라 재배포하거나 수정할 수 있습니다.
이 프로그램은 유용하게 쓰이리라는 희망으로 배포되지만, 어떠한 보증도 없이 배포됩니다. 상품성 또는 특정 목적에의 적합성에 대한 묵시적 보증조차 없습니다. 자세한 내용은 GNU 일반 공중 사용 허가서를 참조하십시오.
이 프로그램과 함께 GNU 일반 공중 사용 허가서의 사본을 받았을 것입니다. 받지 못했다면 https://www.gnu.org/licenses/를 참조하십시오.
timeout