Skip to content

Commit

Permalink
Better PRAGMA error message, closes #1185
Browse files Browse the repository at this point in the history
  • Loading branch information
simonw committed Jan 12, 2021
1 parent 8e8fc5c commit 640ac70
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 5 deletions.
4 changes: 3 additions & 1 deletion datasette/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,9 @@ class InvalidSql(Exception):
disallawed_sql_res = [
(
re.compile(f"pragma(?!_({'|'.join(allowed_pragmas)}))"),
"Statement may not contain PRAGMA",
"Statement contained a disallowed PRAGMA. Allowed pragma functions are {}".format(
", ".join("pragma_{}()".format(pragma) for pragma in allowed_pragmas)
),
)
]

Expand Down
5 changes: 1 addition & 4 deletions docs/sql_queries.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,7 @@ SQLite string escaping rules will be applied to values passed using named
parameters - they will be wrapped in quotes and their content will be correctly
escaped.

Datasette disallows custom SQL containing the string PRAGMA, as SQLite pragma
statements can be used to change database settings at runtime. If you need to
include the string "pragma" in a query you can do so safely using a named
parameter.
Datasette disallows custom SQL queries containing the string PRAGMA (with a small number `of exceptions <https://github.com/simonw/datasette/issues/761>`__) as SQLite pragma statements can be used to change database settings at runtime. If you need to include the string "pragma" in a query you can do so safely using a named parameter.

.. _sql_views:

Expand Down
15 changes: 15 additions & 0 deletions tests/test_html.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from bs4 import BeautifulSoup as Soup
from datasette.utils import allowed_pragmas
from .fixtures import ( # noqa
app_client,
app_client_base_url_prefix,
Expand Down Expand Up @@ -124,6 +125,20 @@ def test_invalid_custom_sql(app_client):
assert "Statement must be a SELECT" in response.text


def test_disallowed_custom_sql_pragma(app_client):
response = app_client.get(
"/fixtures?sql=SELECT+*+FROM+pragma_not_on_allow_list('idx52')"
)
assert response.status == 400
pragmas = ", ".join("pragma_{}()".format(pragma) for pragma in allowed_pragmas)
assert (
"Statement contained a disallowed PRAGMA. Allowed pragma functions are {}".format(
pragmas
)
in response.text
)


def test_sql_time_limit(app_client_shorter_time_limit):
response = app_client_shorter_time_limit.get("/fixtures?sql=select+sleep(0.5)")
assert 400 == response.status
Expand Down

0 comments on commit 640ac70

Please sign in to comment.