- Add extract_keywords() to LLMService with conversation context support,
using process_stream + start_log/end_log for logging consistency
- Add expand_with_terminology() to expand keywords with synonym matching
- Add fusion scoring in calc_table_embedding(): α * vec_score + (1-α) * keyword_score
- Add calc_keyword_score() with multi-level matching:
table name exact (1.0), comment exact (0.9), comment substring (0.7),
table name partial (0.25-0.5), field comment exact (0.5),
field comment substring (0.4), field name partial (0.3)
- Scoring considers keyword coverage rate to differentiate tables
with different numbers of matched keywords
- Extracted keywords persisted to ChatRecord for reuse across endpoints
- get_terminology_template() supports comma-separated keyword input
with per-keyword matching for higher precision
- Add TABLE_EMBEDDING_ALPHA and TABLE_EMBEDDING_KEYWORD_ENABLED config
- TokenMiddleware/ResponseMiddleware/audit logger use scope['path']
instead of request.url.path for whitelist checks: a crafted Host
header (e.g. x/api/v1/mcp) was concatenated into Starlette's URL
and made protected routes match the /mcp* whitelist entry
- validateEmbedded rejects admin accounts and non-type-4 apps, so a
self-signed token with account=admin can no longer impersonate the
administrator
- Add HostValidationMiddleware rejecting malformed Host headers at the
outermost layer (defense in depth)
- Add regression tests for host validation, whitelist matching and
source-level guards
Co-Authored-By: Claude <[email protected]>
Security hardening:
- Add SQLBOT_ALLOW_METADATA_QUERIES config option, disable SHOW/DESCRIBE/EXPLAIN by default
- Add table whitelist check, use sqlglot to parse actual SQL table names and compare with authorized table list
- Add dangerous function check, block LOAD_FILE, INTO OUTFILE, EXEC etc. by database type
- Improve check_sql_read to return specific error reasons for better debugging
"*.css.map" was missing a trailing comma, causing Python's implicit string
literal concatenation to merge it with the next entry into "*.css.map/mcp*".
This made the /mcp* whitelist rule never match, so all /mcp/* endpoints
(mcp_start, mcp_question, mcp_get_sql, mcp_execute_sql, etc.) were blocked
by TokenMiddleware with "Miss Token[X-SQLBOT-TOKEN]" even though they are
intended to handle their own authentication internally.