T09 · Insecure Skill Coding Practices
- Location
scripts/_spapi_fba_common.py:304- Finding
Amazon FBA Requests and Responses Are Persisted in Plaintext
- Content
View full analysis
Vulnerability Details
File Locations:
scripts/_spapi_fba_common.py:304-317scripts/_fba_runner.py:128-136
Vulnerability Type: Unprotected storage of sensitive operational and customer data
Risk Level: MediumVulnerable Code
The operation result includes the full gateway response, query string, and request body:
python out: dict[str, Any] = { "api": amazon_op, "developerProxy": proxy, "resolvedPath": path, "method": op["method"], "queryString": qs, } if rb is not None: out["requestBody"] = rb merge_json_body(out, proxy, "payload") return outThe complete result is then written to a plaintext JSON file:
python def emit_result(result, slug=SLUG, inline=False): serialized = json.dumps(result, ensure_ascii=False, indent=2) ts = time.time() date_str = time.strftime("%Y-%m-%d", time.localtime(ts)) sid = _lf_session_id(ts) root = _lf_root() session_dir = os.path.join(root, date_str, sid) os.makedirs(session_dir, exist_ok=True) _lf_ensure_meta(root, session_dir, date_str, sid, ts) data_dir = os.path.join(session_dir, "data") os.makedirs(data_dir, exist_ok=True) out = os.path.join(data_dir, f"{slug}-{int(ts * 1_000_000)}.json") try: with open(out, "w", encoding="utf-8") as f: f.write(serialized)Technical Analysis
Every operation builds an output object containing the full developer-proxy response. For write operations, the object also contains the submitted
requestBody; for all operations, it can contain the complete query string and parsed payload.emit_result()unconditionally serializes this object and writes it to a local JSON file. Theinlineoption only controls terminal output and does not disable file persistence.Amazon FBA and multi-channel fulfillment payloads may contain recipient names, addresses, telephone numbers, seller ide ...[truncated 2238 chars]
- Remediation
View remediation
Remediation Suggestions
-
Make persistence opt-in
- Return results to standard output by default.
- Require an explicit option such as
--save-full-responsebefore writing complete responses.
-
Redact sensitive data
- Remove customer names, addresses, phone numbers, authorization values, tokens, and other sensitive fields before serialization.
- Use an allowlist of fields that are safe to retain rather than attempting to enumerate every sensitive field.
-
Do not persist request bodies by default
- Remove
requestBodyfrom the result object used for logging. - If diagnostic retention is explicitly enabled, redact sensitive fields and warn the user before saving.
- Remove
-
Enforce restrictive permissions
- Create output directories with mode
0700. - Create response files with mode
0600. - Verify permissions after creation on supported platforms.
- Create output directories with mode
-
Implement retention controls
- Provide a configurable expiration period.
- Automatically remove expired response files.
- Offer a command that securely clears retained session data.
-
Minimize stored response content
- Persist only status codes, operation IDs, timestamps, and non-sensitive summaries unless the user explicitly requests full retention.
- Avoid storing duplicate copies of the raw proxy response and parsed payload.
-
Document the storage behavior
- Clearly disclose what is stored, where it is stored, how long it remains, and how users can disable or delete it.
-
