
Pequeña librería de Python que facilita la explotación de condiciones de carrera en aplicaciones web con Requests.
Requests-Racer es una pequeña librería de Python que le permite utilizar la librería Requests para enviar múltiples solicitudes que serán procesadas por sus servidores de destino aproximadamente al mismo tiempo, incluso si las solicitudes tienen destinos diferentes o payloads de tamaños distintos. Esto puede ser útil para detectar y explotar vulnerabilidades de condición de carrera en aplicaciones web. (Para más información, consulte motivation.md).
Requests (y urllib3, que Requests utiliza internamente) nunca fueron concebidos para permitirle hacer algo como esto. Por lo tanto, Requests-Racer se ve obligado a recurrir a algunos hacks bastante terribles para obtener un control preciso sobre cómo se envían las solicitudes.
Estos hacks incluyen manipular el estado privado de algunos objetos de urllib3, por lo que una actualización de urllib3 que sea retrocompatible con respecto a su API pública podría igualmente romper Requests-Racer. Por ello, recomiendo usar Requests-Racer en un virtualenv e instalarlo antes que Requests o urllib3, de modo que se instale una versión conocida y compatible de estas librerías como dependencia.
Para utilizar Requests-Racer, necesitará Python 3.5 o posterior. Primero, cree y active un entorno virtual de Python:
python3 -m venv env
source env/bin/activate
A continuación, descargue una copia de la librería e instálela:
git clone https://github.com/nccgroup/requests-racer.git
cd requests-racer
python setup.py install
Requests-Racer funciona proporcionando un Adaptador de transporte alternativo para Requests llamado SynchronizedAdapter. Recopilará todas las solicitudes que realice a través de él y las finalizará solo cuando se llame al método 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)
Para simplificar su código, también puede usar SynchronizedSession, que es simplemente un objeto requests.Session que automáticamente monta un SynchronizedAdapter para HTTP[S] y actúa como proxy del método finish_all(), por lo que el código anterior se puede reescribir de la siguiente manera:
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)
A continuación se indican algunas advertencias que debe tener en cuenta y algunas cosas más avanzadas que puede hacer:
SynchronizedAdapter no es thread-safe.SynchronizedAdapter no actualizarán el objeto de sesión (p. ej., las cookies de las cabeceras Set-Cookie no se añadirán al almacén de cookies de la sesión).999 y contendrá un traceback en su atributo .text.SynchronizedSession.from_regular_session construye un SynchronizedSession a partir de una instancia de requests.Session. Esto es útil si necesita hacer algunas solicitudes simples para, p. ej., iniciar sesión en un servicio y obtener una cookie de sesión que necesitará para las solicitudes sincronizadas.SynchronizedAdapter y SynchronizedSession aceptan un parámetro opcional llamado , que indica el número máximo de hilos que utilizará el adaptador. Si no se especifica, el adaptador usará un hilo por solicitud.Consulte benchmark/ para notas sobre el rendimiento.
Copyright (C) 2019 Aleksejs Popovs, NCC Group
Este programa es software libre: puede redistribuirlo y/o modificarlo bajo los términos de la Licencia Pública General de GNU publicada por la Free Software Foundation, ya sea la versión 3 de la Licencia, o (a su elección) cualquier versión posterior.
Este programa se distribuye con la esperanza de que sea útil, pero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de COMERCIABILIDAD o IDONEIDAD PARA UN FIN PARTICULAR. Consulte la Licencia Pública General de GNU para obtener más detalles.
Debería haber recibido una copia de la Licencia Pública General de GNU junto con este programa. Si no es así, consulte https://www.gnu.org/licenses/.
num_threadsfinish_all() acepta un parámetro opcional llamado timeout, que indica la cantidad máxima de tiempo (en segundos) que el adaptador esperará a que un hilo termine.