From a3fd54b8a43d7b139831b55f3c5e24440a09e4e7 Mon Sep 17 00:00:00 2001 From: Egon Okerman Date: Sun, 3 Dec 2023 12:32:40 +0100 Subject: [PATCH] Modify rule S5144: Add HTTPX support (APPSEC-1247) (#3410) * Add HTTPX * Enhance compliant code sample * Keep samples consistent * Simplify compliant example somewhat --- .../header_names/allowed_framework_names.adoc | 1 + rules/S5144/python/how-to-fix-it/httpx.adoc | 52 +++++++++++++++++++ rules/S5144/python/rule.adoc | 1 + 3 files changed, 54 insertions(+) create mode 100644 rules/S5144/python/how-to-fix-it/httpx.adoc diff --git a/docs/header_names/allowed_framework_names.adoc b/docs/header_names/allowed_framework_names.adoc index bc6efa6d52c..ea51545e07b 100644 --- a/docs/header_names/allowed_framework_names.adoc +++ b/docs/header_names/allowed_framework_names.adoc @@ -88,6 +88,7 @@ * Python Standard Library * PyYAML * Requests +* HTTPX * SQLAlchemy * Amazon DynamoDB * python-ldap diff --git a/rules/S5144/python/how-to-fix-it/httpx.adoc b/rules/S5144/python/how-to-fix-it/httpx.adoc new file mode 100644 index 00000000000..504013899d8 --- /dev/null +++ b/rules/S5144/python/how-to-fix-it/httpx.adoc @@ -0,0 +1,52 @@ +== How to fix it in HTTPX + +=== Code examples + +include::../../common/fix/code-rationale.adoc[] + +==== Noncompliant code example + +[source,python,diff-id=21,diff-type=noncompliant] +---- +from fastapi import FastAPI +import httpx + +app = FastAPI() + +@app.get('/example') +def example(url: str): + r = httpx.get(url) # Noncompliant + return {"response": r.text} +---- + +==== Compliant solution + +[source,python,diff-id=21,diff-type=compliant] +---- +from fastapi import FastAPI +from fastapi.responses import JSONResponse +import httpx +from urllib.parse import urlparse + +DOMAINS_ALLOWLIST = ['trusted1.example.com', 'trusted2.example.com'] +app = FastAPI() + +@app.get('/example') +def example(url: str): + if not urlparse(url).hostname in DOMAINS_ALLOWLIST: + return JSONResponse({"error": f"URL {url} is not whitelisted."}, 400) + + r = httpx.get(url) + return {"response": r.text} +---- + +=== How does this work? + +include::../../common/fix/pre-approved-list.adoc[] + +The compliant code example uses such an approach. +HTTPX implicitly validates the scheme as it only allows `http` and `https` by default. + +=== Pitfalls + +include::../../common/pitfalls/starts-with.adoc[] diff --git a/rules/S5144/python/rule.adoc b/rules/S5144/python/rule.adoc index e4e0df58024..a359bcb07c4 100644 --- a/rules/S5144/python/rule.adoc +++ b/rules/S5144/python/rule.adoc @@ -10,6 +10,7 @@ include::how-to-fix-it/python.adoc[] include::how-to-fix-it/requests.adoc[] +include::how-to-fix-it/httpx.adoc[] == Resources