T05 · Unauthorized Access and Privilege Escalation
Warning
- Location
- scripts/audit_renewal_orders.py:304
- Finding
- RDS Renewal Audit Collects and Exposes Account-Wide Order History<![CDATA[ ## Vulnerability Details **File Location**: `scripts/audit_renewal_orders.py:304-437` **Vulnerability Type**: Excessive data access and insufficient product-scope filtering **Risk Level**: Medium ### Vulnerable Code ```python def fetch_orders(months: int, profile: str | None) -> tuple[list[dict], str, str]: """Full order history of the lookback window (no OrderType filter). The explicit CreateTimeStart/End window is mandatory: QueryOrders defaults to a ~1 hour window and would silently return nothing. Real argv assembled by the shared CLI layer (built-in API metadata mode): the product token immediately followed by the action token, then --endpoint ... --CreateTimeStart ... flags. Precheck R16 source anchor for the error-recovery-orders mock cmd (no CLI binary prefix here on purpose, per the SA-2.11 wording discipline): bssopenapi QueryOrders """ start_iso, end_iso = build_order_time_window(months) orders: list[dict] = [] page = 1 while page <= MAX_PAGES: body = _cli.call("bssopenapi", "QueryOrders", { "CreateTimeStart": start_iso, "CreateTimeEnd": end_iso, "PageSize": ORDER_PAGE_SIZE, "PageNum": page, }, profile=profile) data = body.get("Data") or {} rows = _unwrap(data.get("OrderList"), ("Order",)) orders.extend(r for r in rows if isinstance(r, dict)) total = int(data.get("TotalCount") or 0) if not rows or len(orders) >= total: break page += 1 if page > MAX_PAGES: print(f"[WARN] QueryOrders stopped at the {MAX_PAGES}-page " f"guardrail; results may be incomplete", file=sys.stderr) return orders, start_iso, end_iso ``` The unfiltered results are subsequently analyzed: ```python def analyze_orders(orders: list[dict]) -> dict: """Renewal series, price spikes and refund/cancel anomalies.""" renew_by_commodity: dict[str, list[dic ...[truncated 3912 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Apply a supported server-side product filter to `QueryOrders` when available. 2. Independently enforce a client-side allowlist before retaining, analyzing, or emitting orders. 3. Accept only orders positively associated with RDS or another explicitly requested database product. 4. Discard ambiguous or unrelated orders rather than grouping them under an unknown commodity. 5. Filter data before constructing `renewal_series`, refund anomalies, JSON output, or human-readable reports. 6. Minimize output fields. Do not emit order IDs or payment metadata unless they are necessary for the requested diagnosis. 7. Document the exact order-data scope and obtain explicit user confirmation if an account-wide order audit is genuinely required. 8. Add tests containing mixed RDS and non-RDS orders and verify that non-database orders never appear in analysis or output. ]]>
