Is it safe to not parameterize an SQL query when the parameter is not a string?

前端 未结 11 827
一生所求
一生所求 2020-12-23 15:57

In terms of SQL injection, I completely understand the necessity to parameterize a string parameter; that\'s one of the oldest tricks in the book. But when can

相关标签:
11条回答
  • 2020-12-23 16:21

    I think it's safe... technically, but it's a terrible habit to get into. Do you really want to be writing queries like this?

    var sqlCommand = new SqlCommand("SELECT * FROM People WHERE IsAlive = " + isAlive + 
    " AND FirstName = @firstName");
    
    sqlCommand.Parameters.AddWithValue("firstName", "Rob");
    

    It also leaves you vulnerable in the situation where a type changes from an integer to a string (Think employee number which, despite its name - may contain letters).

    So, we've changed the type of EmployeeNumber from int to string, but forgot to update our sql queries. Oops.

    0 讨论(0)
  • 2020-12-23 16:22

    When using a strongly-typed platform on a computer you control (like a web server), you can prevent code injection for queries with only bool, DateTime, or int (and other numeric) values. What is a concern are performance issues caused by forcing sql server to re-compile every query, and by preventing it from getting good statistics on what queries are run with what frequency (which hurts cache management).

    But that "on a computer you control" part is important, because otherwise a user can change the behavior used by the system for generating strings from those values to include arbitrary text.

    I also like to think long-term. What happens when today's old-and-busted strongly-typed code base gets ported via automatic translation to the new-hotness dynamic language, and you suddenly lose the type checking, but don't have all the right unit tests yet for the dynamic code?

    Really, there's no good reason not to use query parameters for these values. It's the right way to go about this. Go ahead and hard-code values into the sql string when they really are constants, but otherwise, why not just use a parameter? It's not like it's hard.

    Ultimately, I wouldn't call this a bug, per se, but I would call it a smell: something that falls just short of a bug by itself, but is a strong indication that bugs are nearby, or will be eventually. Good code avoids leaving smells, and any good static analysis tool will flag this.

    I'll add that this is not, unfortunately, the kind of argument you can win straight up. It sounds like a situation where being "right" is no longer enough, and stepping on your co-workers toes to fix this issue on your own isn't likely to promote good team dynamics; it could ultimately hurt more than it helps. A better approach in this case may be to promote the use of a static analysis tool. That would give legitimacy and credibility to efforts aimed and going back and fixing existing code.

    0 讨论(0)
  • 2020-12-23 16:23
    "SELECT * FROM Table1 WHERE Id=" + intVariable.ToString()
    

    Security

    It is OK.
    Attackers can not inject anything in your typed int variable.

    Performance

    Not OK.

    It's better to use parameters, so the query will be compiled once and cached for next usage. Next time even with different parameter values, query is cached and doesn't need to compile in database server.

    Coding Style

    Poor practice.

    • Parameters are more readable
    • Maybe it makes you get used to queries without parameters, then maybe you made a mistake once and use a string value this way and then you probably should say goodbye to your data. Bad habit!

    "SELECT * FROM Product WHERE Id=" + TextBox1.Text
    

    Although it is not your question, but maybe useful for future readers:

    Security

    Disaster!

    Even when the Id field is an integer, your query may be subject to SQL Injection. Suppose you have a query in your application "SELECT * FROM Table1 WHERE Id=" + TextBox1.Text. An attacker can insert into text box 1; DELETE Table1 and the query will be:

    SELECT * FROM Table1 WHERE Id=1; DELETE Table1
    

    If you don't want to use a parametrized query here, you should use typed values:

    string.Format("SELECT * FROM Table1 WHERE Id={0}", int.Parse(TextBox1.Text))
    

    Your Question

    My question arose because a coworker wrote a bunch of queries concatenating integer values, and I was wondering whether it was a waste of my time to go through and fix all of them.

    I think changing those codes is not waste of time. Indeed change is recommended!

    If your coworker uses int variables it has no security risk, but I think changing those codes is not waste of time and indeed changing those codes is recommended. It makes code more readable, more maintainable, and makes execution faster.

    0 讨论(0)
  • 2020-12-23 16:24

    Let's not just think about security or type-safe considerations.

    The reason you use parametrized queries is to improve performance at the database level. From a database perspective, a parametrized query is one query in the SQL buffer (to use Oracle's terminology although I imagine all databases have a similar concept internally). So, the database can hold a certain amount of queries in memory, prepared and ready to execute. These queries do not need to be parsed and will be quicker. Frequently run queries will usually be in the buffer and will not need parsing every time they are used.

    UNLESS

    Somebody doesn't use parametrized queries. In this case, the buffer gets continually flushed through by a stream of nearly identical queries each of which needs to be parsed and run by the database engine and performance suffers all-round as even frequently run queries end up being re-parsed many times a day. I have tuned databases for a living and this has been one of the biggest sources of low-hanging fruit.

    NOW

    To answer your question, IF your query has a small number of distinct numeric values, you will probably not be causing issues and may in fact improve performance infinitesimally. IF however there are potentially hundreds of values and the query gets called a lot, you are going to affect the performance of your system so don't do it.

    Yes you can increase the SQL buffer but it's always ultimately at the expense of other more critical uses for memory like caching Indexes or Data. Moral, use parametrized queries pretty religiously so you can optimize your database and use more server memory for the stuff that matters...

    0 讨论(0)
  • 2020-12-23 16:25

    It is ok but never safe.. and the security always depend on the inputs, for example if the input object is TextBox, the attackers can do something tricky since the textbox can accept string, so you have to put some kind of validation/conversion to be able prevent users the wrong input. But the thing is, it is not safe. As simply as that.

    0 讨论(0)
提交回复
热议问题