@yanzhang123/readonly-db-mcp 0.9.7 → 0.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ENTERPRISE_DEPLOYMENT.md
CHANGED
|
@@ -160,8 +160,14 @@ on unmatched started events and preserve them during incident review.
|
|
|
160
160
|
|
|
161
161
|
Result masking is a final egress control, not an authorization boundary. Source
|
|
162
162
|
columns matching `mask_columns` are redacted through aliases, expressions,
|
|
163
|
-
|
|
164
|
-
|
|
163
|
+
conversions, window functions, subqueries, derived tables, CTEs, set operations,
|
|
164
|
+
JSON_TABLE, TABLE statements and stars. It is designed to fail closed: an output
|
|
165
|
+
whose source cannot be determined is masked when it could come from a matching
|
|
166
|
+
field, so complex queries may show extra redactions. Static analysis cannot see
|
|
167
|
+
view definitions, stored-function bodies or real schemas, and cannot rule out
|
|
168
|
+
SQL shapes it does not yet model. Bare
|
|
169
|
+
patterns match only field names; qualified patterns retain their scope, resolve
|
|
170
|
+
table aliases, and use the selected database for unqualified tables.
|
|
165
171
|
COUNT statistics remain available without exposing their input values. Masking
|
|
166
172
|
is disabled by default: omitted or empty `mask_columns` returns all field values
|
|
167
173
|
without redaction. Configure the fields to mask per connection; there is no
|
package/README.md
CHANGED
|
@@ -98,7 +98,11 @@ mask_columns = [] # 默认全部放开;省略此项效果相同。
|
|
|
98
98
|
|
|
99
99
|
旧单连接模式通过 `MYSQL_MASK_COLUMNS` 配置,以逗号分隔;未设置或设为空字符串均不脱敏。例如 `MYSQL_MASK_COLUMNS=password,access_token` 只按这两个规则处理。使用命名连接文件时,以各连接自己的 `mask_columns` 为准。
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
显式配置会把每个结果列追溯到底层表的字段:别名、表达式、函数与类型转换、窗口函数、标量子查询与关联子查询、派生表、CTE(含列清单)、`UNION`、`LATERAL`、`JSON_TABLE`、`TABLE` 语句和 `*` 都会继续追踪,并对 JSON 内匹配的键递归处理。派生表或 CTE 中名称匹配规则的列也视为敏感来源;只有最外层的别名不算。不带点的模式只匹配字段名,例如 `password`;带点的模式按限定路径匹配,例如 `users.phone` 或 `app.users.phone`,表别名会解析回真实表名,未写库名的表按当前库匹配。`COUNT` / `COUNT(DISTINCT ...)` 统计值可以正常读取,同一查询中匹配规则的原始值和拼接值仍会隐藏;`WHERE`、`HAVING`、`EXISTS`、`IN` 子查询里的值不会出现在结果中,不会让其他列被遮蔽。
|
|
102
|
+
|
|
103
|
+
脱敏按 fail-closed 设计:某个结果列的来源无法确定时(例如无法解析的列名、子查询中可能来自外层查询的列,或 MySQL 自动生成、与表达式文本对不上的列名),只要它可能来自匹配规则的字段,就按敏感处理;SQL 分析失败时同样按保守规则处理。因此少数复杂查询可能多遮几列。
|
|
104
|
+
|
|
105
|
+
脱敏是结果出口的辅助控制,不是访问授权边界:它基于 SQL 静态分析,无法看到视图定义、存储函数内部或数据库中实际的表结构,也不能排除尚未覆盖的 SQL 写法。绝不能暴露的字段,应在数据库层用只包含安全字段的视图或列级权限隔离,再让本服务使用该账号。
|
|
102
106
|
|
|
103
107
|
脱敏只替换返回值,不改变 MySQL 的 `WHERE` / `JOIN` 条件或删除结果行。`[REDACTED]` 表示值被隐藏,JSON/compact 的 `masked_columns` 可定位受影响列。已有的非空配置仍会生效;需要全部放开时,把它改成空列表(单连接模式清空环境变量),或删除该配置项。
|
|
104
108
|
|
package/SECURITY.md
CHANGED
|
@@ -161,13 +161,28 @@ The MCP server includes built-in protection against SQL injection for administra
|
|
|
161
161
|
- Result masking is opt-in: `mask_columns` defaults to an empty list, and legacy
|
|
162
162
|
`MYSQL_MASK_COLUMNS` defaults to empty. There is no built-in sensitive-field list;
|
|
163
163
|
omitted or empty rules return all field values without redaction, including JSON
|
|
164
|
-
keys. When rules are configured,
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
164
|
+
keys. When rules are configured, each result column is traced through aliases,
|
|
165
|
+
expressions and conversions, window functions, scalar and correlated
|
|
166
|
+
subqueries, derived tables, CTEs (including column lists), set operations,
|
|
167
|
+
LATERAL, JSON_TABLE, TABLE statements and stars to base-table columns, and
|
|
168
|
+
matching sources and JSON keys are replaced with `[REDACTED]`. Columns of derived
|
|
169
|
+
tables and CTEs whose names match are sensitive sources too; only final output
|
|
170
|
+
aliases are exempt. Unqualified patterns match only field names; qualified
|
|
171
|
+
patterns retain table/database scope, resolve table aliases, and apply the
|
|
172
|
+
selected database to tables named without one. COUNT statistics do not inherit
|
|
173
|
+
masking from their inputs, while matching raw values and combined expressions
|
|
174
|
+
remain masked. Values from WHERE, HAVING, EXISTS and IN subqueries never reach
|
|
175
|
+
the result and do not mask other columns.
|
|
176
|
+
- Masking is designed to fail closed: a result column whose source cannot be
|
|
177
|
+
determined (including unqualified names a subquery may resolve in the outer
|
|
178
|
+
query) is treated as sensitive if it could come from a matching field, and
|
|
179
|
+
analysis failures fall back to conservative rules. Some complex queries may
|
|
180
|
+
therefore show extra `[REDACTED]` columns.
|
|
181
|
+
- Masking is a static-analysis egress control, not an authorization boundary. It
|
|
182
|
+
cannot see view definitions, stored-function bodies, or actual table schemas,
|
|
183
|
+
and cannot rule out SQL shapes it does not yet model.
|
|
184
|
+
Fields that must never be exposed belong behind database views or column-level
|
|
185
|
+
permissions for the account this server uses.
|
|
171
186
|
|
|
172
187
|
These controls enforce the MCP read-only contract even when the supplied MySQL
|
|
173
188
|
account has write privileges. A `SELECT`-only account is still recommended as
|
|
Binary file
|
package/package.json
CHANGED