mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-13 20:14:16 +00:00
fix(admin): address review findings
- 0034's backfill set target_id to the acting admin for instance- and team-scoped quota policy changes, which are filed under the actor and have no user target. It now returns NULL for those, matching what quotas.py records going forward, with a test covering all three scopes. - The CSV export wrote every cell verbatim. user_agent is an attacker's raw header, recorded without authenticating on a denied login, and the export is opened in a spreadsheet by an admin -- a cell starting "=" would be evaluated there. Every cell now has a leading formula trigger neutralized. - The activity feed applied every response it received, so a slow reply for an old filter could overwrite the current one. Guarded by a request id, the same way settings/Analytics already does. - The activity detail expander and the top-user drill-down were row onClick handlers, unreachable without a mouse. Both are real buttons now, the expander carrying aria-expanded and a label naming its event. - FLOW_LABELS was applied to both breakdowns in the spend modal, so a model named "fallback" or "workflow" rendered as a flow description. Only the flow table maps keys now. - Changing the range in that modal left the previous range's totals and chart on screen while the new request was in flight.
This commit is contained in:
1 parent
64200a7f23
commit
2ea9d66789
7 files changed
+141
-25
No files matched your search
@@ -209,6 +209,24 @@ def _export_rows(filters: dict, limit: int) -> Iterator[dict]:
|
||||
)
|
||||
|
||||
|
||||
# Characters a spreadsheet reads as the start of a formula.
|
||||
_FORMULA_TRIGGERS = ("=", "+", "-", "@", "\t", "\r")
|
||||
|
||||
|
||||
def _csv_safe(value: object) -> object:
|
||||
"""Neutralize a leading formula trigger before the value becomes a CSV cell.
|
||||
|
||||
The feed carries attacker-controlled text: ``user_agent`` is the raw header
|
||||
of whoever made the request, and a denied login records one without ever
|
||||
authenticating. An export is opened in a spreadsheet by an admin, so a cell
|
||||
beginning ``=`` would be evaluated there. Prefixing an apostrophe keeps the
|
||||
value readable and inert.
|
||||
"""
|
||||
if isinstance(value, str) and value.startswith(_FORMULA_TRIGGERS):
|
||||
return f"'{value}"
|
||||
return value
|
||||
|
||||
|
||||
def _csv_rows(filters: dict, limit: int) -> Iterator[str]:
|
||||
buffer = io.StringIO()
|
||||
writer = csv.DictWriter(buffer, fieldnames=list(ACTIVITY_COLUMNS))
|
||||
@@ -220,7 +238,7 @@ def _csv_rows(filters: dict, limit: int) -> Iterator[str]:
|
||||
serialized["detail"] = json.dumps(
|
||||
serialized.get("detail") or {}, default=str
|
||||
)
|
||||
writer.writerow(serialized)
|
||||
writer.writerow({key: _csv_safe(value) for key, value in serialized.items()})
|
||||
yield _drain(buffer)
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user