VYPR
Critical severityNVD Advisory· Published Jul 18, 2023· Updated Aug 5, 2024

Blue Yonder postgraas_server PostgreSQL Backend postgres_cluster_driver.py create_postgres_db sql injection

CVE-2018-25088

Description

A vulnerability, which was classified as critical, was found in Blue Yonder postgraas_server up to 2.0.0b2. Affected is the function _create_pg_connection/create_postgres_db of the file postgraas_server/backends/postgres_cluster/postgres_cluster_driver.py of the component PostgreSQL Backend Handler. The manipulation leads to sql injection. Upgrading to version 2.0.0 is able to address this issue. The patch is identified as 7cd8d016edc74a78af0d81c948bfafbcc93c937c. It is recommended to upgrade the affected component. VDB-234246 is the identifier assigned to this vulnerability.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Blue Yonder postgraas_server <=2.0.0b2 has a critical SQL injection in PostgreSQL backend handlers that allows attackers to execute arbitrary SQL.

Vulnerability

Overview

A critical SQL injection vulnerability exists in Blue Yonder's postgraas_server, a PostgreSQL-as-a-service toolkit, in versions up to and including 2.0.0b2. The flaw resides in the functions _create_pg_connection and create_postgres_db within the file postgraas_server/backends/postgres_cluster/postgres_cluster_driver.py. The root cause is the use of unsafe string formatting with user-supplied input when constructing SQL queries, bypassing proper parameterization [1][3].

Attack

Vector

The vulnerability is exploitable by an attacker who can provide crafted input to the PostgreSQL backend handler, likely through the REST API that accepts parameters like db_username and db_name. No authentication is explicitly mentioned as a barrier; the attack can be conducted over the network. The vulnerable code directly interpolates unsanitized values into SQL statements, allowing an attacker to inject arbitrary SQL commands [1][2][3].

Impact

Successful exploitation could allow an attacker to execute arbitrary SQL queries against the underlying PostgreSQL database. This could lead to unauthorized data access, modification, or deletion, as well as potential escalation of privileges within the database context. Given that postgraas_server manages database instances, an attacker could compromise the integrity and confidentiality of managed databases [1].

Mitigation

The issue is resolved in version 2.0.0, which was released alongside the commit 7cd8d016edc74a78af0d81c948bfafbcc93c937c. The fix replaces string formatting with parameterized queries using psycopg2's SQL and Identifier objects, preventing injection [3][4]. Users are strongly advised to upgrade to the latest version or apply the patch immediately.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
postgraas-serverPyPI
< 2.0.02.0.0

Affected products

3

Patches

1
7cd8d016edc7

Harden the database creation against SQL injections

https://github.com/blue-yonder/postgraas_serverMatthias BachJan 30, 2018via ghsa
3 files changed · +22 13
  • postgraas_server/backends/postgres_cluster/postgres_cluster_driver.py+20 13 modified
    @@ -1,5 +1,6 @@
     import psycopg2
     from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
    +from psycopg2.sql import SQL, Identifier
     
     
     def _create_pg_connection(config):
    @@ -19,9 +20,9 @@ def _create_pg_connection(config):
     def check_db_or_user_exists(db_name, db_user, config):
         with _create_pg_connection(config) as con:
             with con.cursor() as cur:
    -            cur.execute("SELECT 1 FROM pg_database WHERE datname='{}';".format(db_name))
    +            cur.execute("SELECT 1 FROM pg_database WHERE datname=%s;", (db_name, ))
                 db_exists = cur.fetchone() is not None
    -            cur.execute("SELECT 1 FROM pg_roles WHERE rolname='{}';".format(db_user))
    +            cur.execute("SELECT 1 FROM pg_roles WHERE rolname=%s;", (db_user, ))
                 user = cur.fetchone()
                 user_exists = user is not None
                 return db_exists or user_exists
    @@ -33,23 +34,29 @@ def create_postgres_db(connection_dict, config):
         with _create_pg_connection(config) as con:
             con.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
             with con.cursor() as cur:
    -            create_role = "CREATE USER {db_username} WITH PASSWORD '{db_pwd}';".format(**connection_dict)
    -            drop_role = "DROP ROLE {db_username};".format(**connection_dict)
    -            grant_role = 'GRANT {db_username} TO "{postgraas_user}";'.format(
    -                db_username=connection_dict['db_username'], postgraas_user=get_normalized_username(config['username'])
    -            )
    -            create_database = "CREATE DATABASE {db_name} OWNER {db_username};".format(**connection_dict)
                 try:
    -                cur.execute(create_role)
    -                cur.execute(grant_role)
    +                cur.execute(SQL("CREATE USER {} WITH PASSWORD %s;").format(
    +                    Identifier(connection_dict['db_username']),
    +                ), (
    +                    connection_dict['db_pwd'],
    +                ))
    +                cur.execute(SQL("GRANT {} TO {};").format(
    +                    Identifier(connection_dict['db_username']),
    +                    Identifier(get_normalized_username(config['username'])),
    +                ))
                 except psycopg2.ProgrammingError as e:
                     raise ValueError(e.args[0])
                 # cleanup role in case database creation fails
    -            # saidly 'CREATE DATABASE' cannot run inside a transaction block
    +            # sadly 'CREATE DATABASE' cannot run inside a transaction block
                 try:
    -                cur.execute(create_database)
    +                cur.execute(SQL("CREATE DATABASE {} OWNER {};").format(
    +                    Identifier(connection_dict['db_name']),
    +                    Identifier(connection_dict['db_username']),
    +                ))
                 except psycopg2.ProgrammingError as e:
    -                cur.execute(drop_role)
    +                cur.execute(SQL("DROP ROLE {};").format(
    +                    Identifier(connection_dict['db_username']),
    +                ))
                     raise ValueError(e.args[0])
     
     
    
  • tests/test_integration/backends/postgres_cluster/test_postgres_cluster_driver.py+1 0 modified
    @@ -193,6 +193,7 @@ def test_create_postgres_instance_username_exists(self):
                                           backend_config)
             assert ("database or user already exists" in json.loads(response.get_data(as_text=True))['description']) is True
     
    +    @pytest.mark.xfail(reason='Username now valid due to hardening against SQL injections.')
         def test_create_postgres_instance_bad_username(self):
             backend_config = CONFIGS[self.backend]['backend']
             db_credentials = {
    
  • tests/test_integration/test_backend_behaviour.py+1 0 modified
    @@ -167,6 +167,7 @@ def test_create_postgraas_twice(self):
             self.this_app.postgraas_backend.delete(db_entry)
             assert True
     
    +    @pytest.mark.xfail(reason='Username now valid due to hardening against SQL injections.')
         def test_create_postgraas_bad_username(self):
             db_credentials = {
                 "db_name": 'tests_postgraas_instance_name',
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.