fix(bigtable): stop resolving view parameters from caller-writable state - #7132
Open
prasanna8585 wants to merge 1 commit into
Open
prasanna8585 wants to merge 1 commit into
prasanna8585 wants to merge 1 commit into
Conversation
BigtableParameterizedViewTool wraps Bigtable's execute_sql to automatically inject values (like user_id) into a parameterized view's VIEW_PARAMETERS(), so the view itself can restrict which rows a query is allowed to see. The class's own docstring states this "securely restricts query execution to the logged-in user's data" -- but the resolution logic had an undocumented fallback: when a configured view_parameter_name did not match a strongly-typed attribute of tool_context (which user_id always does, via ReadonlyContext), it fell back to tool_context.state[param_name]. tool_context.state is writable by the caller -- the same fact this same PR's sibling fix (BigQuery/AgentEngineSandboxComputer, in query_tool.py and sandbox_computer.py) already established for a different pair of tools in this same file tree. A view parameter taken from state lets the caller choose which user's (or tenant's) rows a "securely restricted" parameterized view returns, defeating the row- level restriction the feature exists to provide. This is realistic for any application-defined scoping parameter beyond the documented user_id example -- tenant_id, org_id, customer_id, or any other custom name a multi-tenant deployment configures via view_parameter_names, none of which are built-in ToolContext/ReadonlyContext attributes. Verified this was never previously addressed: the feature was introduced in 14a24f2 (PR google#6128, "Support parameterized views with secure parameter injection") and has had no subsequent fix; the only later commit touching this file is an unrelated mypy-typing refactor. Fix: remove the tool_context.state fallback entirely. Only names that resolve to a real tool_context attribute are honored now; anything else is silently omitted from view_parameters, exactly as an already- missing attribute was previously handled. Verified: existing test suite (14 tests) run and pass, including the two pre-existing tests that only exercise the safe, strongly-typed path (user_id), which are unaffected. The test that asserted the vulnerable fallback behavior (test_bigtable_parameterized_view_tool_execution_session_state_fallback) is replaced with test_bigtable_parameterized_view_tool_ignores_state_for_custom_parameters, asserting the opposite: a caller-controlled tenant_id sitting in session state is not used. Confirmed this new test actually catches the bug by temporarily reverting the fix locally and re-running it -- it fails against the vulnerable code and passes against the fix. test_bigtable_parameterized_view_tool_execution_multiple_parameters is updated to match: tenant_id/agent_id (state-only) are now correctly omitted from the result, while user_id (a real attribute) still resolves.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BigtableParameterizedViewTool wraps Bigtable's execute_sql to automatically inject values (like user_id) into a parameterized view's VIEW_PARAMETERS(), so the view itself can restrict which rows a query is allowed to see. The class's own docstring states this "securely restricts query execution to the logged-in user's data" -- but the resolution logic had an undocumented fallback: when a configured view_parameter_name did not match a strongly-typed attribute of tool_context (which user_id always does, via ReadonlyContext), it fell back to tool_context.state[param_name].
tool_context.state is writable by the caller -- the same fact this same PR's sibling fix (BigQuery/AgentEngineSandboxComputer, in query_tool.py and sandbox_computer.py) already established for a different pair of tools in this same file tree. A view parameter taken from state lets the caller choose which user's (or tenant's) rows a "securely restricted" parameterized view returns, defeating the row- level restriction the feature exists to provide. This is realistic for any application-defined scoping parameter beyond the documented user_id example -- tenant_id, org_id, customer_id, or any other custom name a multi-tenant deployment configures via view_parameter_names, none of which are built-in ToolContext/ReadonlyContext attributes.
Verified this was never previously addressed: the feature was introduced in 14a24f2 (PR #6128, "Support parameterized views with secure parameter injection") and has had no subsequent fix; the only later commit touching this file is an unrelated mypy-typing refactor.
Fix: remove the tool_context.state fallback entirely. Only names that resolve to a real tool_context attribute are honored now; anything else is silently omitted from view_parameters, exactly as an already- missing attribute was previously handled.
Verified: existing test suite (14 tests) run and pass, including the two pre-existing tests that only exercise the safe, strongly-typed path (user_id), which are unaffected. The test that asserted the vulnerable fallback behavior (test_bigtable_parameterized_view_tool_execution_session_state_fallback) is replaced with test_bigtable_parameterized_view_tool_ignores_state_for_custom_parameters, asserting the opposite: a caller-controlled tenant_id sitting in session state is not used. Confirmed this new test actually catches the bug by temporarily reverting the fix locally and re-running it -- it fails against the vulnerable code and passes against the fix. test_bigtable_parameterized_view_tool_execution_multiple_parameters is updated to match: tenant_id/agent_id (state-only) are now correctly omitted from the result, while user_id (a real attribute) still resolves.