This is an automated email from the ASF dual-hosted git repository.
uranusjr pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 24a53fb Add config to warn public deployment exposure in UI (#18557)
24a53fb is described below
commit 24a53fb6476a3f671859451049407ba2b8d931c8
Author: Shakaib Khan <[email protected]>
AuthorDate: Fri Dec 24 05:24:31 2021 -0500
Add config to warn public deployment exposure in UI (#18557)
Co-authored-by: eladkal <[email protected]>
Co-authored-by: Shakaib Khan <[email protected]>
Co-authored-by: Kaxil Naik <[email protected]>
---
airflow/config_templates/config.yml | 7 +++++++
airflow/config_templates/default_airflow.cfg | 3 +++
airflow/www/views.py | 25 ++++++++++++++++++++++++-
docs/apache-airflow/security/webserver.rst | 11 +++++++++++
tests/www/views/test_views_base.py | 2 +-
tests/www/views/test_views_robots.py | 13 +++++++++++++
6 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/airflow/config_templates/config.yml
b/airflow/config_templates/config.yml
index d0b9730..f929e73 100644
--- a/airflow/config_templates/config.yml
+++ b/airflow/config_templates/config.yml
@@ -1303,6 +1303,13 @@
type: integer
example: ~
default: "3"
+ - name: warn_deployment_exposure
+ description: |
+ Boolean for displaying warning for publicly viewable deployment
+ version_added: 2.3.0
+ type: boolean
+ example: ~
+ default: "True"
- name: email
description: |
diff --git a/airflow/config_templates/default_airflow.cfg
b/airflow/config_templates/default_airflow.cfg
index 496616b..f81312b 100644
--- a/airflow/config_templates/default_airflow.cfg
+++ b/airflow/config_templates/default_airflow.cfg
@@ -655,6 +655,9 @@ session_lifetime_minutes = 43200
# when auto-refresh is turned on
auto_refresh_interval = 3
+# Boolean for displaying warning for publicly viewable deployment
+warn_deployment_exposure = True
+
[email]
# Configuration email backend and whether to
diff --git a/airflow/www/views.py b/airflow/www/views.py
index f018a40..c5d9d23 100644
--- a/airflow/www/views.py
+++ b/airflow/www/views.py
@@ -120,7 +120,7 @@ from airflow.utils.log.log_reader import TaskLogReader
from airflow.utils.session import create_session, provide_session
from airflow.utils.state import State
from airflow.utils.strings import to_boolean
-from airflow.utils.timezone import td_format
+from airflow.utils.timezone import td_format, utcnow
from airflow.version import version
from airflow.www import auth, utils as wwwutils
from airflow.www.decorators import action_logging, gzipped
@@ -788,6 +788,29 @@ class Airflow(AirflowBaseView):
# Second segment is a version marker that we don't need to
show.
yield segments[2], table_name
+ if (
+ permissions.ACTION_CAN_ACCESS_MENU,
+ permissions.RESOURCE_ADMIN_MENU,
+ ) in user_permissions and conf.getboolean("webserver",
"warn_deployment_exposure"):
+ robots_file_access_count = (
+ session.query(Log)
+ .filter(Log.event == "robots")
+ .filter(Log.dttm > (utcnow() - timedelta(days=7)))
+ .count()
+ )
+ if robots_file_access_count > 0:
+ flash(
+ Markup(
+ 'Recent requests have been made to /robots.txt. '
+ 'This indicates that this deployment may be accessible
to the public internet. '
+ 'This warning can be disabled by setting
webserver.warn_deployment_exposure=False in '
+ 'airflow.cfg. Read more about web deployment security
<a href='
+ f'"{get_docs_url("security/webserver.html")}">'
+ 'here</a>'
+ ),
+ "warning",
+ )
+
return self.render_template(
'airflow/dags.html',
dags=dags,
diff --git a/docs/apache-airflow/security/webserver.rst
b/docs/apache-airflow/security/webserver.rst
index f168faa..91a06ad 100644
--- a/docs/apache-airflow/security/webserver.rst
+++ b/docs/apache-airflow/security/webserver.rst
@@ -31,6 +31,17 @@ set the below:
[webserver]
x_frame_enabled = False
+Disable Deployment Exposure Warning
+---------------------------------------
+
+Airflow warns when recent requests are made to ``/robot.txt``. To disable this
warning set ``warn_deployment_exposure`` to
+``False`` as below:
+
+.. code-block:: ini
+
+ [webserver]
+ warn_deployment_exposure = False
+
Sensitive Variable fields
-------------------------
diff --git a/tests/www/views/test_views_base.py
b/tests/www/views/test_views_base.py
index cc99682..5759369 100644
--- a/tests/www/views/test_views_base.py
+++ b/tests/www/views/test_views_base.py
@@ -30,7 +30,7 @@ from tests.test_utils.www import check_content_in_response,
check_content_not_in
def test_index(admin_client):
- with assert_queries_count(49):
+ with assert_queries_count(50):
resp = admin_client.get('/', follow_redirects=True)
check_content_in_response('DAGs', resp)
diff --git a/tests/www/views/test_views_robots.py
b/tests/www/views/test_views_robots.py
index e9fa986..232bfe0 100644
--- a/tests/www/views/test_views_robots.py
+++ b/tests/www/views/test_views_robots.py
@@ -14,8 +14,21 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
+from tests.test_utils.config import conf_vars
def test_robots(viewer_client):
resp = viewer_client.get('/robots.txt', follow_redirects=True)
assert resp.data.decode('utf-8') == "User-agent: *\nDisallow: /\n"
+
+
+def test_deployment_warning_config(admin_client):
+ warn_text = "webserver.warn_deployment_exposure"
+ admin_client.get('/robots.txt', follow_redirects=True)
+ resp = admin_client.get('', follow_redirects=True)
+ assert warn_text in resp.data.decode('utf-8')
+
+ with conf_vars({('webserver', 'warn_deployment_exposure'): 'False'}):
+ admin_client.get('/robots.txt', follow_redirects=True)
+ resp = admin_client.get('/robots.txt', follow_redirects=True)
+ assert warn_text not in resp.data.decode('utf-8')