@@ -41,6 +41,17 @@ export interface MatchResult {
4141 matchValue : string ;
4242}
4343
44+ // ---------------------------------------------------------------------------
45+ // Constants
46+ // ---------------------------------------------------------------------------
47+
48+ /**
49+ * Tool argument keys that carry document payloads (not SQL parameters).
50+ * Excluded from SQL injection scanning to prevent false positives on
51+ * document writes (e.g. write_file with `content`, chat with `message`).
52+ */
53+ const CONTENT_FIELDS : ReadonlySet < string > = new Set ( [ 'content' , 'body' , 'message' , 'text' ] ) ;
54+
4455// ---------------------------------------------------------------------------
4556// Directive parsing
4657// ---------------------------------------------------------------------------
@@ -142,7 +153,17 @@ function evaluateCondition(
142153
143154 // "tool.call with arguments containing SQL syntax (DROP, DELETE, UNION, --)"
144155 if ( lc . includes ( 'arguments containing' ) ) {
145- const argsStr = JSON . stringify ( event . toolArgs ?? { } ) . toLowerCase ( ) ;
156+ // Only scan fields that could be SQL injection vectors.
157+ // Exclude content-body fields (document payloads written to files,
158+ // not SQL parameters) to prevent false positives.
159+ const rawArgs = event . toolArgs ?? { } ;
160+ const filteredArgs : Record < string , unknown > = { } ;
161+ for ( const [ key , val ] of Object . entries ( rawArgs ) ) {
162+ if ( ! CONTENT_FIELDS . has ( key ) ) {
163+ filteredArgs [ key ] = val ;
164+ }
165+ }
166+ const argsStr = JSON . stringify ( filteredArgs ) . toLowerCase ( ) ;
146167 // Extract keywords from parenthetical list
147168 const openIdx = condition . indexOf ( '(' ) ;
148169 const closeIdx = openIdx >= 0 ? condition . indexOf ( ')' , openIdx + 1 ) : - 1 ;
@@ -152,7 +173,13 @@ function evaluateCondition(
152173 . split ( ',' )
153174 . map ( ( k ) => k . trim ( ) . toLowerCase ( ) ) ;
154175 for ( const keyword of keywords ) {
155- if ( keyword && argsStr . includes ( keyword ) ) {
176+ if ( ! keyword ) continue ;
177+ if ( keyword === '--' ) {
178+ // Match SQL comment marker (--) but NOT markdown separators (---)
179+ if ( / (?< ! - ) - - (? ! - ) / . test ( argsStr ) ) {
180+ return { matchedOn : 'tool.args' , matchValue : keyword } ;
181+ }
182+ } else if ( argsStr . includes ( keyword ) ) {
156183 return { matchedOn : 'tool.args' , matchValue : keyword } ;
157184 }
158185 }
0 commit comments