REST API: `/scan/<taskid>/data` returns Python `repr()` strings instead of structured JSON since 1.10
bug report
### Summary
Since 1.10, the REST API endpoint `/scan/<taskid>/data` returns a JSON-quoted Python `repr()` string for `value` fields where it previously returned a structured JSON object. This breaks any client that parses the documented response shape.
### Reproduction
```bash
git clone --depth 1 --branch 1.10.4 https://github.com/sqlmapproject/sqlmap.git
cd sqlmap
python3 -c "
import sys; sys.path.insert(0, '.')
from lib.core.convert import stdoutEncode
target = {'url': 'http://example.com/foo', 'query': None, 'data': 'id=1'}
encoded = stdoutEncode(target)
print('input :', repr(target))
print('output :', repr(encoded))
print('type :', type(encoded).__name__)
"
```
### Output
**1.10.4 (current — broken):**
```
input : {'url': 'http://example.com/foo', 'query': None, 'data': 'id=1'}
output : "{'url': 'http://example.com/foo', 'query': None, 'data': 'id=1'}"
type : str
```
**1.9.4 (previous — correct):**
```
input : {'url': 'http://example.com/foo', 'query': None, 'data': 'id=1'}
output : {'url': 'http://example.com/foo', 'query': None, 'data': 'id=1'}
type : dict
```
### Why this matters
`stdoutEncode` is the encoder for the API write path: in `lib/core/dump.py` `Dumper.string()` → `_write()` → `lib/core/common.py` `dataToStdout()` → `sys.stdout.write(stdoutEncode(clearColors(data)), ...)` — where `sys.stdout.write` is overridden by the API's `write()` in `lib/utils/api.py`, which then does `jsonize(value)`.
Concrete impact, called from `lib/controller/controller.py:181`:
```python
conf.dumper.string("", {"url": conf.url, "query": ..., "data": ...},
content_type=CONTENT_TYPE.TARGET)
```
- **Before:** `stdoutEncode` returned the dict unchanged → `jsonize(dict)` produced a JSON object → REST clients got `"value": {"url": "...", "query": null, "data": "..."}`.
- **After:** `stdoutEncode` returns `str(dict)` (Python repr) → `jsonize(string)` produces a JSON string → REST clients get `"value": "{'url': '...', 'query': None, 'data': '...'}"` — unparseable, since `None` and single-quotes aren't JSON.
For `CONTENT_TYPE.TECHNIQUES` (type 1) the breakage is worse: the value contains nested dicts with integer keys (`{1: {...}, 2: {...}}`), so the resulting Python repr is not even convertible to JSON without a Python-literal parser.
### Root cause
Commit [`09fadc43`](https://github.com/sqlmapproject/sqlmap/commit/09fadc43) ("Minor improvement of stdoutEncode", 2025-12-31) replaced the `else: retVal = value` branch with `elif not isinstance(value, str): value = str(value)`, eagerly stringifying any non-string input.
### Suggested fix
In `stdoutEncode`, skip the `str(value)` coercion when `conf.api` is set (the API path expects to forward structured values to `jsonize`), or move that coercion out of `stdoutEncode` and only into the non-API stdout branch in `dataToStdout`.
**Screenshots**
If applicable, add screenshots to help explain your problem.
关闭于 2026-05-02 0 条评论