Apache Airflow Pinot provider allowed Command Injection
Description
OS command injection in Apache Airflow Pinot Provider allows attackers to execute arbitrary commands in task execution context without write access to DAG files.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
OS command injection in Apache Airflow Pinot Provider allows attackers to execute arbitrary commands in task execution context without write access to DAG files.
CVE-2022-38649 is an OS command injection vulnerability in the Apache Airflow Pinot Provider, affecting versions prior to 4.0.0, as well as any Airflow version prior to 2.3.0 if the Pinot Provider is installed [2]. The root cause is improper neutralization of special elements used in an OS command, where the PinotAdminHook allowed the attacker-controlled connection parameter cmd_path to be injected into the command executed by pinot-admin.sh [3]. This allowed a malicious actor to control the command path without needing write access to DAG files [1].
To exploit this, an attacker must have the ability to modify Airflow connection configurations, for example, through the Airflow UI or API, as the cmd_path parameter was read from the connection's extra JSON [3]. The attack can be performed by setting the cmd_path to the attacker's executable or script, which is then executed with the privileges of the Airflow worker [1]. The exploitation does not require the attacker to have write access to DAG files, lowering the barrier for exploitation [2].
Successful exploitation allows an attacker to execute arbitrary OS commands in the task execution context, potentially leading to full compromise of the Airflow worker environment, including access to sensitive data, credentials, and the ability to pivot to other systems [1][2]. The impact is high, as Airflow workers often have access to various databases, cloud services, and other infrastructure [1].
Affected users should upgrade to Apache Airflow Pinot Provider version 4.0.0, which hard-codes the pinot-admin.sh command path and prevents the injection [3][4]. For Airflow versions prior to 2.3.0, upgrading Airflow itself to 2.3.0 or later is required before installing the fixed Pinot Provider [2]. No workarounds are provided by the vendor, and the vulnerability is not listed on CISA's Known Exploited Vulnerabilities catalog at the time of writing.
- GitHub - apache/airflow: Apache Airflow - A platform to programmatically author, schedule, and monitor workflows
- NVD - CVE-2022-38649
- The pinot-admin.sh command is now hard-coded. (#27641) · apache/airflow@1d4fd5c
- The pinot-admin.sh command is now hard-coded. by potiuk · Pull Request #27641 · apache/airflow
AI Insight generated on May 21, 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.
| Package | Affected versions | Patched versions |
|---|---|---|
apache-airflowPyPI | < 2.3.0 | 2.3.0 |
Affected products
4- osv-coords2 versions
< 2.3.0+ 1 more
- (no CPE)range: < 2.3.0
- (no CPE)range: < 2.3.0
- Range: unspecified
Patches
11d4fd5c6eacaThe pinot-admin.sh command is now hard-coded. (#27641)
4 files changed · +49 −7
airflow/providers/apache/pinot/CHANGELOG.rst+22 −0 modified@@ -24,6 +24,28 @@ Changelog --------- +4.0.0 +..... + +This release of provider is only available for Airflow 2.3+ as explained in the Apache Airflow +providers support policy https://github.com/apache/airflow/blob/main/README.md#support-for-providers + +Breaking changes +~~~~~~~~~~~~~~~~ + +The admin command is now hard-coded to ``pinot-admin.sh``. The ``pinot-admin.sh`` command must be available +on the path in order to use PinotAdminHook. + +Misc +~~~~ + +* ``Move min airflow version to 2.3.0 for all providers (#27196)`` +* ``Bump pinotdb version (#27201)`` + +.. Below changes are excluded from the changelog. Move them to + appropriate section above if needed. Do not delete the lines(!): + * ``Enable string normalization in python formatting - providers (#27205)`` + 3.2.1 .....
airflow/providers/apache/pinot/hooks/pinot.py+13 −3 modified@@ -46,7 +46,10 @@ class PinotAdminHook(BaseHook): following PR: https://github.com/apache/incubator-pinot/pull/4110 :param conn_id: The name of the connection to use. - :param cmd_path: The filepath to the pinot-admin.sh executable + :param cmd_path: Do not modify the parameter. It used to be the filepath to the pinot-admin.sh + executable but in version 4.0.0 of apache-pinot provider, value of this parameter must + remain the default value: `pinot-admin.sh`. It is left here to not accidentally override + the `pinot_admin_system_exit` in case positional parameters were used to initialize the hook. :param pinot_admin_system_exit: If true, the result is evaluated based on the status code. Otherwise, the result is evaluated as a failure if "Error" or "Exception" is in the output message. @@ -62,7 +65,15 @@ def __init__( conn = self.get_connection(conn_id) self.host = conn.host self.port = str(conn.port) - self.cmd_path = conn.extra_dejson.get("cmd_path", cmd_path) + if cmd_path != "pinot-admin.sh": + raise RuntimeError( + "In version 4.0.0 of the PinotAdminHook the cmd_path has been hard-coded to" + " pinot-admin.sh. In order to avoid accidental using of this parameter as" + " positional `pinot_admin_system_exit` the `cmd_parameter`" + " parameter is left here but you should not modify it. Make sure that " + " `pinot-admin.sh` is on your PATH and do not change cmd_path value." + ) + self.cmd_path = "pinot-admin.sh" self.pinot_admin_system_exit = conn.extra_dejson.get( "pinot_admin_system_exit", pinot_admin_system_exit ) @@ -213,7 +224,6 @@ def run_cli(self, cmd: list[str], verbose: bool = True) -> str: if verbose: self.log.info(" ".join(command)) - with subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True, env=env ) as sub_process:
airflow/providers/apache/pinot/provider.yaml+1 −0 modified@@ -22,6 +22,7 @@ description: | `Apache Pinot <https://pinot.apache.org/>`__ versions: + - 4.0.0 - 3.2.1 - 3.2.0 - 3.1.0
tests/providers/apache/pinot/hooks/test_pinot.py+13 −4 modified@@ -35,7 +35,7 @@ def setUp(self): self.conn = conn = mock.MagicMock() self.conn.host = "host" self.conn.port = "1000" - self.conn.extra_dejson = {"cmd_path": "./pinot-admin.sh"} + self.conn.extra_dejson = {} class PinotAdminHookTest(PinotAdminHook): def get_connection(self, conn_id): @@ -165,7 +165,7 @@ def test_run_cli_success(self, mock_popen): params = ["foo", "bar", "baz"] self.db_hook.run_cli(params) - params.insert(0, self.conn.extra_dejson.get("cmd_path")) + params.insert(0, "pinot-admin.sh") mock_popen.assert_called_once_with( params, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, close_fds=True, env=None ) @@ -180,7 +180,7 @@ def test_run_cli_failure_error_message(self, mock_popen): params = ["foo", "bar", "baz"] with pytest.raises(AirflowException): self.db_hook.run_cli(params) - params.insert(0, self.conn.extra_dejson.get("cmd_path")) + params.insert(0, "pinot-admin.sh") mock_popen.assert_called_once_with( params, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, close_fds=True, env=None ) @@ -196,14 +196,23 @@ def test_run_cli_failure_status_code(self, mock_popen): params = ["foo", "bar", "baz"] with pytest.raises(AirflowException): self.db_hook.run_cli(params) - params.insert(0, self.conn.extra_dejson.get("cmd_path")) + params.insert(0, "pinot-admin.sh") env = os.environ.copy() env.update({"JAVA_OPTS": "-Dpinot.admin.system.exit=true "}) mock_popen.assert_called_once_with( params, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, close_fds=True, env=env ) +class TestPinotAdminHookCreation: + def test_exception_when_overriding_cmd_path(self): + with pytest.raises(RuntimeError): + PinotAdminHook(cmd_path="some_path.sh") + + def test_exception_when_keeping_cmd_path(self): + PinotAdminHook(cmd_path="pinot-admin.sh") + + class TestPinotDbApiHook(unittest.TestCase): def setUp(self): super().setUp()
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5News mentions
0No linked articles in our index yet.