Skip to content

feat(api): log rejected related/distinct field access as security events#41306

Open
rusackas wants to merge 2 commits into
masterfrom
fix/log-allowlist-denials
Open

feat(api): log rejected related/distinct field access as security events#41306
rusackas wants to merge 2 commits into
masterfrom
fix/log-allowlist-denials

Conversation

@rusackas

Copy link
Copy Markdown
Member

SUMMARY

When a user-supplied column_name fails the related/distinct allowlist check in BaseSupersetModelRestApi, the API incremented a statsd counter and returned a 404 but emitted no structured log event. As a result, rejected field-access attempts against these secondary checks were absent from the security audit trail — no caller identity, endpoint, or attempted value.

This adds a sanitized security log event (user id, endpoint, attempted column) at both denial points, alongside the existing statsd counter. The attempted column name is sanitized to a single bounded token (printable, no newlines, length-capped) so it cannot inject log lines. The allowlist control itself is unchanged.

This addresses two related audit-trail gaps in views/base_api.py: the secondary-authorization denial (the related/distinct 404) and the input-validation/allowlist-bypass attempt that produces it.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

N/A — audit logging.

TESTING INSTRUCTIONS

test_get_related_fail (run for each resource via ApiOwnersTestCaseMixin) is extended to assert a logger.warning security event is emitted with the rejected column name when a disallowed related field is requested.

Run e.g.: pytest tests/integration_tests/charts/api_tests.py -k related_fail

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

When a user-supplied column_name fails the related/distinct allowlist check,
the API incremented a statsd counter and returned 404 but emitted no structured
log event, so rejected field-access attempts were absent from the security
audit trail (no user identity, endpoint, or attempted value).

Emit a sanitized security log event (user id, endpoint, attempted column) on
these denials, alongside the existing statsd counter. The column name is
sanitized to a single bounded token to prevent log injection. The allowlist
control itself is unchanged.

Extends the related-field failure integration test to assert the event is
logged with the rejected column name.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@rusackas rusackas added the asvs label Jun 23, 2026
@dosubot dosubot Bot added api Related to the REST API logging Creates a UI or API endpoint that could benefit from logging. labels Jun 23, 2026
@bito-code-review

bito-code-review Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #6fff82

Actionable Suggestions - 0
Review Details
  • Files reviewed - 2 · Commit Range: 7d9b918..7d9b918
    • superset/views/base_api.py
    • tests/integration_tests/base_api_tests.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@github-actions github-actions Bot removed the api Related to the REST API label Jun 23, 2026
Comment thread superset/views/base_api.py
@bito-code-review

Copy link
Copy Markdown
Contributor

The flagged security issue is correct. The current sanitization logic only removes control characters and newlines, allowing attackers to inject spaces and punctuation like = into the log message, which can corrupt downstream log parsing. To resolve this, you should restrict the sanitized_column to a safe character set, such as alphanumeric characters, underscores, hyphens, and dots.

Here is the corrected implementation for superset/views/base_api.py:

        # Sanitize the user-supplied column name to a safe token set
        import re
        sanitized_column = re.sub(r'[^a-zA-Z0-9_.-]', '', str(column_name))[:200]
        logger.warning(
            "Rejected disallowed field access: user_id=%s endpoint=%s.%s column=%s",
            get_user_id(),
            self.__class__.__name__,
            func_name,
            sanitized_column,
        )

There are no other review comments in this pull request. Would you like me to assist with any other part of the implementation?

superset/views/base_api.py

# Sanitize the user-supplied column name to a safe token set
        import re
        sanitized_column = re.sub(r'[^a-zA-Z0-9_.-]', '', str(column_name))[:200]
        logger.warning(
            "Rejected disallowed field access: user_id=%s endpoint=%s.%s column=%s",
            get_user_id(),
            self.__class__.__name__,
            func_name,
            sanitized_column,
        )

@codecov

codecov Bot commented Jun 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.34%. Comparing base (3b46a5f) to head (9b7f632).
⚠️ Report is 3 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #41306      +/-   ##
==========================================
- Coverage   64.34%   64.34%   -0.01%     
==========================================
  Files        2653     2653              
  Lines      144952   144957       +5     
  Branches    33433    33433              
==========================================
  Hits        93273    93273              
- Misses      49995    49998       +3     
- Partials     1684     1686       +2     
Flag Coverage Δ
hive 39.27% <20.00%> (-0.01%) ⬇️
mysql 58.00% <100.00%> (+<0.01%) ⬆️
postgres 58.07% <100.00%> (-0.01%) ⬇️
presto 40.86% <20.00%> (-0.01%) ⬇️
python 59.51% <100.00%> (-0.01%) ⬇️
sqlite 57.72% <100.00%> (+<0.01%) ⬆️
unit 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

asvs logging Creates a UI or API endpoint that could benefit from logging. size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants