FKIE_CVE-2026-17349

Vulnerability from fkie_nvd - Published: 2026-07-31 16:16 - Updated: 2026-10-23 23:10
Summary
/misc/workspace/adhoc_connect_server, part of the Workspaces feature introduced in pgAdmin 4 9.0, when passed the id of an existing server, clones that server via Server.clone(), which copies every column from the source row, including user_id, shared, shared_username, and the stored credential fields password, save_password, and tunnel_password. When a non-owner triggered an adhoc connect against another user's (in practice, typically an administrator's) shared server, the clone inherited that user's ownership, shared flag, and stored database credentials verbatim. pgAdmin persisted this cross-tenant, credential-bearing server row before the connection was even attempted, so it survived even when the connection subsequently failed. The non-owner could then open the newly-owned clone and pgAdmin would connect using the source user's stored database password on the non-owner's behalf, granting the non-owner use of database credentials -- and whatever database privileges they confer -- that were never their own. Fix forces the cloned adhoc record's ownership fields (user_id, shared, shared_username) and stored credential fields (password, save_password, tunnel_password) to belong to the calling user and be cleared/private before committing, regardless of the source server's ownership, sharing state, or stored credentials. A regression test asserts that an adhoc connect triggered by a non-owner against another user's shared server persists a row owned by the caller, not shared, and without the source's stored credentials. This issue affects pgAdmin 4: from 9.0 before 9.17.
Impacted products
Vendor Product Version
pgadmin pgadmin_4 *

{
  "affected": [
    {
      "affectedData": [
        {
          "defaultStatus": "unaffected",
          "modules": [
            "Workspaces"
          ],
          "product": "pgAdmin 4",
          "programFiles": [
            "https://github.com/pgadmin-org/pgadmin4/blob/master/web/pgadmin/misc/workspaces/__init__.py"
          ],
          "repo": "https://github.com/pgadmin-org/pgadmin4",
          "vendor": "pgadmin.org",
          "versions": [
            {
              "lessThan": "9.17",
              "status": "affected",
              "version": "9.0",
              "versionType": "custom"
            }
          ]
        }
      ],
      "source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007"
    }
  ],
  "configurations": [
    {
      "nodes": [
        {
          "cpeMatch": [
            {
              "criteria": "cpe:2.3:a:pgadmin:pgadmin_4:*:*:*:*:*:postgresql:*:*",
              "matchCriteriaId": "19055EF1-2717-4422-BC50-4D5764612CC8",
              "versionEndExcluding": "9.17",
              "versionStartIncluding": "9.0",
              "vulnerable": true
            }
          ],
          "negate": false,
          "operator": "OR"
        }
      ]
    }
  ],
  "cveTags": [],
  "descriptions": [
    {
      "lang": "en",
      "value": "/misc/workspace/adhoc_connect_server, part of the Workspaces feature introduced in pgAdmin 4 9.0, when passed the id of an existing server, clones that server via Server.clone(), which copies every column from the source row, including user_id, shared, shared_username, and the stored credential fields password, save_password, and tunnel_password. When a non-owner triggered an adhoc connect against another user\u0027s (in practice, typically an administrator\u0027s) shared server, the clone inherited that user\u0027s ownership, shared flag, and stored database credentials verbatim. pgAdmin persisted this cross-tenant, credential-bearing server row before the connection was even attempted, so it survived even when the connection subsequently failed. The non-owner could then open the newly-owned clone and pgAdmin would connect using the source user\u0027s stored database password on the non-owner\u0027s behalf, granting the non-owner use of database credentials -- and whatever database privileges they confer -- that were never their own.\n\nFix forces the cloned adhoc record\u0027s ownership fields (user_id, shared, shared_username) and stored credential fields (password, save_password, tunnel_password) to belong to the calling user and be cleared/private before committing, regardless of the source server\u0027s ownership, sharing state, or stored credentials. A regression test asserts that an adhoc connect triggered by a non-owner against another user\u0027s shared server persists a row owned by the caller, not shared, and without the source\u0027s stored credentials.\n\nThis issue affects pgAdmin 4: from 9.0 before 9.17."
    },
    {
      "lang": "es",
      "value": "/misc/workspace/adhoc_connect_server, parte de la caracter\u00edstica Workspaces introducida en pgAdmin 4 9.0, cuando se le pasa el ID de un servidor existente, clona ese servidor a trav\u00e9s de Server.clone(), lo que copia cada columna de la fila de origen, incluyendo user_id, shared, shared_username, y los campos de credenciales almacenadas password, save_password, y tunnel_password. Cuando un no-propietario activaba una conexi\u00f3n ad-hoc contra el servidor compartido de otro usuario (en la pr\u00e1ctica, t\u00edpicamente de un administrador), el clon heredaba la propiedad de ese usuario, el indicador de compartido, y las credenciales de la base de datos almacenadas textualmente. pgAdmin persist\u00eda esta fila de servidor entre inquilinos y portadora de credenciales antes de que la conexi\u00f3n fuera siquiera intentada, por lo que sobreviv\u00eda incluso cuando la conexi\u00f3n fallaba posteriormente. El no-propietario pod\u00eda entonces abrir el clon reci\u00e9n adquirido y pgAdmin se conectar\u00eda usando la contrase\u00f1a de la base de datos almacenada del usuario de origen en nombre del no-propietario, otorgando al no-propietario el uso de credenciales de la base de datos -- y cualesquiera privilegios de la base de datos que estas confieran -- que nunca fueron suyas.\n\nLa correcci\u00f3n fuerza que los campos de propiedad del registro ad-hoc clonado (user_id, shared, shared_username) y los campos de credenciales almacenadas (password, save_password, tunnel_password) pertenezcan al usuario que realiza la llamada y se borren/privaticen antes de la confirmaci\u00f3n, independientemente de la propiedad del servidor de origen, el estado de compartido o las credenciales almacenadas. Una prueba de regresi\u00f3n afirma que una conexi\u00f3n ad-hoc activada por un no-propietario contra el servidor compartido de otro usuario persiste una fila propiedad del llamador, no compartida, y sin las credenciales almacenadas del origen.\n\nEste problema afecta a pgAdmin 4: desde 9.0 antes de 9.17."
    }
  ],
  "id": "CVE-2026-17349",
  "lastModified": "2026-10-23T23:10:00.157",
  "metrics": {
    "cvssMetricV31": [
      {
        "cvssData": {
          "attackComplexity": "LOW",
          "attackVector": "NETWORK",
          "availabilityImpact": "NONE",
          "baseScore": 9.6,
          "baseSeverity": "CRITICAL",
          "confidentialityImpact": "HIGH",
          "integrityImpact": "HIGH",
          "privilegesRequired": "LOW",
          "scope": "CHANGED",
          "userInteraction": "NONE",
          "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N",
          "version": "3.1"
        },
        "exploitabilityScore": 3.1,
        "impactScore": 5.8,
        "source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
        "type": "Secondary"
      }
    ],
    "cvssMetricV40": [
      {
        "cvssData": {
          "Automatable": "NOT_DEFINED",
          "Recovery": "NOT_DEFINED",
          "Safety": "NOT_DEFINED",
          "attackComplexity": "LOW",
          "attackRequirements": "NONE",
          "attackVector": "NETWORK",
          "availabilityRequirement": "NOT_DEFINED",
          "baseScore": 9.3,
          "baseSeverity": "CRITICAL",
          "confidentialityRequirement": "NOT_DEFINED",
          "exploitMaturity": "NOT_DEFINED",
          "integrityRequirement": "NOT_DEFINED",
          "modifiedAttackComplexity": "NOT_DEFINED",
          "modifiedAttackRequirements": "NOT_DEFINED",
          "modifiedAttackVector": "NOT_DEFINED",
          "modifiedPrivilegesRequired": "NOT_DEFINED",
          "modifiedSubAvailabilityImpact": "NOT_DEFINED",
          "modifiedSubConfidentialityImpact": "NOT_DEFINED",
          "modifiedSubIntegrityImpact": "NOT_DEFINED",
          "modifiedUserInteraction": "NOT_DEFINED",
          "modifiedVulnAvailabilityImpact": "NOT_DEFINED",
          "modifiedVulnConfidentialityImpact": "NOT_DEFINED",
          "modifiedVulnIntegrityImpact": "NOT_DEFINED",
          "privilegesRequired": "LOW",
          "providerUrgency": "NOT_DEFINED",
          "subAvailabilityImpact": "NONE",
          "subConfidentialityImpact": "HIGH",
          "subIntegrityImpact": "HIGH",
          "userInteraction": "NONE",
          "valueDensity": "NOT_DEFINED",
          "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:H/SI:H/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",
          "version": "4.0",
          "vulnAvailabilityImpact": "NONE",
          "vulnConfidentialityImpact": "HIGH",
          "vulnIntegrityImpact": "HIGH",
          "vulnerabilityResponseEffort": "NOT_DEFINED"
        },
        "source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
        "type": "Secondary"
      }
    ],
    "ssvcV203": [
      {
        "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
        "ssvcData": {
          "id": "CVE-2026-17349",
          "options": [
            {
              "exploitation": "none"
            },
            {
              "automatable": "no"
            },
            {
              "technicalImpact": "total"
            }
          ],
          "role": "CISA Coordinator",
          "timestamp": "2026-07-31T00:00:00+00:00",
          "version": "2.0.3"
        }
      }
    ]
  },
  "published": "2026-07-31T16:16:59.480",
  "references": [
    {
      "source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
      "tags": [
        "Patch"
      ],
      "url": "https://github.com/pgadmin-org/pgadmin4/commit/64a9cdbd6a240a962144f84418beaf9e66419779"
    },
    {
      "source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
      "tags": [
        "Patch"
      ],
      "url": "https://github.com/pgadmin-org/pgadmin4/commit/a7e74a6ed685bc34e1f77a8b6a94d00fa3dff815"
    },
    {
      "source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
      "tags": [
        "Issue Tracking",
        "Patch",
        "Vendor Advisory"
      ],
      "url": "https://github.com/pgadmin-org/pgadmin4/issues/10200"
    }
  ],
  "sourceIdentifier": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
  "vulnStatus": "Analyzed",
  "weaknesses": [
    {
      "description": [
        {
          "lang": "en",
          "value": "CWE-522"
        },
        {
          "lang": "en",
          "value": "CWE-639"
        }
      ],
      "source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
      "type": "Secondary"
    }
  ]
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline

Sightings and recorded dates, grouped by day · UTC

JSON
Events included in the timeline

Loading timeline…


    Loading…

    Loading…

    Loading…

    Related by attack behaviour

    Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.