V
valentin tihomirov
Hello,
-=PREHISTORY=-
Occasionally, I wanted to rewrite my UPDATE code to prevent SQL injection. I
generated the SQL query
UPDATE tt
SET
@p1_name = @p1_val
, @p2_name = @p2_val
, ...
along with the pairs of paramz:
new SqlParameter(formalName, actualName);
new SqlParameter(formalValue, actualValue);
for every column. Now, user can send name-value pairs the corresponding
columns will be updated safely. However, this fails if a value is longer
than 4 chars:
"System.Data.SqlClient.SqlException: String or binary data would be
truncated. The statement has been terminated."
Note, the code still works if the column names are not parametrized. As this
is weired, so I have decided to trial in pure SQL.
-=SQL=-
Here is the code to execute:
DECLARE @val varchar(100)
SELECT @val ='vvvv' -- making val longer breaks the code
exec sp_executesql N'update tt SET @name=@val'
, N'@name varchar(4), @val varchar(100)'
, 'col1', @val
Making the value one char longer will end up in the suspiciously famous "Msg
8152, Level 16, State 14, Line 1 String or binary data would be truncated."
THE INTERESTING thing is that the maximal allowed @val length is determined
by the @name parameter definition! Try yourslf by changing the declaration
varchar(4) -> varchar(5) and this will allow entering 5-symbol values.
Another bug observed is possibly related to the this one. The table data is
not affected even when no error is encountered. The value is taken only when
column name is not parametrized, that is, 'UPDATE tt SET col1 = @val' is
submitted.
Am I missing something?
-=PREHISTORY=-
Occasionally, I wanted to rewrite my UPDATE code to prevent SQL injection. I
generated the SQL query
UPDATE tt
SET
@p1_name = @p1_val
, @p2_name = @p2_val
, ...
along with the pairs of paramz:
new SqlParameter(formalName, actualName);
new SqlParameter(formalValue, actualValue);
for every column. Now, user can send name-value pairs the corresponding
columns will be updated safely. However, this fails if a value is longer
than 4 chars:
"System.Data.SqlClient.SqlException: String or binary data would be
truncated. The statement has been terminated."
Note, the code still works if the column names are not parametrized. As this
is weired, so I have decided to trial in pure SQL.
-=SQL=-
Here is the code to execute:
DECLARE @val varchar(100)
SELECT @val ='vvvv' -- making val longer breaks the code
exec sp_executesql N'update tt SET @name=@val'
, N'@name varchar(4), @val varchar(100)'
, 'col1', @val
Making the value one char longer will end up in the suspiciously famous "Msg
8152, Level 16, State 14, Line 1 String or binary data would be truncated."
THE INTERESTING thing is that the maximal allowed @val length is determined
by the @name parameter definition! Try yourslf by changing the declaration
varchar(4) -> varchar(5) and this will allow entering 5-symbol values.
Another bug observed is possibly related to the this one. The table data is
not affected even when no error is encountered. The value is taken only when
column name is not parametrized, that is, 'UPDATE tt SET col1 = @val' is
submitted.
Am I missing something?