Skip to content

fix(monitoring): escape values interpolated into query filter strings - #18491

Open
Samin061 wants to merge 2 commits into
googleapis:mainfrom
Samin061:monitoring-filter-escape
Open

Samin061 wants to merge 2 commits into
googleapis:mainfrom
Samin061:monitoring-filter-escape

Conversation

@Samin061

Copy link
Copy Markdown
Contributor

_build_label_filter and _Filter.str in monitoring_v3/query.py interpolate label values (and the metric type, group id, and project) into double-quoted Cloud Monitoring filter literals without escaping, so a value passed to Query.select_metrics/select_resources that contains a double quote closes the literal and injects filter syntax, for example select_metrics(instance_name='x" OR metric.label.y = "z') broadens the returned time series. Route every value that lands in a quoted filter literal through a helper that backslash-escapes backslashes and double quotes per the Monitoring filter syntax. Legitimate values are unchanged and the numeric comparison operators are untouched; regression tests are added in test_query.py.

  • Make sure to open an issue as a bug/issue before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea
  • Ensure the tests and linter pass
  • Code coverage does not decrease (if any source code was changed)
  • Appropriate docs were updated (if necessary)

@Samin061
Samin061 requested a review from a team as a code owner September 29, 2026 10:50

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a helper function _escape_filter_value to escape backslashes and double quotes in Google Cloud Monitoring filter string literals, protecting against filter injection vulnerabilities. It applies this escaping to metric types, group IDs, project lists, prefix/suffix matches, and default equality operators, and adds corresponding unit tests. However, the review comments highlight that the inequality operator (!=) and comparison operators (such as greater and greaterequal) still lack proper quoting and escaping, which leaves them vulnerable to filter injection and syntax errors.

@@ -635,6 +653,7 @@ def _build_label_filter(category, *args, **kwargs):
term = "{key} != {value}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The != operator does not enclose {value} in double quotes. This leads to both a security vulnerability (filter injection) and a correctness issue, as the Cloud Monitoring API requires string literals to be double-quoted. Since the default = operator in the else block quotes and escapes the value, the != operator should do the same.

Suggested change
term = "{key} != {value}"
term = '{key} != "{value}"'
value = _escape_filter_value(value)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. != is the string counterpart to =, so it now quotes and routes the value through _escape_filter_value the same way. Added a regression test.

Comment on lines 644 to 646
elif suffix == "greater":
term = "{key} > {value}"
elif suffix == "greaterequal":

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The comparison operators greater and greaterequal (as well as less and lessequal which are outside this diff hunk) do not enclose {value} in double quotes.

If these operators are intended only for numeric comparisons, we should validate that value is a safe numeric representation (e.g., by verifying it can be parsed as a float/int) to prevent filter injection. If they are also intended for lexicographical string comparisons, they must be double-quoted and escaped using _escape_filter_value(value) to comply with the Cloud Monitoring API syntax and prevent injection.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those operators are documented as INT64 numeric comparisons, so they stay unquoted. I added _numeric_filter_value to reject any value that does not parse as a number (covers greater/greaterequal/less/lessequal), which closes the injection path without breaking the numeric semantics. Test added.

This branch has not been deployed

No deployments
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