mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-30 11:52:04 +00:00
fix(gateway): sanitize agent error messages, validate webhook gh args
Two of the three fixes from PR #6660 (the cli.py reopen_session change is moot — that raw _conn.execute reopen block no longer exists on main). - gateway/run.py: stop sending raw type(e).__name__ and str(e)[:300] to end users on chat platforms. Exception text from LLM providers can leak API URLs, file paths, and partial credentials. Return a generic message; keep curated status hints for known HTTP codes; full detail stays in logs. - gateway/platforms/webhook.py: validate pr_number (positive int) and repo (owner/name regex) before passing to the 'gh pr comment' subprocess. Payload-controlled values could otherwise inject gh flags (--help, a different --repo). List-form subprocess means this is arg injection, not shell injection, but validation is still correct. Co-authored-by: aaronagent <1115117931@qq.com>
This commit is contained in:
parent
ec148f5d31
commit
27ddd8fd80
2 changed files with 25 additions and 6 deletions
|
|
@ -938,13 +938,34 @@ class WebhookAdapter(BasePlatformAdapter):
|
|||
success=False, error="Missing repo or pr_number"
|
||||
)
|
||||
|
||||
# --- Input validation (prevent CLI argument injection) ---
|
||||
# pr_number must be a positive integer.
|
||||
try:
|
||||
pr_int = int(pr_number)
|
||||
if pr_int <= 0:
|
||||
raise ValueError("non-positive")
|
||||
except (ValueError, TypeError):
|
||||
logger.error(
|
||||
"[webhook] invalid pr_number: %r", pr_number
|
||||
)
|
||||
return SendResult(
|
||||
success=False, error="Invalid pr_number"
|
||||
)
|
||||
|
||||
# repo must match owner/name (alphanumeric, hyphens, underscores, dots).
|
||||
if not re.fullmatch(r"[A-Za-z0-9._-]+/[A-Za-z0-9._-]+", repo):
|
||||
logger.error("[webhook] invalid repo format: %r", repo)
|
||||
return SendResult(
|
||||
success=False, error="Invalid repo format"
|
||||
)
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
[
|
||||
"gh",
|
||||
"pr",
|
||||
"comment",
|
||||
str(pr_number),
|
||||
str(pr_int),
|
||||
"--repo",
|
||||
repo,
|
||||
"--body",
|
||||
|
|
|
|||
|
|
@ -10910,8 +10910,8 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew
|
|||
)
|
||||
except Exception:
|
||||
logger.debug("Failed to persist inbound user message after agent exception", exc_info=True)
|
||||
error_type = type(e).__name__
|
||||
error_detail = str(e)[:300] if str(e) else "no details available"
|
||||
# Log full details server-side only; never expose raw exception
|
||||
# types or messages to end users (info-leakage risk).
|
||||
status_hint = ""
|
||||
status_code = getattr(e, "status_code", None)
|
||||
_hist_len = len(history) if 'history' in locals() else 0
|
||||
|
|
@ -10955,9 +10955,7 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew
|
|||
elif status_code == 400:
|
||||
status_hint = " The request was rejected by the API."
|
||||
return (
|
||||
f"Sorry, I encountered an error ({error_type}).\n"
|
||||
f"{error_detail}\n"
|
||||
f"{status_hint}"
|
||||
f"Sorry, I encountered an unexpected error.{status_hint}\n"
|
||||
"Try again or use /reset to start a fresh session."
|
||||
)
|
||||
finally:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue