Skip to content

fix(tool/mysql-get-query-plan): prevent query execution bypass and statement injection#3235

Merged
averikitsch merged 8 commits into
googleapis:mainfrom
evilgensec:fix/mysql-explain-analyze-injection
Jun 15, 2026
Merged

fix(tool/mysql-get-query-plan): prevent query execution bypass and statement injection#3235
averikitsch merged 8 commits into
googleapis:mainfrom
evilgensec:fix/mysql-explain-analyze-injection

Conversation

@evilgensec

Copy link
Copy Markdown
Contributor

Summary

mysql-get-query-plan builds its EXPLAIN query by directly interpolating the
caller-supplied sql_statement into EXPLAIN FORMAT=JSON %s with no
validation:

// internal/tools/mysql/mysqlgetqueryplan/mysqlgetqueryplan.go:118
query := fmt.Sprintf("EXPLAIN FORMAT=JSON %s", sqlStr)
result, err := source.RunSQL(ctx, query, nil)

Attack 1 — EXPLAIN ANALYZE execution bypass

MySQL 8.0+ treats EXPLAIN [FORMAT=JSON] ANALYZE <stmt> as an execution
primitive: the statement is actually run (with full I/O) and the measured
runtime statistics are returned. Supplying

sql_statement = "ANALYZE SELECT password FROM mysql.user WHERE user='root'"

causes the tool to issue

EXPLAIN FORMAT=JSON ANALYZE SELECT password FROM mysql.user WHERE user='root'

which MySQL executes. The actual_rows field in the returned JSON is non-zero
when the WHERE condition matches, enabling boolean-based blind extraction of
arbitrary data. Heavier variants (long SLEEP, table scans on huge tables)
yield denial-of-service.

Attack 2 — multi-statement injection via semicolons

Without semicolon filtering, a caller can append additional statements:

sql_statement = "SELECT 1; DROP TABLE orders"

Many MySQL drivers execute each semicolon-separated statement in sequence.

Fix

ValidateSQLStatement (new, exported for testing):

  1. Rejects any input containing ;.
  2. Allowlists only the DML prefixes MySQL's EXPLAIN legitimately supports:
    SELECT, INSERT, UPDATE, DELETE, REPLACE, TABLE, WITH,
    VALUES, FOR. This excludes ANALYZE, DROP, CREATE, CALL, and
    all other non-explainable forms.

13 unit tests added (happy-path DML variants + all attack variants).

Test plan

  • go build ./internal/tools/mysql/mysqlgetqueryplan/... — clean
  • go test ./internal/tools/mysql/mysqlgetqueryplan/... -run TestValidateSQLStatement -v — 13/13 PASS
  • ANALYZE payload → rejected at input validation, never reaches RunSQL
  • Semicolon payload → rejected at input validation
  • Normal SELECT queries → pass through unchanged

EXPLAIN FORMAT=JSON ANALYZE <stmt> causes MySQL 8.0+ to actually execute
the statement rather than just plan it, bypassing the read-only intent of
the tool. Any caller who can supply the sql_statement parameter could run
arbitrary queries (SELECT on privileged tables, SLEEP-based DoS, etc.) or
inject additional statements via semicolons.

Add ValidateSQLStatement to allowlist only the DML prefixes that MySQL
EXPLAIN legitimately supports (SELECT, INSERT, UPDATE, DELETE, REPLACE,
TABLE, WITH, VALUES, FOR) and reject semicolons. Add unit tests covering
both the happy path and all attack variants.
@evilgensec evilgensec requested a review from a team as a code owner May 15, 2026 06:52

@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 SQL validation layer to the MySQL query plan tool, aimed at preventing multi-statement injection and accidental query execution via the ANALYZE keyword. While the addition of validation and unit tests is a positive security improvement, the current implementation has several issues. Specifically, the FOR keyword should be removed from the allowlist as it is incompatible with the tool's hardcoded JSON output format. Additionally, the semicolon check is too broad and will trigger false positives for valid queries containing semicolons in string literals. Finally, the use of strings.Fields for tokenization is fragile, as it fails to account for valid SQL starting with comments or parentheses.

Comment thread internal/tools/mysql/mysqlgetqueryplan/mysqlgetqueryplan.go Outdated
Comment thread internal/tools/mysql/mysqlgetqueryplan/mysqlgetqueryplan.go Outdated
Comment thread internal/tools/mysql/mysqlgetqueryplan/mysqlgetqueryplan.go Outdated
Comment thread internal/tools/mysql/mysqlgetqueryplan/mysqlgetqueryplan.go Outdated
@duwenxin99 duwenxin99 changed the title security: block ANALYZE keyword and semicolons in mysql-get-query-plan fix(tool/mysql-get-query-plan): prevent query execution bypass and statement injection May 18, 2026
@duwenxin99

Copy link
Copy Markdown
Contributor

Hi @evilgensec, thanks for opening the PR!
The changes LGTM with some minor issues proposed by gemini that need to be fixed.
We should explicitly document the input validation rules introduced in this PR here so users (and LLMs) know about the keyword whitelist and the semicolon restriction upfront.
I would also suggest updating and testing the mysql-get-query-plan prebuilt tool descriptions to make sure the LLM understand the rules:

evilgensec and others added 2 commits May 19, 2026 06:13
- Remove FOR from the allowlist (EXPLAIN FOR CONNECTION does not
  support FORMAT=JSON) and from the error message.
- Replace strings.Fields/raw semicolon check with a string- and
  comment-aware scanner so leading parentheses (parenthesized UNION),
  leading comments, a single trailing semicolon, and semicolons inside
  string literals are accepted; only true multi-statement input is
  rejected.
- Document the validation rules in the tool docs and in the mysql /
  cloud-sql-mysql prebuilt tool descriptions.
- Extend unit tests for the new accepted/rejected cases.
@evilgensec evilgensec requested a review from duwenxin99 May 20, 2026 18:37
@evilgensec

Copy link
Copy Markdown
Contributor Author

@duwenxin99 Can you please review the changes

@evilgensec

Copy link
Copy Markdown
Contributor Author

@duwenxin99

@averikitsch averikitsch 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.

The current approach of manually scanning and validating SQL statements to prevent injection and unintended execution (like EXPLAIN ANALYZE) has several drawbacks:

  1. Maintenance and Complexity (Too Restrictive): Maintaining a custom parser to stay in sync with the MySQL dialect is challenging. Valid but complex syntax, such as MySQL-specific executable comments (/*! ... */) or rare DML forms, might be incorrectly rejected. This high rate of false positives can hinder legitimate use cases and create a maintenance burden as the database engine evolves.
  2. Security Gaps (Incomplete Coverage): Hand-written scanners are prone to bypasses. For instance, subtle variations in character encoding, nested comments, or specific SQL hints might evade the scanStatement logic , potentially allowing for statement injection or unauthorized query execution that the validator is designed to prevent. Relying on manual logic to secure a database interface is often less robust than using a formal grammar or a limited-privilege database user.

…of hand-written SQL validation

Address review feedback that a manual SQL scanner is the wrong mechanism:
it is both too restrictive (false positives on executable comments,
parenthesized UNION, rare DML) and bypassable (encoding, nested comments,
hints).

Verified against MySQL 8.4 and 9.7 through the Go driver that the threats
the scanner targeted are already neutralized structurally:

- Plain EXPLAIN (without ANALYZE) never executes the wrapped statement
  (SELECT/INSERT/UPDATE/DELETE all return a plan with no side effects).
- EXPLAIN ANALYZE is unreachable: the tool fixes the FORMAT=JSON prefix and
  MySQL requires ANALYZE to precede FORMAT=, so an injected ANALYZE is a
  server-side syntax error.
- Multi-statement input is rejected by the driver (multiStatements is off by
  default), so "SELECT 1; DROP TABLE t" does not execute.

Remove explainableStatements/ValidateSQLStatement/scanStatement and their
tests. Document the real security model (EXPLAIN does not execute; configure
the source with a least-privilege database user) in the tool docs and prebuilt
descriptions. Keep the evalueate -> evaluate typo fix.
@evilgensec

Copy link
Copy Markdown
Contributor Author

@averikitsch @duwenxin99 thanks for the review. I agree with the concern that a hand-written SQL scanner is the wrong mechanism — it is both too restrictive (false positives on /*! ... */ executable comments, parenthesized UNION, comment-led queries) and bypassable. I went back and verified what this tool can actually do against real servers (MySQL 8.4 and 9.7) through the Go driver, and the threats the validator targeted turn out to be neutralized structurally, not by parsing:

  1. Plain EXPLAIN never executes the wrapped statement. EXPLAIN FORMAT=JSON SELECT SLEEP(3) returns in 0s, and EXPLAIN FORMAT=JSON of DELETE/UPDATE/INSERT leaves the table unchanged. Only EXPLAIN ANALYZE executes.

  2. EXPLAIN ANALYZE is unreachable through this tool. The tool hardcodes the FORMAT=JSON prefix, and MySQL's grammar requires ANALYZE to appear before FORMAT=. So an injected ANALYZE SELECT ... lands after FORMAT=JSON and the server rejects it as a syntax error:

    EXPLAIN FORMAT=JSON ANALYZE SELECT ... -> ERROR 1064 (42000) ... near 'ANALYZE SELECT ...'
    

    This holds even on 9.7, where the correct-order EXPLAIN ANALYZE FORMAT=JSON is supported.

  3. Multi-statement input is rejected by the driver. go-sql-driver/mysql has multiStatements=false by default, so EXPLAIN FORMAT=JSON SELECT 1; DROP TABLE t returns ERROR 1064 and the table survives.

Given that, and that the sibling tools (mysql-execute-sql, mysql-sql) pass user SQL straight through and rely on the database's privileges, I've removed the ValidateSQLStatement/scanStatement scanner and its tests. In its place the PR now documents the actual security model — EXPLAIN does not execute, and the recommended control is configuring the source with a least-privilege database user (with a note to avoid enabling the driver's multi-statement option). The evalueate -> evaluate typo fix and the prebuilt description cleanup are kept.

Net change is −125 LOC. Build, go vet, package tests, and the prebuiltconfigs tests are green. Happy to go the formal-parser route instead if you'd prefer in-code enforcement over the privilege model, but given the above I think relying on least-privilege is the cleaner fit for this tool.

@evilgensec evilgensec requested a review from averikitsch June 11, 2026 01:03
@evilgensec

Copy link
Copy Markdown
Contributor Author

Hi Team, anything else needed to merge?

@averikitsch averikitsch added the tests: run Label to trigger Github Action tests. label Jun 15, 2026
@averikitsch

Copy link
Copy Markdown
Contributor

/gcbrun

@averikitsch averikitsch enabled auto-merge (squash) June 15, 2026 18:07
@github-actions github-actions Bot removed the tests: run Label to trigger Github Action tests. label Jun 15, 2026
Comment thread docs/en/integrations/mysql/tools/mysql-get-query-plan.md Outdated
@averikitsch averikitsch added the tests: run Label to trigger Github Action tests. label Jun 15, 2026
@averikitsch

Copy link
Copy Markdown
Contributor

/gcbrun

@github-actions github-actions Bot removed the tests: run Label to trigger Github Action tests. label Jun 15, 2026
@averikitsch averikitsch dismissed duwenxin99’s stale review June 15, 2026 18:31

reviewed by Averi

@averikitsch averikitsch merged commit 7ed1e7b into googleapis:main Jun 15, 2026
33 checks passed
github-actions Bot pushed a commit that referenced this pull request Jun 15, 2026
…s and statement injection (#3235)

## Summary

`mysql-get-query-plan` builds its EXPLAIN query by directly
interpolating the
caller-supplied `sql_statement` into `EXPLAIN FORMAT=JSON %s` with no
validation:

```go
// internal/tools/mysql/mysqlgetqueryplan/mysqlgetqueryplan.go:118
query := fmt.Sprintf("EXPLAIN FORMAT=JSON %s", sqlStr)
result, err := source.RunSQL(ctx, query, nil)
```

### Attack 1 — EXPLAIN ANALYZE execution bypass

MySQL 8.0+ treats `EXPLAIN [FORMAT=JSON] ANALYZE <stmt>` as an
**execution**
primitive: the statement is actually run (with full I/O) and the
measured
runtime statistics are returned. Supplying

```
sql_statement = "ANALYZE SELECT password FROM mysql.user WHERE user='root'"
```

causes the tool to issue

```sql
EXPLAIN FORMAT=JSON ANALYZE SELECT password FROM mysql.user WHERE user='root'
```

which MySQL executes. The `actual_rows` field in the returned JSON is
non-zero
when the WHERE condition matches, enabling boolean-based blind
extraction of
arbitrary data. Heavier variants (long `SLEEP`, table scans on huge
tables)
yield denial-of-service.

### Attack 2 — multi-statement injection via semicolons

Without semicolon filtering, a caller can append additional statements:

```
sql_statement = "SELECT 1; DROP TABLE orders"
```

Many MySQL drivers execute each semicolon-separated statement in
sequence.

## Fix

`ValidateSQLStatement` (new, exported for testing):

1. Rejects any input containing `;`.
2. Allowlists only the DML prefixes MySQL's EXPLAIN legitimately
supports:
   `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `REPLACE`, `TABLE`, `WITH`,
`VALUES`, `FOR`. This excludes `ANALYZE`, `DROP`, `CREATE`, `CALL`, and
   all other non-explainable forms.

13 unit tests added (happy-path DML variants + all attack variants).

## Test plan

- [x] `go build ./internal/tools/mysql/mysqlgetqueryplan/...` — clean
- [x] `go test ./internal/tools/mysql/mysqlgetqueryplan/... -run
TestValidateSQLStatement -v` — 13/13 PASS
- [x] `ANALYZE` payload → rejected at input validation, never reaches
`RunSQL`
- [x] Semicolon payload → rejected at input validation
- [x] Normal `SELECT` queries → pass through unchanged

---------

Co-authored-by: evilgensec <[email protected]>
Co-authored-by: Averi Kitsch <[email protected]> 7ed1e7b
github-actions Bot pushed a commit to renovate-bot/googleapis-_-genai-toolbox that referenced this pull request Jun 15, 2026
…s and statement injection (googleapis#3235)

## Summary

`mysql-get-query-plan` builds its EXPLAIN query by directly
interpolating the
caller-supplied `sql_statement` into `EXPLAIN FORMAT=JSON %s` with no
validation:

```go
// internal/tools/mysql/mysqlgetqueryplan/mysqlgetqueryplan.go:118
query := fmt.Sprintf("EXPLAIN FORMAT=JSON %s", sqlStr)
result, err := source.RunSQL(ctx, query, nil)
```

### Attack 1 — EXPLAIN ANALYZE execution bypass

MySQL 8.0+ treats `EXPLAIN [FORMAT=JSON] ANALYZE <stmt>` as an
**execution**
primitive: the statement is actually run (with full I/O) and the
measured
runtime statistics are returned. Supplying

```
sql_statement = "ANALYZE SELECT password FROM mysql.user WHERE user='root'"
```

causes the tool to issue

```sql
EXPLAIN FORMAT=JSON ANALYZE SELECT password FROM mysql.user WHERE user='root'
```

which MySQL executes. The `actual_rows` field in the returned JSON is
non-zero
when the WHERE condition matches, enabling boolean-based blind
extraction of
arbitrary data. Heavier variants (long `SLEEP`, table scans on huge
tables)
yield denial-of-service.

### Attack 2 — multi-statement injection via semicolons

Without semicolon filtering, a caller can append additional statements:

```
sql_statement = "SELECT 1; DROP TABLE orders"
```

Many MySQL drivers execute each semicolon-separated statement in
sequence.

## Fix

`ValidateSQLStatement` (new, exported for testing):

1. Rejects any input containing `;`.
2. Allowlists only the DML prefixes MySQL's EXPLAIN legitimately
supports:
   `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `REPLACE`, `TABLE`, `WITH`,
`VALUES`, `FOR`. This excludes `ANALYZE`, `DROP`, `CREATE`, `CALL`, and
   all other non-explainable forms.

13 unit tests added (happy-path DML variants + all attack variants).

## Test plan

- [x] `go build ./internal/tools/mysql/mysqlgetqueryplan/...` — clean
- [x] `go test ./internal/tools/mysql/mysqlgetqueryplan/... -run
TestValidateSQLStatement -v` — 13/13 PASS
- [x] `ANALYZE` payload → rejected at input validation, never reaches
`RunSQL`
- [x] Semicolon payload → rejected at input validation
- [x] Normal `SELECT` queries → pass through unchanged

---------

Co-authored-by: evilgensec <[email protected]>
Co-authored-by: Averi Kitsch <[email protected]> 7ed1e7b
Yuan325 added a commit that referenced this pull request Jun 18, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.5.0](v1.4.0...v1.5.0)
(2026-06-18)


### Features

* **auth/google:** Require audience or clientId for mcpEnabled
([#3450](#3450))
([59f7b6e](59f7b6e))
* Enable per source level flags for sql commenter
([#3465](#3465))
([ecce6b7](ecce6b7))
* **mcp:** Add URL parameter binding for HTTP transport
([#3112](#3112))
([0cc7b37](0cc7b37))
* **scylladb:** Adding support for ScyllaDB source and tool
([#3119](#3119))
([2dada83](2dada83))
* **server:** Add support for toolset filtering in prebuilt CLI flag
([#3245](#3245))
([7cc4f65](7cc4f65))
* **skills:** Generate skills offline without live source connections
([#3388](#3388))
([4c860b6](4c860b6))
* **skills:** Tolerate missing env vars during offline skills-generate
([#3399](#3399))
([ea5d3e5](ea5d3e5))
* **source/cloud-storage:** Restrict bucket and local path access
([#3454](#3454))
([2c3ca5d](2c3ca5d))
* **tools/bigquery:** Add per tool query label in BigQuery jobs
([#1975](#1975))
([3f6a49f](3f6a49f))
* **tools/dataplex:** Add tools to support metadata enrichment workflow
([#3270](#3270))
([05289aa](05289aa))
* **tools/mysql:** Add show-query-stats and list-all-locks tools for
MySQL and Cloud SQL MySQL source
([#2954](#2954))
([a9693bd](a9693bd))
* **tools:** Decouple tool initialization from sources
([#3355](#3355))
([32a24e3](32a24e3))


### Bug Fixes

* **auth/dataplex:** Fix failing source with service account credentials
([#3369](#3369))
([ba4deef](ba4deef))
* **bigquery:** Wire maximumBytesBilled into prebuilt config
([#3385](#3385))
([4abbf6e](4abbf6e))
* Bound MCP HTTP body size
([#3216](#3216))
([d4f4342](d4f4342))
* **config:** Add doc/line context to parse errors
([#2957](#2957))
([4b097da](4b097da))
* Escape delimiter characters in applyEscape to prevent SQL injection
([#2811](#2811))
([932519a](932519a))
* **npm:** Source binary version from cmd/version.txt
([#3417](#3417))
([6ffbdec](6ffbdec))
* **prebuilt/alloydb-omni:** Require password env var explicitly
([#3398](#3398))
([fcbe3e7](fcbe3e7))
* **server:** Fail if MCP auth is enabled together with enable-api
([#3435](#3435))
([a6ff910](a6ff910))
* **server:** Return errors instead of panicking in InitializeConfigs
([#3397](#3397))
([f48b01d](f48b01d))
* **source/cloudhealthcare:** Validate pageURL parameter to prevent SSRF
([#3453](#3453))
([9abf47d](9abf47d))
* **source/dataplex,source/datalineage:** Specify cloud-platform scope
for default credentials
([#3376](#3376))
([13e8c36](13e8c36))
* **source/http:** Implement SSRF guard
([#3448](#3448))
([24d7d29](24d7d29))
* **tool/bigquery-execute-sql:** Prevent dataset restriction bypass
([#3452](#3452))
([ca6d5e3](ca6d5e3))
* **tool/mysql-get-query-plan:** Prevent query execution bypass and
statement injection
([#3235](#3235))
([7ed1e7b](7ed1e7b))
* **tool/spanner-sql,tool/spanner-execute-sql:** Use read-only
annotations when readOnly is set
([#3338](#3338))
([8bde0ec](8bde0ec))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Co-authored-by: Yuan Teoh <[email protected]>
github-actions Bot pushed a commit that referenced this pull request Jun 18, 2026
🤖 I have created a release *beep* *boop*
---

##
[1.5.0](v1.4.0...v1.5.0)
(2026-06-18)

### Features

* **auth/google:** Require audience or clientId for mcpEnabled
([#3450](#3450))
([59f7b6e](59f7b6e))
* Enable per source level flags for sql commenter
([#3465](#3465))
([ecce6b7](ecce6b7))
* **mcp:** Add URL parameter binding for HTTP transport
([#3112](#3112))
([0cc7b37](0cc7b37))
* **scylladb:** Adding support for ScyllaDB source and tool
([#3119](#3119))
([2dada83](2dada83))
* **server:** Add support for toolset filtering in prebuilt CLI flag
([#3245](#3245))
([7cc4f65](7cc4f65))
* **skills:** Generate skills offline without live source connections
([#3388](#3388))
([4c860b6](4c860b6))
* **skills:** Tolerate missing env vars during offline skills-generate
([#3399](#3399))
([ea5d3e5](ea5d3e5))
* **source/cloud-storage:** Restrict bucket and local path access
([#3454](#3454))
([2c3ca5d](2c3ca5d))
* **tools/bigquery:** Add per tool query label in BigQuery jobs
([#1975](#1975))
([3f6a49f](3f6a49f))
* **tools/dataplex:** Add tools to support metadata enrichment workflow
([#3270](#3270))
([05289aa](05289aa))
* **tools/mysql:** Add show-query-stats and list-all-locks tools for
MySQL and Cloud SQL MySQL source
([#2954](#2954))
([a9693bd](a9693bd))
* **tools:** Decouple tool initialization from sources
([#3355](#3355))
([32a24e3](32a24e3))

### Bug Fixes

* **auth/dataplex:** Fix failing source with service account credentials
([#3369](#3369))
([ba4deef](ba4deef))
* **bigquery:** Wire maximumBytesBilled into prebuilt config
([#3385](#3385))
([4abbf6e](4abbf6e))
* Bound MCP HTTP body size
([#3216](#3216))
([d4f4342](d4f4342))
* **config:** Add doc/line context to parse errors
([#2957](#2957))
([4b097da](4b097da))
* Escape delimiter characters in applyEscape to prevent SQL injection
([#2811](#2811))
([932519a](932519a))
* **npm:** Source binary version from cmd/version.txt
([#3417](#3417))
([6ffbdec](6ffbdec))
* **prebuilt/alloydb-omni:** Require password env var explicitly
([#3398](#3398))
([fcbe3e7](fcbe3e7))
* **server:** Fail if MCP auth is enabled together with enable-api
([#3435](#3435))
([a6ff910](a6ff910))
* **server:** Return errors instead of panicking in InitializeConfigs
([#3397](#3397))
([f48b01d](f48b01d))
* **source/cloudhealthcare:** Validate pageURL parameter to prevent SSRF
([#3453](#3453))
([9abf47d](9abf47d))
* **source/dataplex,source/datalineage:** Specify cloud-platform scope
for default credentials
([#3376](#3376))
([13e8c36](13e8c36))
* **source/http:** Implement SSRF guard
([#3448](#3448))
([24d7d29](24d7d29))
* **tool/bigquery-execute-sql:** Prevent dataset restriction bypass
([#3452](#3452))
([ca6d5e3](ca6d5e3))
* **tool/mysql-get-query-plan:** Prevent query execution bypass and
statement injection
([#3235](#3235))
([7ed1e7b](7ed1e7b))
* **tool/spanner-sql,tool/spanner-execute-sql:** Use read-only
annotations when readOnly is set
([#3338](#3338))
([8bde0ec](8bde0ec))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Co-authored-by: Yuan Teoh <[email protected]> 45c0f86
github-actions Bot pushed a commit to renovate-bot/googleapis-_-genai-toolbox that referenced this pull request Jun 18, 2026
🤖 I have created a release *beep* *boop*
---

##
[1.5.0](googleapis/mcp-toolbox@v1.4.0...v1.5.0)
(2026-06-18)

### Features

* **auth/google:** Require audience or clientId for mcpEnabled
([googleapis#3450](googleapis#3450))
([59f7b6e](googleapis@59f7b6e))
* Enable per source level flags for sql commenter
([googleapis#3465](googleapis#3465))
([ecce6b7](googleapis@ecce6b7))
* **mcp:** Add URL parameter binding for HTTP transport
([googleapis#3112](googleapis#3112))
([0cc7b37](googleapis@0cc7b37))
* **scylladb:** Adding support for ScyllaDB source and tool
([googleapis#3119](googleapis#3119))
([2dada83](googleapis@2dada83))
* **server:** Add support for toolset filtering in prebuilt CLI flag
([googleapis#3245](googleapis#3245))
([7cc4f65](googleapis@7cc4f65))
* **skills:** Generate skills offline without live source connections
([googleapis#3388](googleapis#3388))
([4c860b6](googleapis@4c860b6))
* **skills:** Tolerate missing env vars during offline skills-generate
([googleapis#3399](googleapis#3399))
([ea5d3e5](googleapis@ea5d3e5))
* **source/cloud-storage:** Restrict bucket and local path access
([googleapis#3454](googleapis#3454))
([2c3ca5d](googleapis@2c3ca5d))
* **tools/bigquery:** Add per tool query label in BigQuery jobs
([googleapis#1975](googleapis#1975))
([3f6a49f](googleapis@3f6a49f))
* **tools/dataplex:** Add tools to support metadata enrichment workflow
([googleapis#3270](googleapis#3270))
([05289aa](googleapis@05289aa))
* **tools/mysql:** Add show-query-stats and list-all-locks tools for
MySQL and Cloud SQL MySQL source
([googleapis#2954](googleapis#2954))
([a9693bd](googleapis@a9693bd))
* **tools:** Decouple tool initialization from sources
([googleapis#3355](googleapis#3355))
([32a24e3](googleapis@32a24e3))

### Bug Fixes

* **auth/dataplex:** Fix failing source with service account credentials
([googleapis#3369](googleapis#3369))
([ba4deef](googleapis@ba4deef))
* **bigquery:** Wire maximumBytesBilled into prebuilt config
([googleapis#3385](googleapis#3385))
([4abbf6e](googleapis@4abbf6e))
* Bound MCP HTTP body size
([googleapis#3216](googleapis#3216))
([d4f4342](googleapis@d4f4342))
* **config:** Add doc/line context to parse errors
([googleapis#2957](googleapis#2957))
([4b097da](googleapis@4b097da))
* Escape delimiter characters in applyEscape to prevent SQL injection
([googleapis#2811](googleapis#2811))
([932519a](googleapis@932519a))
* **npm:** Source binary version from cmd/version.txt
([googleapis#3417](googleapis#3417))
([6ffbdec](googleapis@6ffbdec))
* **prebuilt/alloydb-omni:** Require password env var explicitly
([googleapis#3398](googleapis#3398))
([fcbe3e7](googleapis@fcbe3e7))
* **server:** Fail if MCP auth is enabled together with enable-api
([googleapis#3435](googleapis#3435))
([a6ff910](googleapis@a6ff910))
* **server:** Return errors instead of panicking in InitializeConfigs
([googleapis#3397](googleapis#3397))
([f48b01d](googleapis@f48b01d))
* **source/cloudhealthcare:** Validate pageURL parameter to prevent SSRF
([googleapis#3453](googleapis#3453))
([9abf47d](googleapis@9abf47d))
* **source/dataplex,source/datalineage:** Specify cloud-platform scope
for default credentials
([googleapis#3376](googleapis#3376))
([13e8c36](googleapis@13e8c36))
* **source/http:** Implement SSRF guard
([googleapis#3448](googleapis#3448))
([24d7d29](googleapis@24d7d29))
* **tool/bigquery-execute-sql:** Prevent dataset restriction bypass
([googleapis#3452](googleapis#3452))
([ca6d5e3](googleapis@ca6d5e3))
* **tool/mysql-get-query-plan:** Prevent query execution bypass and
statement injection
([googleapis#3235](googleapis#3235))
([7ed1e7b](googleapis@7ed1e7b))
* **tool/spanner-sql,tool/spanner-execute-sql:** Use read-only
annotations when readOnly is set
([googleapis#3338](googleapis#3338))
([8bde0ec](googleapis@8bde0ec))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Co-authored-by: Yuan Teoh <[email protected]> 45c0f86
github-actions Bot pushed a commit to rodineyw/mcp-toolbox that referenced this pull request Jun 19, 2026
🤖 I have created a release *beep* *boop*
---

##
[1.5.0](googleapis/mcp-toolbox@v1.4.0...v1.5.0)
(2026-06-18)

### Features

* **auth/google:** Require audience or clientId for mcpEnabled
([googleapis#3450](googleapis#3450))
([59f7b6e](googleapis@59f7b6e))
* Enable per source level flags for sql commenter
([googleapis#3465](googleapis#3465))
([ecce6b7](googleapis@ecce6b7))
* **mcp:** Add URL parameter binding for HTTP transport
([googleapis#3112](googleapis#3112))
([0cc7b37](googleapis@0cc7b37))
* **scylladb:** Adding support for ScyllaDB source and tool
([googleapis#3119](googleapis#3119))
([2dada83](googleapis@2dada83))
* **server:** Add support for toolset filtering in prebuilt CLI flag
([googleapis#3245](googleapis#3245))
([7cc4f65](googleapis@7cc4f65))
* **skills:** Generate skills offline without live source connections
([googleapis#3388](googleapis#3388))
([4c860b6](googleapis@4c860b6))
* **skills:** Tolerate missing env vars during offline skills-generate
([googleapis#3399](googleapis#3399))
([ea5d3e5](googleapis@ea5d3e5))
* **source/cloud-storage:** Restrict bucket and local path access
([googleapis#3454](googleapis#3454))
([2c3ca5d](googleapis@2c3ca5d))
* **tools/bigquery:** Add per tool query label in BigQuery jobs
([googleapis#1975](googleapis#1975))
([3f6a49f](googleapis@3f6a49f))
* **tools/dataplex:** Add tools to support metadata enrichment workflow
([googleapis#3270](googleapis#3270))
([05289aa](googleapis@05289aa))
* **tools/mysql:** Add show-query-stats and list-all-locks tools for
MySQL and Cloud SQL MySQL source
([googleapis#2954](googleapis#2954))
([a9693bd](googleapis@a9693bd))
* **tools:** Decouple tool initialization from sources
([googleapis#3355](googleapis#3355))
([32a24e3](googleapis@32a24e3))

### Bug Fixes

* **auth/dataplex:** Fix failing source with service account credentials
([googleapis#3369](googleapis#3369))
([ba4deef](googleapis@ba4deef))
* **bigquery:** Wire maximumBytesBilled into prebuilt config
([googleapis#3385](googleapis#3385))
([4abbf6e](googleapis@4abbf6e))
* Bound MCP HTTP body size
([googleapis#3216](googleapis#3216))
([d4f4342](googleapis@d4f4342))
* **config:** Add doc/line context to parse errors
([googleapis#2957](googleapis#2957))
([4b097da](googleapis@4b097da))
* Escape delimiter characters in applyEscape to prevent SQL injection
([googleapis#2811](googleapis#2811))
([932519a](googleapis@932519a))
* **npm:** Source binary version from cmd/version.txt
([googleapis#3417](googleapis#3417))
([6ffbdec](googleapis@6ffbdec))
* **prebuilt/alloydb-omni:** Require password env var explicitly
([googleapis#3398](googleapis#3398))
([fcbe3e7](googleapis@fcbe3e7))
* **server:** Fail if MCP auth is enabled together with enable-api
([googleapis#3435](googleapis#3435))
([a6ff910](googleapis@a6ff910))
* **server:** Return errors instead of panicking in InitializeConfigs
([googleapis#3397](googleapis#3397))
([f48b01d](googleapis@f48b01d))
* **source/cloudhealthcare:** Validate pageURL parameter to prevent SSRF
([googleapis#3453](googleapis#3453))
([9abf47d](googleapis@9abf47d))
* **source/dataplex,source/datalineage:** Specify cloud-platform scope
for default credentials
([googleapis#3376](googleapis#3376))
([13e8c36](googleapis@13e8c36))
* **source/http:** Implement SSRF guard
([googleapis#3448](googleapis#3448))
([24d7d29](googleapis@24d7d29))
* **tool/bigquery-execute-sql:** Prevent dataset restriction bypass
([googleapis#3452](googleapis#3452))
([ca6d5e3](googleapis@ca6d5e3))
* **tool/mysql-get-query-plan:** Prevent query execution bypass and
statement injection
([googleapis#3235](googleapis#3235))
([7ed1e7b](googleapis@7ed1e7b))
* **tool/spanner-sql,tool/spanner-execute-sql:** Use read-only
annotations when readOnly is set
([googleapis#3338](googleapis#3338))
([8bde0ec](googleapis@8bde0ec))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Co-authored-by: Yuan Teoh <[email protected]> 45c0f86
github-actions Bot pushed a commit to Jaleel-zhu/genai-toolbox that referenced this pull request Jun 19, 2026
🤖 I have created a release *beep* *boop*
---

##
[1.5.0](googleapis/mcp-toolbox@v1.4.0...v1.5.0)
(2026-06-18)

### Features

* **auth/google:** Require audience or clientId for mcpEnabled
([googleapis#3450](googleapis#3450))
([59f7b6e](googleapis@59f7b6e))
* Enable per source level flags for sql commenter
([googleapis#3465](googleapis#3465))
([ecce6b7](googleapis@ecce6b7))
* **mcp:** Add URL parameter binding for HTTP transport
([googleapis#3112](googleapis#3112))
([0cc7b37](googleapis@0cc7b37))
* **scylladb:** Adding support for ScyllaDB source and tool
([googleapis#3119](googleapis#3119))
([2dada83](googleapis@2dada83))
* **server:** Add support for toolset filtering in prebuilt CLI flag
([googleapis#3245](googleapis#3245))
([7cc4f65](googleapis@7cc4f65))
* **skills:** Generate skills offline without live source connections
([googleapis#3388](googleapis#3388))
([4c860b6](googleapis@4c860b6))
* **skills:** Tolerate missing env vars during offline skills-generate
([googleapis#3399](googleapis#3399))
([ea5d3e5](googleapis@ea5d3e5))
* **source/cloud-storage:** Restrict bucket and local path access
([googleapis#3454](googleapis#3454))
([2c3ca5d](googleapis@2c3ca5d))
* **tools/bigquery:** Add per tool query label in BigQuery jobs
([googleapis#1975](googleapis#1975))
([3f6a49f](googleapis@3f6a49f))
* **tools/dataplex:** Add tools to support metadata enrichment workflow
([googleapis#3270](googleapis#3270))
([05289aa](googleapis@05289aa))
* **tools/mysql:** Add show-query-stats and list-all-locks tools for
MySQL and Cloud SQL MySQL source
([googleapis#2954](googleapis#2954))
([a9693bd](googleapis@a9693bd))
* **tools:** Decouple tool initialization from sources
([googleapis#3355](googleapis#3355))
([32a24e3](googleapis@32a24e3))

### Bug Fixes

* **auth/dataplex:** Fix failing source with service account credentials
([googleapis#3369](googleapis#3369))
([ba4deef](googleapis@ba4deef))
* **bigquery:** Wire maximumBytesBilled into prebuilt config
([googleapis#3385](googleapis#3385))
([4abbf6e](googleapis@4abbf6e))
* Bound MCP HTTP body size
([googleapis#3216](googleapis#3216))
([d4f4342](googleapis@d4f4342))
* **config:** Add doc/line context to parse errors
([googleapis#2957](googleapis#2957))
([4b097da](googleapis@4b097da))
* Escape delimiter characters in applyEscape to prevent SQL injection
([googleapis#2811](googleapis#2811))
([932519a](googleapis@932519a))
* **npm:** Source binary version from cmd/version.txt
([googleapis#3417](googleapis#3417))
([6ffbdec](googleapis@6ffbdec))
* **prebuilt/alloydb-omni:** Require password env var explicitly
([googleapis#3398](googleapis#3398))
([fcbe3e7](googleapis@fcbe3e7))
* **server:** Fail if MCP auth is enabled together with enable-api
([googleapis#3435](googleapis#3435))
([a6ff910](googleapis@a6ff910))
* **server:** Return errors instead of panicking in InitializeConfigs
([googleapis#3397](googleapis#3397))
([f48b01d](googleapis@f48b01d))
* **source/cloudhealthcare:** Validate pageURL parameter to prevent SSRF
([googleapis#3453](googleapis#3453))
([9abf47d](googleapis@9abf47d))
* **source/dataplex,source/datalineage:** Specify cloud-platform scope
for default credentials
([googleapis#3376](googleapis#3376))
([13e8c36](googleapis@13e8c36))
* **source/http:** Implement SSRF guard
([googleapis#3448](googleapis#3448))
([24d7d29](googleapis@24d7d29))
* **tool/bigquery-execute-sql:** Prevent dataset restriction bypass
([googleapis#3452](googleapis#3452))
([ca6d5e3](googleapis@ca6d5e3))
* **tool/mysql-get-query-plan:** Prevent query execution bypass and
statement injection
([googleapis#3235](googleapis#3235))
([7ed1e7b](googleapis@7ed1e7b))
* **tool/spanner-sql,tool/spanner-execute-sql:** Use read-only
annotations when readOnly is set
([googleapis#3338](googleapis#3338))
([8bde0ec](googleapis@8bde0ec))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Co-authored-by: Yuan Teoh <[email protected]> 45c0f86
github-actions Bot pushed a commit to pepe57/genai-toolbox that referenced this pull request Jun 19, 2026
🤖 I have created a release *beep* *boop*
---

##
[1.5.0](googleapis/mcp-toolbox@v1.4.0...v1.5.0)
(2026-06-18)

### Features

* **auth/google:** Require audience or clientId for mcpEnabled
([googleapis#3450](googleapis#3450))
([59f7b6e](googleapis@59f7b6e))
* Enable per source level flags for sql commenter
([googleapis#3465](googleapis#3465))
([ecce6b7](googleapis@ecce6b7))
* **mcp:** Add URL parameter binding for HTTP transport
([googleapis#3112](googleapis#3112))
([0cc7b37](googleapis@0cc7b37))
* **scylladb:** Adding support for ScyllaDB source and tool
([googleapis#3119](googleapis#3119))
([2dada83](googleapis@2dada83))
* **server:** Add support for toolset filtering in prebuilt CLI flag
([googleapis#3245](googleapis#3245))
([7cc4f65](googleapis@7cc4f65))
* **skills:** Generate skills offline without live source connections
([googleapis#3388](googleapis#3388))
([4c860b6](googleapis@4c860b6))
* **skills:** Tolerate missing env vars during offline skills-generate
([googleapis#3399](googleapis#3399))
([ea5d3e5](googleapis@ea5d3e5))
* **source/cloud-storage:** Restrict bucket and local path access
([googleapis#3454](googleapis#3454))
([2c3ca5d](googleapis@2c3ca5d))
* **tools/bigquery:** Add per tool query label in BigQuery jobs
([googleapis#1975](googleapis#1975))
([3f6a49f](googleapis@3f6a49f))
* **tools/dataplex:** Add tools to support metadata enrichment workflow
([googleapis#3270](googleapis#3270))
([05289aa](googleapis@05289aa))
* **tools/mysql:** Add show-query-stats and list-all-locks tools for
MySQL and Cloud SQL MySQL source
([googleapis#2954](googleapis#2954))
([a9693bd](googleapis@a9693bd))
* **tools:** Decouple tool initialization from sources
([googleapis#3355](googleapis#3355))
([32a24e3](googleapis@32a24e3))

### Bug Fixes

* **auth/dataplex:** Fix failing source with service account credentials
([googleapis#3369](googleapis#3369))
([ba4deef](googleapis@ba4deef))
* **bigquery:** Wire maximumBytesBilled into prebuilt config
([googleapis#3385](googleapis#3385))
([4abbf6e](googleapis@4abbf6e))
* Bound MCP HTTP body size
([googleapis#3216](googleapis#3216))
([d4f4342](googleapis@d4f4342))
* **config:** Add doc/line context to parse errors
([googleapis#2957](googleapis#2957))
([4b097da](googleapis@4b097da))
* Escape delimiter characters in applyEscape to prevent SQL injection
([googleapis#2811](googleapis#2811))
([932519a](googleapis@932519a))
* **npm:** Source binary version from cmd/version.txt
([googleapis#3417](googleapis#3417))
([6ffbdec](googleapis@6ffbdec))
* **prebuilt/alloydb-omni:** Require password env var explicitly
([googleapis#3398](googleapis#3398))
([fcbe3e7](googleapis@fcbe3e7))
* **server:** Fail if MCP auth is enabled together with enable-api
([googleapis#3435](googleapis#3435))
([a6ff910](googleapis@a6ff910))
* **server:** Return errors instead of panicking in InitializeConfigs
([googleapis#3397](googleapis#3397))
([f48b01d](googleapis@f48b01d))
* **source/cloudhealthcare:** Validate pageURL parameter to prevent SSRF
([googleapis#3453](googleapis#3453))
([9abf47d](googleapis@9abf47d))
* **source/dataplex,source/datalineage:** Specify cloud-platform scope
for default credentials
([googleapis#3376](googleapis#3376))
([13e8c36](googleapis@13e8c36))
* **source/http:** Implement SSRF guard
([googleapis#3448](googleapis#3448))
([24d7d29](googleapis@24d7d29))
* **tool/bigquery-execute-sql:** Prevent dataset restriction bypass
([googleapis#3452](googleapis#3452))
([ca6d5e3](googleapis@ca6d5e3))
* **tool/mysql-get-query-plan:** Prevent query execution bypass and
statement injection
([googleapis#3235](googleapis#3235))
([7ed1e7b](googleapis@7ed1e7b))
* **tool/spanner-sql,tool/spanner-execute-sql:** Use read-only
annotations when readOnly is set
([googleapis#3338](googleapis#3338))
([8bde0ec](googleapis@8bde0ec))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Co-authored-by: Yuan Teoh <[email protected]> 45c0f86
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.

3 participants