apache / airflow

Apache Airflow - A platform to programmatically author, schedule, and monitor workflows
https://airflow.apache.org/
Apache License 2.0
36.39k stars 14.11k forks source link

Incorrect encoding of the plus sign in URLs during user authentication #39128

Open e-galan opened 5 months ago

e-galan commented 5 months ago

Apache Airflow version

main (development)

If "Other Airflow 2 version" selected, which one?

No response

What happened?

A URL encoding error of the + sign happens during user authentication, if a user tries to access the dag run page link (/dags/<dag_id>/grid?dag_run_id=<dag_run_id>&tab=graph) while not being logged in. After several redirects the user gets forwarded to the dag page instead (/dags/<dag_id>/grid?&tab=graph).

What you think should happen instead?

The + sign in the URL should be properly encoded and decoded during the redirects. The user should be redirected to the proper dag run page (/dags/<dag_id>/grid?dag_run_id=<dag_run_id>&tab=graph).

How to reproduce

Here is what happens to the URL during the redirects. For this example I am using the latest development version of Airflow (2.10.0.dev0) and tutorial_dag from airflow/example_dags.

  1. We make a GET request to /dags/tutorial_dag/grid?dag_run_id=manual__2024-04-18T12%3A03%3A17.474232%2B00%3A00&tab=graph while being logged out from Airflow.

  2. The Airflow server checks authentication and returns a response 302 FOUND with one of the headers being Location: /login/?next=http%3A%2F%2F127.0.0.1%3A28080%2Fdags%2Ftutorial_dag%2Fgrid%3Fdag_run_id%3Dmanual__2024-04-18T12%253A03%253A17.474232%2B00%253A00%26tab%3Dgraph . Here we can see that during encoding all non-ASCII chars get prefixed with %25 (%) except for single %2B (+) which stays unchanged. This is the first error.

  3. Then the GET request is redirected to /login/?next=http%3A%2F%2F127.0.0.1%3A28080%2Fdags%2Ftutorial_dag%2Fgrid%3Fdag_run_id%3Dmanual__2024-04-18T12%253A03%253A17.474232%2B00%253A00%26tab%3Dgraph , where we can see the same un-encoded %2B in the next parameter.

  4. Once the user logs in, a POST request with the same next parameter value is made: /login/?next=http%3A%2F%2F127.0.0.1%3A28080%2Fdags%2Ftutorial_dag%2Fgrid%3Fdag_run_id%3Dmanual__2024-04-18T12%253A03%253A17.474232%2B00%253A00%26tab%3Dgraph .

  5. Again we get a 302 FOUND response, but its headers now contain Location: /dags/tutorial_dag/grid?dag_run_id=manual__2024-04-18T12%3A03%3A17.474232+00%3A00&tab=graph . Here we can see that during decoding the %25 prefixes are removed, but the lonely %2B gets decoded into a + sign. This is the second error

  6. Then we make another request to Airflow, this time using URL from step 5. Airflow can’t find the badly encoded dag_run_id and instead sends us to the dag page (/dags/tutorial_dag/grid?tab=graph).

Operating System

Debian GNU/Linux rodete

Versions of Apache Airflow Providers

No response

Deployment

Other Docker-based deployment

Deployment details

No response

Anything else?

Happens every time.

The same problem exists in Apache Airflow 2.7.3.

In Apache Airflow 2.6.3 and 2.5.3 it results in an uncaught server error, although it should be mentioned that the dag run page URL looks differently for these versions (/dags/<dag_id>/graph?run_id=<run_id>0&execution_date=<execution_date> vs /dags/<dag_id>/grid?dag_run_id=<dag_run_id>&tab=graph).

A kind of similar problem was mentioned for Apache Airflow 2.5.3 in #30898 , where Werkzeug 2.3.0 was pointed as the culprit. However, I have tested the bug in environments with Werkzeug 2.2.3, and it was still reproduced, which leads me to believe that it is probably not the reason in my case.

Are you willing to submit PR?

Code of Conduct

boring-cyborg[bot] commented 5 months ago

Thanks for opening your first issue here! Be sure to follow the issue template! If you are willing to raise PR to address this issue please do so, no need to wait for approval.

VladaZakharova commented 2 days ago

Hi @potiuk ! I think we found this problem long time ago, do you have some ideas what we can do in this case?