[MAJOR] Doc-map configuration is read from the PR workspace and used to fetch arbitrary docs from the repository (default branch) via the VCS API, which are then sent to external LLMs. An untrusted PR author can modify the doc-map file in their PR to map any changed path to sensitive repository documents, exfiltrating content outside the organization and potentially into PR comments via the model's response. Mitigations: fetch the doc-map from a trusted reference (e.g., default/protected branch) rather than the PR branch, or disable doc-map on untrusted PRs; additionally allowlist permissible doc path prefixes (e.g., only under docs/) and/or require maintainer opt-in before using doc-map on a PR.
[MINOR] Path validation defense-in-depth: validateDocPath rejects absolute paths and literal '..' segments but does not normalize or reject percent-encoded traversal (e.g., %2e%2e), backslashes on Windows, or control characters. While doc-map is typically trusted, adding stricter validation would harden against edge cases.
[MINOR] Potential resource exhaustion: loadDocEntries uses GetAllFilesInPath to retrieve all files and their full contents for a directory, with no cap on number of files or total bytes fetched from the VCS before applying the post-fetch MaxBytes limit. A large directory of .md files could cause high memory/network usage before truncation.
[MINOR] Path hardening: doc paths from the local YAML are passed directly to GetAllFilesInPath/GetFileContent. Although the VCS API should constrain paths to the repo, adding local validation (e.g., reject absolute paths, clean and deny any '..' segments) would provide defense-in-depth against potential backend path handling quirks.
[MINOR] Potential denial-of-service via unbounded directory fetch: LoadMatchingDocs calls GetAllFilesInPath which returns full contents of all files under a path before applying the MaxBytes cap. A malicious or misconfigured doc-map could point to a very large directory, causing excessive memory/network usage prior to truncation.
[MINOR] Prompt-injection hardening: Design docs (which are ultimately repository-controlled data) are injected into the system prompt without explicit instruction separation. While content is fetched from the default branch (reducing attacker control via PR), best practice is to clearly treat docs as data and direct the model not to follow any instructions contained within them to mitigate prompt injection.
[MINOR] Integration test logs the authenticated GitHub username. While not a secret, in some setups this could expose account identifiers in CI logs for private environments.
[MINOR] Integration test logs PR title and commit SHA, which could leak private repository metadata to CI logs if those logs are accessible. Consider reducing or gating such logs.
[MINOR] githubAPIURL derives the API host directly from the provided server URL. With the heuristic that detects GitHub when the URL contains "github.com", a misconfigured or malicious host like "https://github.com.evil.com" would be treated as GHES and receive the Authorization bearer token. While this is an operator configuration input (not user-controlled), consider hardening by requiring explicit VCS_TYPE and/or validating the host against an allowlist to reduce the chance of credential leakage due to misconfiguration.
[MINOR] Potential log injection: extractSentinelName(body) returns attacker-controlled content from review bodies, which is logged as the "sibling_role" value via slog.Warn without escaping. With text logging, embedded newlines could lead to log injection/format confusion. Consider normalizing or escaping control characters (e.g., replace \n/\r) before logging.
[MAJOR] PostReview, DeleteReview, and RequestReviewer construct and execute HTTP requests directly (c.httpClient.Do) without the HTTPS-only guard used in doRequest. If baseURL is accidentally configured with an http:// scheme (e.g., GHES on HTTP), these methods will send the Authorization header over plaintext, exposing tokens. Enforce scheme checks consistently or reuse a common request helper for non-GET methods.