CVE-2020-11978
Description
An issue was found in Apache Airflow versions 1.10.10 and below. A remote code/command injection vulnerability was discovered in one of the example DAGs shipped with Airflow which would allow any authenticated user to run arbitrary commands as the user running airflow worker/scheduler (depending on the executor in use). If you already have examples disabled by setting load_examples=False in the config then you are not vulnerable.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
apache-airflowPyPI | < 1.10.11rc1 | 1.10.11rc1 |
Affected products
1- Apache Software Foundation/Apache Airflowv5Range: 1.10.10 and below
Patches
22fa51576e128Add note about using dag_run.conf in BashOperator (#9143)
3 files changed · +65 −3
airflow/example_dags/example_trigger_target_dag.py+2 −2 modified@@ -66,7 +66,7 @@ def run_this_func(ds, **kwargs): # You can also access the DagRun object in templates bash_task = BashOperator( task_id="bash_task", - bash_command='echo "Here is the message: ' - '{{ dag_run.conf["message"] if dag_run else "" }}" ', + bash_command='echo "Here is the message: $message"', + env={'message': '{{ dag_run.conf["message"] if dag_run else "" }}'}, dag=dag, )
airflow/operators/bash_operator.py+32 −1 modified@@ -33,7 +33,7 @@ class BashOperator(BaseOperator): - """ + r""" Execute a Bash script, command or set of commands. .. seealso:: @@ -53,6 +53,37 @@ class BashOperator(BaseOperator): :type env: dict :param output_encoding: Output encoding of bash command :type output_encoding: str + + .. warning:: + + Care should be taken with "user" input or when using Jinja templates in the + ``bash_command``, as this bash operator does not perform any escaping or + sanitization of the command. + + This applies mostly to using "dag_run" conf, as that can be submitted via + users in the Web UI. Most of the default template variables are not at + risk. + + For example, do **not** do this: + + .. code-block:: python + + bash_task = BashOperator( + task_id="bash_task", + bash_command='echo "Here is the message: \'{{ dag_run.conf["message"] if dag_run else "" }}\'"', + ) + + Instead, you should pass this via the ``env`` kwarg and use double-quotes + inside the bash_command, as below: + + .. code-block:: python + + bash_task = BashOperator( + task_id="bash_task", + bash_command='echo "here is the message: \'$message\'"', + env={'message': '{{ dag_run.conf["message"] if dag_run else "" }}'}, + ) + """ template_fields = ('bash_command', 'env') template_ext = ('.sh', '.bash',)
docs/howto/operator/bash.rst+31 −0 modified@@ -41,6 +41,37 @@ You can use :ref:`Jinja templates <jinja-templating>` to parameterize the :start-after: [START howto_operator_bash_template] :end-before: [END howto_operator_bash_template] + +.. warning:: + + Care should be taken with "user" input or when using Jinja templates in the + ``bash_command``, as this bash operator does not perform any escaping or + sanitization of the command. + + This applies mostly to using "dag_run" conf, as that can be submitted via + users in the Web UI. Most of the default template variables are not at + risk. + +For example, do **not** do this: + +.. code-block:: python + + bash_task = BashOperator( + task_id="bash_task", + bash_command='echo "Here is the message: \'{{ dag_run.conf["message"] if dag_run else "" }}\'"', + ) + +Instead, you should pass this via the ``env`` kwarg and use double-quotes +inside the bash_command, as below: + +.. code-block:: python + + bash_task = BashOperator( + task_id="bash_task", + bash_command='echo "here is the message: \'$message\'"', + env={'message': '{{ dag_run.conf["message"] if dag_run else "" }}'}, + ) + Troubleshooting ---------------
4d8599e8b052Add note about using dag_run.conf in BashOperator (#9143)
3 files changed · +65 −2
airflow/example_dags/example_trigger_target_dag.py+2 −1 modified@@ -49,6 +49,7 @@ def run_this_func(**context): bash_task = BashOperator( task_id="bash_task", - bash_command='echo "Here is the message: \'{{ dag_run.conf["message"] if dag_run else "" }}\'"', + bash_command='echo "Here is the message: $message"', + env={'message': '{{ dag_run.conf["message"] if dag_run else "" }}'}, dag=dag, )
airflow/operators/bash.py+32 −1 modified@@ -30,7 +30,7 @@ class BashOperator(BaseOperator): - """ + r""" Execute a Bash script, command or set of commands. .. seealso:: @@ -61,6 +61,37 @@ class BashOperator(BaseOperator): .. code-block:: python bash_command = "set -e; python3 script.py '{{ next_execution_date }}'" + + .. warning:: + + Care should be taken with "user" input or when using Jinja templates in the + ``bash_command``, as this bash operator does not perform any escaping or + sanitization of the command. + + This applies mostly to using "dag_run" conf, as that can be submitted via + users in the Web UI. Most of the default template variables are not at + risk. + + For example, do **not** do this: + + .. code-block:: python + + bash_task = BashOperator( + task_id="bash_task", + bash_command='echo "Here is the message: \'{{ dag_run.conf["message"] if dag_run else "" }}\'"', + ) + + Instead, you should pass this via the ``env`` kwarg and use double-quotes + inside the bash_command, as below: + + .. code-block:: python + + bash_task = BashOperator( + task_id="bash_task", + bash_command='echo "here is the message: \'$message\'"', + env={'message': '{{ dag_run.conf["message"] if dag_run else "" }}'}, + ) + """ template_fields = ('bash_command', 'env') template_ext = ('.sh', '.bash',)
docs/howto/operator/bash.rst+31 −0 modified@@ -41,6 +41,37 @@ You can use :ref:`Jinja templates <jinja-templating>` to parameterize the :start-after: [START howto_operator_bash_template] :end-before: [END howto_operator_bash_template] + +.. warning:: + + Care should be taken with "user" input or when using Jinja templates in the + ``bash_command``, as this bash operator does not perform any escaping or + sanitization of the command. + + This applies mostly to using "dag_run" conf, as that can be submitted via + users in the Web UI. Most of the default template variables are not at + risk. + +For example, do **not** do this: + +.. code-block:: python + + bash_task = BashOperator( + task_id="bash_task", + bash_command='echo "Here is the message: \'{{ dag_run.conf["message"] if dag_run else "" }}\'"', + ) + +Instead, you should pass this via the ``env`` kwarg and use double-quotes +inside the bash_command, as below: + +.. code-block:: python + + bash_task = BashOperator( + task_id="bash_task", + bash_command='echo "here is the message: \'$message\'"', + env={'message': '{{ dag_run.conf["message"] if dag_run else "" }}'}, + ) + Troubleshooting ---------------
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- github.com/advisories/GHSA-rvmq-4x66-q7j3ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-11978ghsaADVISORY
- packetstormsecurity.com/files/162908/Apache-Airflow-1.10.10-Remote-Code-Execution.htmlghsaWEB
- packetstormsecurity.com/files/174764/Apache-Airflow-1.10.10-Remote-Code-Execution.htmlghsaWEB
- github.com/apache/airflow/commit/2fa51576e1283f5732e38fada686fd248d9c3a1eghsaWEB
- github.com/apache/airflow/commit/4d8599e8b0520ff4226fbad72f724afae50fdd08ghsaWEB
- github.com/apache/airflow/pull/9143ghsaWEB
- github.com/pypa/advisory-database/tree/main/vulns/apache-airflow/PYSEC-2020-14.yamlghsaWEB
- lists.apache.org/thread.html/r7255cf0be3566f23a768e2a04b40fb09e52fcd1872695428ba9afe91%40%3Cusers.airflow.apache.org%3EghsaWEB
- www.cisa.gov/known-exploited-vulnerabilities-catalogghsaWEB
News mentions
0No linked articles in our index yet.