diff --git a/airflow/example_dags/example_trigger_target_dag.py b/airflow/example_dags/example_trigger_target_dag.py index 7d4f6f6406a6b..83db9458cbcd8 100644 --- a/airflow/example_dags/example_trigger_target_dag.py +++ b/airflow/example_dags/example_trigger_target_dag.py @@ -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, ) diff --git a/airflow/operators/bash.py b/airflow/operators/bash.py index 9eef881e0ec8f..22577d291fcae 100644 --- a/airflow/operators/bash.py +++ b/airflow/operators/bash.py @@ -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',) diff --git a/docs/howto/operator/bash.rst b/docs/howto/operator/bash.rst index f581aec0d9427..ba0e21074c23e 100644 --- a/docs/howto/operator/bash.rst +++ b/docs/howto/operator/bash.rst @@ -41,6 +41,37 @@ You can use :ref:`Jinja templates ` 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 ---------------