
Kleine Python-Bibliothek, die das Ausnutzen von Race Conditions in Web-Apps mit Requests erleichtert.
Requests-Racer ist eine kleine Python-Bibliothek, die es Ihnen ermöglicht, die Requests-Bibliothek zu verwenden, um mehrere Anfragen zu senden, die von ihren Zielservern ungefähr zur gleichen Zeit verarbeitet werden, selbst wenn die Anfragen unterschiedliche Ziele haben oder unterschiedlich große Nutzlasten aufweisen. Dies kann hilfreich sein, um Race-Condition-Schwachstellen in Webanwendungen zu erkennen und auszunutzen. (Weitere Informationen finden Sie unter motivation.md.)
Requests (und urllib3, das Requests intern verwendet) waren nie dafür gedacht, Ihnen so etwas zu ermöglichen. Requests-Racer ist daher gezwungen, auf einige ziemlich schreckliche Hacks zurückzugreifen, um eine feingranulare Kontrolle darüber zu erlangen, wie Anfragen gesendet werden.
Diese Hacks bestehen darin, den privaten Zustand einiger urllib3-Objekte zu manipulieren, sodass ein urllib3-Update, das in Bezug auf seine öffentliche API abwärtskompatibel ist, Requests-Racer dennoch beschädigen könnte. Daher empfehle ich, Requests-Racer in einem virtualenv zu verwenden und es vor Requests oder urllib3 zu installieren, damit eine bekanntermaßen kompatible Version dieser Bibliotheken als Abhängigkeit installiert wird.
Um Requests-Racer zu verwenden, benötigen Sie Python 3.5 oder höher. Erstellen und aktivieren Sie zunächst eine virtuelle Python-Umgebung:
python3 -m venv env
source env/bin/activate
Laden Sie dann eine Kopie der Bibliothek herunter und installieren Sie sie:
git clone https://github.com/nccgroup/requests-racer.git
cd requests-racer
python setup.py install
Requests-Racer funktioniert, indem es einen alternativen Transport-Adapter für Requests bereitstellt, der SynchronizedAdapter heißt. Dieser sammelt alle Anfragen, die Sie über ihn senden, und schließt sie erst ab, wenn die Methode finish_all() aufgerufen wird:
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)
Um Ihren Code zu vereinfachen, können Sie auch SynchronizedSession verwenden. Dabei handelt es sich um ein requests.Session-Objekt, das automatisch einen SynchronizedAdapter für HTTP[S] einbindet und die Methode finish_all() weiterreicht, sodass der obige Code wie folgt umgeschrieben werden kann:
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)
Hier sind einige Einschränkungen, die Sie beachten sollten, sowie ausgefallenere Dinge, die Sie tun können:
SynchronizedAdapter ist nicht threadsicher.SynchronizedAdapter gesendete Anfragen aktualisieren das Session-Objekt nicht (z. B. werden Cookies aus Set-Cookie-Headern nicht zum Cookie-Jar der Session hinzugefügt).999 und enthält einen Traceback in ihrem .text-Attribut.SynchronizedSession.from_regular_session erstellt eine SynchronizedSession aus einer requests.Session-Instanz. Dies ist hilfreich, wenn Sie einige einfache Anfragen stellen müssen, um sich z. B. bei einem Dienst anzumelden und ein Session-Cookie zu erhalten, das Sie für die synchronisierten Anfragen benötigen.SynchronizedAdapter und SynchronizedSession akzeptieren einen optionalen Parameter namens , der die maximale Anzahl von Threads angibt, die der Adapter verwendet. Wenn nicht angegeben, verwendet der Adapter einen Thread pro Anfrage.Hinweise zur Leistung finden Sie unter benchmark/.
Copyright (C) 2019 Aleksejs Popovs, NCC Group
Dieses Programm ist freie Software: Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren veröffentlichten Version, weiterverbreiten und/oder modifizieren.
Dieses Programm wird in der Hoffnung verbreitet, dass es nützlich sein wird, aber OHNE JEDE GEWÄHRLEISTUNG; ohne auch nur die implizite Gewährleistung der MARKTFÄHIGKEIT oder der EIGNUNG FÜR EINEN BESTIMMTEN ZWECK. Siehe die GNU General Public License für weitere Details.
Sie sollten eine Kopie der GNU General Public License zusammen mit diesem Programm erhalten haben. Wenn nicht, siehe https://www.gnu.org/licenses/.
num_threadsfinish_all() akzeptiert einen optionalen Parameter namens timeout, der die maximale Zeit (in Sekunden) angibt, die der Adapter auf das Beenden eines Threads wartet.