From 25ff0a8ba6b2e3247a66048ad173ba5ed8a38b80 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Wed, 3 Jul 2019 22:47:45 -0700 Subject: [PATCH] Fix for accidentally leaking secrets in /-/metadata, closes #538 --- datasette/app.py | 9 ++++++--- tests/test_plugins.py | 8 ++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/datasette/app.py b/datasette/app.py index 70bd3c12..56b60533 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -271,12 +271,15 @@ class Datasette: plugin_config = plugins.get(plugin_name) # Resolve any $file and $env keys if isinstance(plugin_config, dict): - for key, value in plugin_config.items(): + # Create a copy so we don't mutate the version visible at /-/metadata.json + plugin_config_copy = dict(plugin_config) + for key, value in plugin_config_copy.items(): if isinstance(value, dict): if list(value.keys()) == ["$env"]: - plugin_config[key] = os.environ.get(list(value.values())[0]) + plugin_config_copy[key] = os.environ.get(list(value.values())[0]) elif list(value.keys()) == ["$file"]: - plugin_config[key] = open(list(value.values())[0]).read() + plugin_config_copy[key] = open(list(value.values())[0]).read() + return plugin_config_copy return plugin_config def app_css_hash(self): diff --git a/tests/test_plugins.py b/tests/test_plugins.py index f42eebd7..9af2a430 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -129,12 +129,20 @@ def test_plugin_config(app_client): def test_plugin_config_env(app_client): os.environ["FOO_ENV"] = "FROM_ENVIRONMENT" assert {"foo": "FROM_ENVIRONMENT"} == app_client.ds.plugin_config("env-plugin") + # Ensure secrets aren't visible in /-/metadata.json + metadata = app_client.get("/-/metadata.json") + assert {"foo": {"$env": "FOO_ENV"}} == metadata.json["plugins"]["env-plugin"] del os.environ["FOO_ENV"] def test_plugin_config_file(app_client): open(TEMP_PLUGIN_SECRET_FILE, "w").write("FROM_FILE") assert {"foo": "FROM_FILE"} == app_client.ds.plugin_config("file-plugin") + # Ensure secrets aren't visible in /-/metadata.json + metadata = app_client.get("/-/metadata.json") + assert {"foo": {"$file": TEMP_PLUGIN_SECRET_FILE}} == metadata.json["plugins"][ + "file-plugin" + ] os.remove(TEMP_PLUGIN_SECRET_FILE)