diff --git a/rules/S5144/python/how-to-fix-it/aiohttp.adoc b/rules/S5144/python/how-to-fix-it/aiohttp.adoc new file mode 100644 index 0000000000..dec6e3d7fb --- /dev/null +++ b/rules/S5144/python/how-to-fix-it/aiohttp.adoc @@ -0,0 +1,50 @@ +== How to fix it in aiohttp + +=== Code examples + +include::../../common/fix/code-rationale.adoc[] + +==== Noncompliant code example + +[source,python,diff-id=31,diff-type=noncompliant] +---- +from fastapi import FastAPI +import aiohttp + +app = FastAPI() +@app.get('/example') +async def example(url: str): + async with aiohttp.request('GET', url) as response: # Noncompliant + return {"response": await response.text()} +---- + +==== Compliant solution + +[source,python,diff-id=31,diff-type=compliant] +---- +from fastapi import FastAPI +from fastapi.responses import JSONResponse +import aiohttp +from urllib.parse import urlparse + +DOMAINS_ALLOWLIST = ['trusted1.example.com', 'trusted2.example.com']; +app = FastAPI() + +@app.get('/example') +async def example(url: str): + if urlparse(url).hostname not in DOMAINS_ALLOWLIST: + return JSONResponse({"error": f"URL {url} is not whitelisted."}, 400) + + async with aiohttp.request('GET', url.unicode_string()) as response: + return {"response": await response.text()} +---- + +=== How does this work? + +include::../../common/fix/pre-approved-list.adoc[] + +The compliant code example uses such an approach. + +=== Pitfalls + +include::../../common/pitfalls/starts-with.adoc[] diff --git a/rules/S5144/python/rule.adoc b/rules/S5144/python/rule.adoc index a359bcb07c..2c1bfb2dcb 100644 --- a/rules/S5144/python/rule.adoc +++ b/rules/S5144/python/rule.adoc @@ -10,6 +10,8 @@ include::how-to-fix-it/python.adoc[] include::how-to-fix-it/requests.adoc[] +include::how-to-fix-it/aiohttp.adoc[] + include::how-to-fix-it/httpx.adoc[] == Resources