0

I have an ASP.net C# site. I feed one of the ListView in that with this code and it's work:

protected void BindData()
{
    string forwardedSearchText = Request.QueryString["SearchText"];
    string forwardedSearchColumn = Convert.ToString(Session["SearchTitle"]);

    string strsql = "Select TbSoore.IdSoore, TbSoore.NameSoore, TbAye.NumberAye, TbAye.IdAye, TbAye.TextAye, TbAye.TextTarjome From TbAye INNER JOIN TbSoore ON TbAye.IdSoore = TbSoore.IdSoore Where FreeText((" + forwardedSearchColumn + "),N' " + forwardedSearchText + "')";

    DataTable dt = new DataTable();
    using (SqlConnection con = new SqlConnection(strcon))
    {
        using
            (SqlCommand cmdSQL = new SqlCommand(strsql, con))
        {
            con.Open();
            ListViewSearchResults.DataSource = cmdSQL.ExecuteReader();
            ListViewSearchResults.DataBind();
        }
    }

}

Now I want to change the query string style for better security to:

$@"Select TbSoore.IdSoore, TbSoore.NameSoore, TbAye.NumberAye, TbAye.IdAye, TbAye.TextAye, TbAye.TextTarjome From TbAye INNER JOIN TbSoore ON TbAye.IdSoore = TbSoore.IdSoore Where FreeText(({forwardedSearchColumn}),N' @forwardedSearchText ')";

So change BindData() to:

protected void BindData()
{
    string forwardedSearchText = Request.QueryString["SearchText"];
    string forwardedSearchColumn = Convert.ToString(Session["SearchTitle"]);

    string strsql = $@"Select TbSoore.IdSoore, TbSoore.NameSoore, TbAye.NumberAye, TbAye.IdAye, TbAye.TextAye, TbAye.TextTarjome From TbAye INNER JOIN TbSoore ON TbAye.IdSoore = TbSoore.IdSoore Where FreeText(({forwardedSearchColumn}),N' @forwardedSearchText ')";

    DataTable dt = new DataTable();
    using (SqlConnection con = new SqlConnection(strcon))
    {
        using
            (SqlCommand cmdSQL = new SqlCommand(strsql, con))
        {
            cmdSQL.Parameters.Add("@forwardedSearchText", SqlDbType.NVarChar).Value = forwardedSearchText;
            con.Open();
            ListViewSearchResults.DataSource = cmdSQL.ExecuteReader();
            ListViewSearchResults.DataBind();
        }
    }

}

But it doesn't work. I don't get any error but the table is empty.

Can any one help me?

2 Answers 2

1

A good example as to how formatting the SQL text in code, and not having it warp off the page ensures that when reading the code, you can with ease see all of the text.

I would consider a view, or even better a stored procedure, and that would have eliminated this error due to difficult to read in-line SQL.

SQL parameters don't use nor require quotes.

I suggest this:

    protected void BindData()
    {
        string forwardedSearchText = Request.QueryString["SearchText"];
        string forwardedSearchColumn = Convert.ToString(Session["SearchTitle"]);

        string strsql = 
            $@"Select TbSoore.IdSoore, TbSoore.NameSoore, TbAye.NumberAye, TbAye.IdAye, TbAye.TextAye,
            TbAye.TextTarjome From TbAye
            INNER JOIN TbSoore ON TbAye.IdSoore = TbSoore.IdSoore
            Where FreeText({forwardedSearchColumn},@forwardedSearchText)";

        DataTable dt = new DataTable();
        using (SqlConnection con = new SqlConnection(strcon))
        {
            using
                (SqlCommand cmdSQL = new SqlCommand(strsql, con))
            {
                cmdSQL.Parameters.Add("@forwardedSearchText", SqlDbType.NVarChar).Value = forwardedSearchText;
                con.Open();
                ListViewSearchResults.DataSource = cmdSQL.ExecuteReader();
                ListViewSearchResults.DataBind();
            }
        }

    }

Also, if the ListView is going to require use of the full row during databinding such as often used for formatting of each row, then feeding the ListView with a reader does not allow use of the full data row during the binding process.

So, I thus suggest this:

   cmdSQL.Parameters.Add("@forwardedSearchText", SqlDbType.NVarChar).Value = forwardedSearchText;
   con.Open();
   DataTable dt = new DataTable();
   dt.Load(cmdSQL.ExecuteReader());

   ListViewSearchResults.DataSource = dt;
   ListViewSearchResults.DataBind();

With above, we have reduced string concatenation for the search terms, but we still have an injection vulnerability.

The problem of course is that the SearchColumn is still a concatenation expression, but worse is T-SQL does not allow column names as a parameter.

If the column is to only ever be one column, then I suggest hard coding of that column, or even introduction of a switch case statement for the given column name.

If the number of columns is variable (and can be more then one column), then at least ensure that this selecting is some kind of ListBox, or other type of UI in which the user does not type in the column names.

As noted, concatenation of those column names still represents a security risk.

So, I would ensure that the column selecting of your UI does not allow free form (text box input) for the column names.

I should also point out in your posted code, you defined a DataTable, but it is not used. And reading above, I in fact missed that you already declared the DataTable.

Hence, we now have this code:

    protected void BindData()
    {
        string forwardedSearchText = Request.QueryString["SearchText"];
        string forwardedSearchColumn = Convert.ToString(Session["SearchTitle"]);

        string strsql = 
            $@"Select TbSoore.IdSoore, TbSoore.NameSoore, TbAye.NumberAye, TbAye.IdAye, TbAye.TextAye,
            TbAye.TextTarjome From TbAye
            INNER JOIN TbSoore ON TbAye.IdSoore = TbSoore.IdSoore
            Where FreeText({forwardedSearchColumn},@forwardedSearchText)";

        DataTable dt = new DataTable();
        using (SqlConnection con = new SqlConnection(strcon))
        {
            using (SqlCommand cmdSQL = new SqlCommand(strsql, con))
            {
                cmdSQL.Parameters.Add("@forwardedSearchText", SqlDbType.NVarChar).Value = forwardedSearchText;
                con.Open();
                dt.Load(cmdSQL.ExecuteReader());
            }
        }
        ListViewSearchResults.DataSource = dt;
        ListViewSearchResults.DataBind();
    }
Sign up to request clarification or add additional context in comments.

Comments

0

This problem was Like this on and has the same answer. Thank AlbertD.Kallal for his complete answer, his answer helped me but my problem solved by this tip:

I do that AlbertD.Kallal said but instead of forwardedSearchText ,I have to use Request.QueryString["SearchText"] in command.parameters with " both sides of .

So the correct code that works, is:

strsql =
           $@"Select TbSoore.IdSoore, TbSoore.NameSoore, TbAye.NumberAye, TbAye.IdAye, TbAye.TextAye, TbAye.TextTarjome
           From TbAye INNER JOIN TbSoore ON TbAye.IdSoore = TbSoore.IdSoore
           Where FreeText(({forwardedSearchColumn}), @forwardedSearchText )";
        }
        DataTable dt = new DataTable();
        using (SqlConnection con = new SqlConnection(strcon))
        {
            using
                (SqlCommand cmdSQL = new SqlCommand(strsql, con))
            {
                
                cmdSQL.Parameters.Add("@forwardedSearchText", SqlDbType.NVarChar).Value =
                "\"" + Request.QueryString["SearchText"] + "\"";
                
                con.Open();
                dt.Load(cmdSQL.ExecuteReader());
            }
            ListViewSearchResultAye.DataSource = dt;
            ListViewSearchResultAye.DataBind();

        }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.