CVE-2026-86861 (GCVE-0-2026-86861)
Vulnerability from cvelistv5
Published
2026-09-17 15:30
Modified
2026-09-17 19:18
CWE
  • CWE-367 - Time-of-check Time-of-use (TOCTOU) Race Condition
  • CWE-59 - Improper Link Resolution Before File Access ('Link Following')
Summary
pgAdmin 4's File Manager save_file endpoint, which backs saving from the Query Tool and ERD, validated the requested path with Filemanager.check_access_permission() and then opened the file for writing with a plain open() call. CVE-2026-7819 had previously hardened the separate file upload path by opening its target with O_NOFOLLOW, so that the kernel refuses to follow a symbolic link at the final path component, but save_file was left on an unprotected open(). A symbolic link already present when the check ran was rejected by the check itself; the remaining exposure was a link substituted at the final path component in the interval between the check and the write, at which point the write followed the link and landed outside the user's storage directory, creating or overwriting an arbitrary file as the operating-system account running pgAdmin. Exploitation requires the ability to create or replace a symbolic link inside the requesting user's storage directory. pgAdmin exposes no interface that creates symbolic links, so this requires filesystem access to the pgAdmin host or to a shared or network-mounted storage backend, together with winning the timing window. The reporter did not achieve a write against a released version, having attempted approximately 63,000 racing requests without success; the reported defect is the uncovered write path rather than a demonstrated sandbox escape. The fix routes save_file's write through the same O_NOFOLLOW-protected helper already used by the upload path, so both File Manager write sinks carry identical kernel-enforced protection, and reports a symbolic-link refusal explicitly instead of surfacing the underlying system error text. Note that files created by save_file are now given mode 0600, inheriting the behaviour introduced for uploads. The protection covers the final path component; substitution of an intermediate directory component is not addressed by this change. This issue affects pgAdmin 4: from the introduction of the containment check in the File Manager save path before 9.18.
References
Impacted products
Vendor Product Version
pgadmin.org pgAdmin 4 Version: 0   < 9.18
Create a notification for this product.
Show details on NVD website


{
  "containers": {
    "adp": [
      {
        "metrics": [
          {
            "other": {
              "content": {
                "id": "CVE-2026-86861",
                "options": [
                  {
                    "Exploitation": "none"
                  },
                  {
                    "Automatable": "no"
                  },
                  {
                    "Technical Impact": "partial"
                  }
                ],
                "role": "CISA Coordinator",
                "timestamp": "2026-09-17T19:18:06.282518Z",
                "version": "2.0.3"
              },
              "type": "ssvc"
            }
          }
        ],
        "providerMetadata": {
          "dateUpdated": "2026-09-17T19:18:18.115Z",
          "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
          "shortName": "CISA-ADP"
        },
        "title": "CISA ADP Vulnrichment"
      }
    ],
    "cna": {
      "affected": [
        {
          "defaultStatus": "unaffected",
          "modules": [
            "File Manager"
          ],
          "product": "pgAdmin 4",
          "programFiles": [
            "https://github.com/pgadmin-org/pgadmin4/blob/master/web/pgadmin/misc/file_manager/__init__.py"
          ],
          "repo": "https://github.com/pgadmin-org/pgadmin4",
          "vendor": "pgadmin.org",
          "versions": [
            {
              "lessThan": "9.18",
              "status": "affected",
              "version": "0",
              "versionType": "custom"
            }
          ]
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "finder",
          "value": "sec-rex \u003csecrex837@gmail.com\u003e"
        },
        {
          "lang": "en",
          "type": "remediation developer",
          "value": "Dave Page \u003cdpage@pgadmin.org\u003e"
        },
        {
          "lang": "en",
          "type": "remediation reviewer",
          "value": "Ashesh Vashi \u003cashesh.vashi@enterprisedb.com\u003e"
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "pgAdmin 4\u0027s File Manager save_file endpoint, which backs saving from the Query Tool and ERD, validated the requested path with Filemanager.check_access_permission() and then opened the file for writing with a plain open() call. CVE-2026-7819 had previously hardened the separate file upload path by opening its target with O_NOFOLLOW, so that the kernel refuses to follow a symbolic link at the final path component, but save_file was left on an unprotected open(). A symbolic link already present when the check ran was rejected by the check itself; the remaining exposure was a link substituted at the final path component in the interval between the check and the write, at which point the write followed the link and landed outside the user\u0027s storage directory, creating or overwriting an arbitrary file as the operating-system account running pgAdmin.\n\nExploitation requires the ability to create or replace a symbolic link inside the requesting user\u0027s storage directory. pgAdmin exposes no interface that creates symbolic links, so this requires filesystem access to the pgAdmin host or to a shared or network-mounted storage backend, together with winning the timing window. The reporter did not achieve a write against a released version, having attempted approximately 63,000 racing requests without success; the reported defect is the uncovered write path rather than a demonstrated sandbox escape.\n\nThe fix routes save_file\u0027s write through the same O_NOFOLLOW-protected helper already used by the upload path, so both File Manager write sinks carry identical kernel-enforced protection, and reports a symbolic-link refusal explicitly instead of surfacing the underlying system error text. Note that files created by save_file are now given mode 0600, inheriting the behaviour introduced for uploads. The protection covers the final path component; substitution of an intermediate directory component is not addressed by this change.\n\nThis issue affects pgAdmin 4: from the introduction of the containment check in the File Manager save path before 9.18."
        }
      ],
      "metrics": [
        {
          "cvssV3_1": {
            "attackComplexity": "HIGH",
            "attackVector": "NETWORK",
            "availabilityImpact": "LOW",
            "baseScore": 5.9,
            "baseSeverity": "MEDIUM",
            "confidentialityImpact": "NONE",
            "integrityImpact": "HIGH",
            "privilegesRequired": "LOW",
            "scope": "UNCHANGED",
            "userInteraction": "NONE",
            "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:L",
            "version": "3.1"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "Threat model: an authenticated pgAdmin user who can also create or replace a symbolic link inside their own File Manager storage directory, which requires filesystem access to the pgAdmin host or to a shared or network-mounted storage backend, since pgAdmin exposes no primitive that creates symbolic links. Attack Complexity is High: the attacker must both obtain that separate primitive and win a narrow race between the containment check and the write, and the reporter did not succeed in approximately 63,000 attempts against a released version. Integrity is High because a successful write creates or overwrites an arbitrary file as the account running pgAdmin. Confidentiality is None, as the flaw permits writing but not reading. Availability is Low, reflecting that a chosen file may be clobbered without a general loss of service. Scope is Unchanged, consistent with the equivalent argument-injection write path, because the write occurs with the authority pgAdmin already holds."
            }
          ]
        },
        {
          "cvssV4_0": {
            "baseScore": 6,
            "baseSeverity": "MEDIUM",
            "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:N/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N",
            "version": "4.0"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "Same reasoning as the CVSS 3.1 entry. AT:P records that exploitation depends on a race condition the attacker does not control and on a symbolic-link primitive obtained outside pgAdmin. VI:H for arbitrary file creation and overwrite as the pgAdmin account, VC:N because nothing is read, VA:L for the loss of a clobbered file. SC:N/SI:N/SA:N because no distinct subsequent system is compromised by the flaw itself."
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-367",
              "description": "CWE-367 Time-of-check Time-of-use (TOCTOU) Race Condition",
              "lang": "en",
              "type": "CWE"
            },
            {
              "cweId": "CWE-59",
              "description": "CWE-59 Improper Link Resolution Before File Access (\u0027Link Following\u0027)",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-09-17T15:30:51.232Z",
        "orgId": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
        "shortName": "PostgreSQL"
      },
      "references": [
        {
          "tags": [
            "issue-tracking"
          ],
          "url": "https://github.com/pgadmin-org/pgadmin4/issues/10385"
        }
      ],
      "source": {
        "discovery": "EXTERNAL"
      },
      "title": "pgAdmin 4: File Manager save_file writes through a symbolic link planted after the containment check"
    }
  },
  "cveMetadata": {
    "assignerOrgId": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
    "assignerShortName": "PostgreSQL",
    "cveId": "CVE-2026-86861",
    "datePublished": "2026-09-17T15:30:51.232Z",
    "dateReserved": "2026-09-08T15:47:04.229Z",
    "dateUpdated": "2026-09-17T19:18:18.115Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2",
  "vulnerability-lookup:meta": {
    "vulnrichment": {
      "containers": "{\"adp\": [{\"title\": \"CISA ADP Vulnrichment\", \"metrics\": [{\"other\": {\"type\": \"ssvc\", \"content\": {\"id\": \"CVE-2026-86861\", \"role\": \"CISA Coordinator\", \"options\": [{\"Exploitation\": \"none\"}, {\"Automatable\": \"no\"}, {\"Technical Impact\": \"partial\"}], \"version\": \"2.0.3\", \"timestamp\": \"2026-09-17T19:18:06.282518Z\"}}}], \"providerMetadata\": {\"orgId\": \"134c704f-9b21-4f2e-91b3-4a467353bcc0\", \"shortName\": \"CISA-ADP\", \"dateUpdated\": \"2026-09-17T19:18:12.760Z\"}}], \"cna\": {\"title\": \"pgAdmin 4: File Manager save_file writes through a symbolic link planted after the containment check\", \"source\": {\"discovery\": \"EXTERNAL\"}, \"credits\": [{\"lang\": \"en\", \"type\": \"finder\", \"value\": \"sec-rex \u003csecrex837@gmail.com\u003e\"}, {\"lang\": \"en\", \"type\": \"remediation developer\", \"value\": \"Dave Page \u003cdpage@pgadmin.org\u003e\"}, {\"lang\": \"en\", \"type\": \"remediation reviewer\", \"value\": \"Ashesh Vashi \u003cashesh.vashi@enterprisedb.com\u003e\"}], \"metrics\": [{\"format\": \"CVSS\", \"cvssV3_1\": {\"scope\": \"UNCHANGED\", \"version\": \"3.1\", \"baseScore\": 5.9, \"attackVector\": \"NETWORK\", \"baseSeverity\": \"MEDIUM\", \"vectorString\": \"CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:L\", \"integrityImpact\": \"HIGH\", \"userInteraction\": \"NONE\", \"attackComplexity\": \"HIGH\", \"availabilityImpact\": \"LOW\", \"privilegesRequired\": \"LOW\", \"confidentialityImpact\": \"NONE\"}, \"scenarios\": [{\"lang\": \"en\", \"value\": \"Threat model: an authenticated pgAdmin user who can also create or replace a symbolic link inside their own File Manager storage directory, which requires filesystem access to the pgAdmin host or to a shared or network-mounted storage backend, since pgAdmin exposes no primitive that creates symbolic links. Attack Complexity is High: the attacker must both obtain that separate primitive and win a narrow race between the containment check and the write, and the reporter did not succeed in approximately 63,000 attempts against a released version. Integrity is High because a successful write creates or overwrites an arbitrary file as the account running pgAdmin. Confidentiality is None, as the flaw permits writing but not reading. Availability is Low, reflecting that a chosen file may be clobbered without a general loss of service. Scope is Unchanged, consistent with the equivalent argument-injection write path, because the write occurs with the authority pgAdmin already holds.\"}]}, {\"format\": \"CVSS\", \"cvssV4_0\": {\"version\": \"4.0\", \"baseScore\": 6, \"baseSeverity\": \"MEDIUM\", \"vectorString\": \"CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:N/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N\"}, \"scenarios\": [{\"lang\": \"en\", \"value\": \"Same reasoning as the CVSS 3.1 entry. AT:P records that exploitation depends on a race condition the attacker does not control and on a symbolic-link primitive obtained outside pgAdmin. VI:H for arbitrary file creation and overwrite as the pgAdmin account, VC:N because nothing is read, VA:L for the loss of a clobbered file. SC:N/SI:N/SA:N because no distinct subsequent system is compromised by the flaw itself.\"}]}], \"affected\": [{\"repo\": \"https://github.com/pgadmin-org/pgadmin4\", \"vendor\": \"pgadmin.org\", \"modules\": [\"File Manager\"], \"product\": \"pgAdmin 4\", \"versions\": [{\"status\": \"affected\", \"version\": \"0\", \"lessThan\": \"9.18\", \"versionType\": \"custom\"}], \"programFiles\": [\"https://github.com/pgadmin-org/pgadmin4/blob/master/web/pgadmin/misc/file_manager/__init__.py\"], \"defaultStatus\": \"unaffected\"}], \"references\": [{\"url\": \"https://github.com/pgadmin-org/pgadmin4/issues/10385\", \"tags\": [\"issue-tracking\"]}], \"descriptions\": [{\"lang\": \"en\", \"value\": \"pgAdmin 4\u0027s File Manager save_file endpoint, which backs saving from the Query Tool and ERD, validated the requested path with Filemanager.check_access_permission() and then opened the file for writing with a plain open() call. CVE-2026-7819 had previously hardened the separate file upload path by opening its target with O_NOFOLLOW, so that the kernel refuses to follow a symbolic link at the final path component, but save_file was left on an unprotected open(). A symbolic link already present when the check ran was rejected by the check itself; the remaining exposure was a link substituted at the final path component in the interval between the check and the write, at which point the write followed the link and landed outside the user\u0027s storage directory, creating or overwriting an arbitrary file as the operating-system account running pgAdmin.\\n\\nExploitation requires the ability to create or replace a symbolic link inside the requesting user\u0027s storage directory. pgAdmin exposes no interface that creates symbolic links, so this requires filesystem access to the pgAdmin host or to a shared or network-mounted storage backend, together with winning the timing window. The reporter did not achieve a write against a released version, having attempted approximately 63,000 racing requests without success; the reported defect is the uncovered write path rather than a demonstrated sandbox escape.\\n\\nThe fix routes save_file\u0027s write through the same O_NOFOLLOW-protected helper already used by the upload path, so both File Manager write sinks carry identical kernel-enforced protection, and reports a symbolic-link refusal explicitly instead of surfacing the underlying system error text. Note that files created by save_file are now given mode 0600, inheriting the behaviour introduced for uploads. The protection covers the final path component; substitution of an intermediate directory component is not addressed by this change.\\n\\nThis issue affects pgAdmin 4: from the introduction of the containment check in the File Manager save path before 9.18.\"}], \"problemTypes\": [{\"descriptions\": [{\"lang\": \"en\", \"type\": \"CWE\", \"cweId\": \"CWE-367\", \"description\": \"CWE-367 Time-of-check Time-of-use (TOCTOU) Race Condition\"}, {\"lang\": \"en\", \"type\": \"CWE\", \"cweId\": \"CWE-59\", \"description\": \"CWE-59 Improper Link Resolution Before File Access (\u0027Link Following\u0027)\"}]}], \"providerMetadata\": {\"orgId\": \"f86ef6dc-4d3a-42ad-8f28-e6d5547a5007\", \"shortName\": \"PostgreSQL\", \"dateUpdated\": \"2026-09-17T15:30:51.232Z\"}}}",
      "cveMetadata": "{\"cveId\": \"CVE-2026-86861\", \"state\": \"PUBLISHED\", \"dateUpdated\": \"2026-09-17T19:18:18.115Z\", \"dateReserved\": \"2026-09-08T15:47:04.229Z\", \"assignerOrgId\": \"f86ef6dc-4d3a-42ad-8f28-e6d5547a5007\", \"datePublished\": \"2026-09-17T15:30:51.232Z\", \"assignerShortName\": \"PostgreSQL\"}",
      "dataType": "CVE_RECORD",
      "dataVersion": "5.2"
    }
  }
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
  • Confirmed: The vulnerability is confirmed from an analyst perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
  • Patched: This vulnerability was successfully patched by the user reporting the sighting.
  • Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
  • Not confirmed: The user expresses doubt about the veracity of the vulnerability.
  • Not patched: This vulnerability was not successfully patched by the user reporting the sighting.


Loading…

Loading…