From 7f31cf4122850839df035f5dd15b1ccfb7a0d317 Mon Sep 17 00:00:00 2001 From: naorpeled Date: Tue, 16 Jun 2026 21:50:09 +0300 Subject: [PATCH] fix(security): temporarily disable /help_docs command (#2445) /help_docs lets an untrusted PR commenter override the git clone target and, due to weak clone-URL host validation, exfiltrate the git provider token to an attacker-controlled host. As an immediate mitigation, unregister the command so it can no longer be invoked, ahead of the full validation fix. Re-enable by restoring the `help_docs` entry and its import once the hardening PR is merged. --- pr_agent/agent/pr_agent.py | 5 +++-- tests/unittest/test_help_docs_disabled.py | 25 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 tests/unittest/test_help_docs_disabled.py diff --git a/pr_agent/agent/pr_agent.py b/pr_agent/agent/pr_agent.py index 1e995ffb6f..4c2d2ef1c2 100644 --- a/pr_agent/agent/pr_agent.py +++ b/pr_agent/agent/pr_agent.py @@ -13,7 +13,6 @@ from pr_agent.tools.pr_config import PRConfig from pr_agent.tools.pr_description import PRDescription from pr_agent.tools.pr_generate_labels import PRGenerateLabels -from pr_agent.tools.pr_help_docs import PRHelpDocs from pr_agent.tools.pr_help_message import PRHelpMessage from pr_agent.tools.pr_line_questions import PR_LineQuestions from pr_agent.tools.pr_questions import PRQuestions @@ -40,7 +39,9 @@ "similar_issue": PRSimilarIssue, "add_docs": PRAddDocs, "generate_labels": PRGenerateLabels, - "help_docs": PRHelpDocs, + # SECURITY: "/help_docs" is temporarily disabled while the clone-target validation + # fix is reviewed (see issue #2445). Re-enable by restoring `"help_docs": PRHelpDocs` + # and its import once the hardening PR is merged. } commands = list(command2class.keys()) diff --git a/tests/unittest/test_help_docs_disabled.py b/tests/unittest/test_help_docs_disabled.py new file mode 100644 index 0000000000..ade22377dd --- /dev/null +++ b/tests/unittest/test_help_docs_disabled.py @@ -0,0 +1,25 @@ +import pytest + +import pr_agent.agent.pr_agent as pr_agent_module +from pr_agent.agent.pr_agent import PRAgent, command2class + + +def test_help_docs_is_not_registered(): + """Security stopgap for issue #2445: the /help_docs command must be disabled + (unregistered) until the clone-target validation fix is merged.""" + assert "help_docs" not in command2class + assert "help_docs" not in pr_agent_module.commands + + +@pytest.mark.asyncio +async def test_help_docs_command_is_not_routed(monkeypatch): + """An incoming /help_docs command resolves to an unknown command and is rejected.""" + monkeypatch.setattr(pr_agent_module, "apply_repo_settings", lambda pr_url: None) + monkeypatch.setattr(pr_agent_module.CliArgs, "validate_user_args", lambda args: (True, "")) + monkeypatch.setattr(pr_agent_module, "update_settings_from_args", lambda args: args) + + handled = await PRAgent()._handle_request( + "https://github.com/owner/repo/pull/1", + "/help_docs \"what docs exist\" --pr_help_docs.repo_url=https://github.com/x/y", + ) + assert handled is False