Skip to content

Require permissions on assistant endpoints and validate sampled table names - #710

Merged
chrisclark merged 2 commits into
masterfrom
fix-assistant-auth-sqli
Sep 23, 2026
Merged

chrisclark merged 2 commits into
masterfrom
fix-assistant-auth-sqli

Conversation

@chrisclark

Copy link
Copy Markdown
Collaborator

Summary

Fixes a reported security issue in the AI assistant endpoints.

  • Missing auth: AssistantHelpView (/assistant/) and AssistantHistoryApiView (/assistant/history/) were plain Views with no permission check, unlike every other Explorer view. The routes are registered even when no EXPLORER_AI_API_KEY is configured. Both now use PermissionRequiredMixin with change_permission, matching the playground, which is where the assistant is used.
  • SQL injection: table names from the request's selected_tables were put into SELECT * FROM {table_name} ... via an f-string. table_schema() returned None for unknown tables, but nothing checked that result before sampling rows.
    • build_prompt now resolves each requested table through a new find_table() helper against the connection's schema (which honors the include/exclude prefixes). It skips tables that aren't found and uses the introspected table name.
    • sample_rows_from_table also quotes the name with connection.ops.quote_name as defense in depth.

Tests

  • New: anonymous and non-staff users are denied on both endpoints, and run_assistant is never called for them.
  • New: build_prompt skips table names that aren't in the schema.
  • New: sample_rows_from_table quotes the identifier.
  • The new tests fail on master and pass with this change.
  • Updated two existing build_prompt tests to patch find_table, and fixed mocks that assigned MagicMock (the class) instead of MagicMock() (an instance).
  • The full suite passes under explorer.tests.settings. test_assistant also passes under settings_base.

🤖 Generated with Claude Code

… names

AssistantHelpView and AssistantHistoryApiView had no permission check, and
table names from the request's selected_tables were interpolated directly
into the row-sampling SQL.

- Both assistant API views now require change_permission, matching the
  playground where the assistant is used.
- build_prompt only samples tables that exist in the connection's schema
  (respecting include/exclude prefixes), using the introspected name.
- sample_rows_from_table quotes the table name via connection.ops.quote_name.

Co-Authored-By: Claude <noreply@anthropic.com>
@chrisclark
chrisclark merged commit d8d6041 into master Sep 23, 2026
11 checks passed
@chrisclark
chrisclark deleted the fix-assistant-auth-sqli branch September 23, 2026 21:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant