fix: shlex.quote values in as_curl() so the command is valid and not injectable

header/body/url/proxy values were wrapped in raw single quotes, so a value containing a quote or shell metacharacter produced a broken or injectable command. every interpolated value is now shell-quoted.

Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
disqualifier 2026-06-28 17:18:28 -04:00
parent 7a2f24be9e
commit dc3fb70a1e
2 changed files with 15 additions and 9 deletions

View File

@ -11,13 +11,13 @@ and swap the HTTP client while inheriting everything else.
`requirements.txt`:
```
aioweb @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb.git@v0.1.1
aioweb @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb.git@v0.1.2
```
Direct:
```bash
pip install "aioweb @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb.git@v0.1.1"
pip install "aioweb @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb.git@v0.1.2"
```
Requires `aiohttp` and `yarl` (pulled transitively).

View File

@ -3,6 +3,7 @@ request preview for aioweb — format or export a request without sending it
"""
import json as _json
import shlex
class RequestPreview:
@ -25,15 +26,20 @@ class RequestPreview:
return "\n".join(f"{key}: {value}" for key, value in self.details.items())
def as_curl(self):
"""equivalent cURL command for the request"""
parts = [f"curl -X {self.details['method']}"]
"""equivalent cURL command for the request
every interpolated value is shell-quoted with shlex.quote, so headers,
body, url, or proxy containing quotes/spaces/metacharacters produce a
valid, non-injectable command rather than a broken or unsafe one.
"""
parts = [f"curl -X {shlex.quote(self.details['method'])}"]
for header, value in (self.details["headers"] or {}).items():
parts.append(f"-H '{header}: {value}'")
parts.append(f"-H {shlex.quote(f'{header}: {value}')}")
if self.details["data"]:
parts.append(f"--data '{self.details['data']}'")
parts.append(f"--data {shlex.quote(str(self.details['data']))}")
elif self.details["json"]:
parts.append(f"--data '{_json.dumps(self.details['json'])}'")
parts.append(f"'{self.details['url']}'")
parts.append(f"--data {shlex.quote(_json.dumps(self.details['json']))}")
parts.append(shlex.quote(str(self.details["url"])))
if self.details["proxy"]:
parts.append(f"--proxy '{self.details['proxy']}'")
parts.append(f"--proxy {shlex.quote(str(self.details['proxy']))}")
return " \\\n ".join(parts)