Skip to content

Commit 02b85f4

Browse files
fix: fixed polynomial regex used on uncontrolled data in isSQLStatement validation function
1 parent 9c3537f commit 02b85f4

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

__tests__/validation.test.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,38 @@ describe( 'Validation Utils', () => {
142142

143143

144144
describe( 'isSQLStatement', () => {
145-
it( 'returns `true` if the given value is a SQL statement', () => {
145+
it( 'detects SQL statements', () => {
146146
expect( isSQLStatement( 'SELECT * FROM users' ) ).toBe( true )
147+
expect( isSQLStatement( 'DELETE FROM users WHERE id = 1' ) ).toBe( true )
148+
expect( isSQLStatement( 'INSERT INTO users (name) VALUES ("John")' ) ).toBe( true )
149+
expect( isSQLStatement( 'UPDATE users SET name = "John" WHERE `id` = 1' ) ).toBe( true )
150+
expect( isSQLStatement( 'UNION SELECT * FROM users' ) ).toBe( true )
151+
expect( isSQLStatement( 'REPLACE INTO users (id, name) VALUES (1, "John")' ) ).toBe( true )
152+
expect( isSQLStatement( 'CREATE TABLE users (id INT, name VARCHAR(255))' ) ).toBe( true )
153+
expect( isSQLStatement( 'DROP TABLE users' ) ).toBe( true )
154+
expect( isSQLStatement( 'ALTER TABLE users ADD COLUMN age INT' ) ).toBe( true )
155+
expect( isSQLStatement( 'RENAME TABLE users TO customers' ) ).toBe( true )
156+
expect( isSQLStatement( 'SELECT * FROM users; --' ) ).toBe( true )
157+
} )
158+
159+
160+
it( 'does not detect non-SQL statements', () => {
161+
expect( isSQLStatement( 'This is a regular sentence.' ) ).toBe( false )
162+
expect( isSQLStatement( 'SELECTING a book FROM the shelf' ) ).toBe( false )
163+
expect( isSQLStatement( 'DROP the ball' ) ).toBe( false )
164+
expect( isSQLStatement( 'ALTER your plans' ) ).toBe( false )
165+
expect( isSQLStatement( 'RENAME the file' ) ).toBe( false )
147166
expect( isSQLStatement( 'SELECT this is a normal string' ) ).toBe( false )
148167
} )
168+
169+
170+
it('returns false for non-string values', () => {
171+
expect( isSQLStatement( null ) ).toBe( false )
172+
expect( isSQLStatement( undefined ) ).toBe( false )
173+
expect( isSQLStatement( 123 ) ).toBe( false )
174+
expect( isSQLStatement( {} ) ).toBe( false )
175+
expect( isSQLStatement( [] ) ).toBe( false )
176+
} )
149177
} )
150178

151179
} )

src/validation.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,5 +125,18 @@ export const isStrictEqual = ( a: unknown, b: unknown ) => a === b
125125
*/
126126
// eslint-disable-next-line @typescript-eslint/no-explicit-any
127127
export const isSQLStatement = ( value: any ) => (
128-
typeof value === 'string' && !! value.match( /(SELECT|DELETE|INSERT|UNION|REPLACE)\s.*(FROM|INTO|DISTINCT)|(CREATE|DROP|ALTER|RENAME)\s.*(TABLE|COLUMN|VIEW)|(;\-\-)/gi )
128+
typeof value === 'string' &&
129+
[
130+
/\bselect\b\s+.*?\bfrom\b/,
131+
/\bdelete\b\s+.*?\bfrom\b/,
132+
/\binsert\b\s+.*?\binto\b/,
133+
/\bupdate\b\s+.*?\bset\b/,
134+
/\bunion\b\s+.*?\bselect\b/,
135+
/\breplace\b\s+.*?\binto\b/,
136+
/\bcreate\b\s+.*?\b(table|view|index|database)\b/,
137+
/\bdrop\b\s+.*?\b(table|view|index|database)\b/,
138+
/\balter\b\s+.*?\b(table|view|index|database)\b/,
139+
/\brename\b\s+.*?\b(table|view|index|database)\b/,
140+
/;\s*--/
141+
].some( pattern => pattern.test( value.toLowerCase() ) )
129142
)

0 commit comments

Comments
 (0)