简体   繁体   中英

Select command has truncated parameter when called from webpage

SQL Server profiler output when called by the website:

exec sp_executesql N'SELECT top 1 [id],[salt] FROM dbo.[Users] 
                                                    WHERE recoveryCode = @recoveryCode and DATEDIFF(HOUR, [recoveryDateTime],  GETDATE())  < 25',N'@recoveryCode nvarchar(30)',@recoveryCode=N'�

The parameter at the end of the line is truncated. Why did that happen?

If I execute the command from the dev environment, everything works fine.

SQL Server profiler output for the working code:

exec sp_executesql N'SELECT top 1 [id],[salt] FROM dbo.[Users] 
                                                    WHERE recoveryCode = @recoveryCode and DATEDIFF(HOUR, [recoveryDateTime],  GETDATE())  < 25',N'@recoveryCode nvarchar(29)',@recoveryCode=N'&c26އ�]LwIǔ�lݓ&^�`;�4���sD�'

Both calls are directed toward the same database. The first one from my local environment, the second one from an azure webpage.

This is the C# code doing the call:

string HashVarchar = HashSHA256(Request.Params["random"]);

//get the user data.  
try
{
      SqlCommand cmd = new SqlCommand(@"SELECT top 1 [id],[salt] FROM dbo.[Users] 
                                                    WHERE recoveryCode = @recoveryCode and DATEDIFF(HOUR, [recoveryDateTime],  GETDATE())  < 25", conn);
      //recoveryCode = @hash, recoveryDateTime = GETDATE()
      cmd.Parameters.AddWithValue("recoveryCode", HashVarchar);

      try
      {
          conn.Open();
          SqlDataReader reader = cmd.ExecuteReader();

The following is only a workaround. An explanation for the strange behaviour would be most welcome...

Putting everything in a stored procedure solved the problem:

CREATE PROCEDURE [dbo].[getUserDataByRecoveryCode]
    @recoveryCode  nvarchar(64) 
AS
BEGIN
    /*
    exec [dbo].[getUserDataByRecoveryCode] @recoveryCode=N'7�,n�4_� Yctg|�� �^*�1����'
    */

    SELECT top 1 
        [id],
        [salt] 
    FROM dbo.[Users] 
    WHERE recoveryCode = @recoveryCode 
        and DATEDIFF(HOUR, [recoveryDateTime],  GETDATE())  < 25    
END

And the Call from C#

string query = "[dbo].[getUserDataByRecoveryCode]";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.CommandType = CommandType.StoredProcedure;

SqlParameter param1 = new SqlParameter();
param1.DbType = DbType.String;
param1.ParameterName = "@recoveryCode";
param1.Value = HashVarchar;
cmd.Parameters.Add(param1);


try
{
    conn.Open();
    SqlDataReader reader = cmd.ExecuteReader();

Doing this also allows to remove the rights to the sql user used to access the database by select commands:

DENY SELECT ON dbo.Users TO exampleUser

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM