Can I protect against SQL injection by escaping single-quote and surrounding user input with single-quotes?

后端 未结 18 2269
忘了有多久
忘了有多久 2020-11-22 14:03

I realize that parameterized SQL queries is the optimal way to sanitize user input when building queries that contain user input, but I\'m wondering what is wrong with takin

相关标签:
18条回答
  • 2020-11-22 14:47

    Okay, this response will relate to the update of the question:

    "If anyone knows of any specific way to mount a SQL injection attack against this sanitization method I would love to see it."

    Now, besides the MySQL backslash escaping - and taking into account that we're actually talking about MSSQL, there are actually 3 possible ways of still SQL injecting your code

    sSanitizedInput = "'" & Replace(sInput, "'", "''") & "'"

    Take into account that these will not all be valid at all times, and are very dependant on your actual code around it:

    1. Second-order SQL Injection - if an SQL query is rebuilt based upon data retrieved from the database after escaping, the data is concatenated unescaped and may be indirectly SQL-injected. See
    2. String truncation - (a bit more complicated) - Scenario is you have two fields, say a username and password, and the SQL concatenates both of them. And both fields (or just the first) has a hard limit on length. For instance, the username is limited to 20 characters. Say you have this code:
    username = left(Replace(sInput, "'", "''"), 20)
    

    Then what you get - is the username, escaped, and then trimmed to 20 characters. The problem here - I'll stick my quote in the 20th character (e.g. after 19 a's), and your escaping quote will be trimmed (in the 21st character). Then the SQL

    sSQL = "select * from USERS where username = '" + username + "'  and password = '" + password + "'"
    

    combined with the aforementioned malformed username will result in the password already being outside the quotes, and will just contain the payload directly.
    3. Unicode Smuggling - In certain situations, it is possible to pass a high-level unicode character that looks like a quote, but isn't - until it gets to the database, where suddenly it is. Since it isn't a quote when you validate it, it will go through easy... See my previous response for more details, and link to original research.

    0 讨论(0)
  • 2020-11-22 14:47

    It might work, but it seems a little hokey to me. I'd recommend verifing that each string is valid by testing it against a regular expression instead.

    0 讨论(0)
  • 2020-11-22 14:50

    First of all, it's just bad practice. Input validation is always necessary, but it's also always iffy.
    Worse yet, blacklist validation is always problematic, it's much better to explicitly and strictly define what values/formats you accept. Admittedly, this is not always possible - but to some extent it must always be done.
    Some research papers on the subject:

    • http://www.imperva.com/docs/WP_SQL_Injection_Protection_LK.pdf
    • http://www.it-docs.net/ddata/4954.pdf (Disclosure, this last one was mine ;) )
    • https://www.owasp.org/images/d/d4/OWASP_IL_2007_SQL_Smuggling.pdf (based on the previous paper, which is no longer available)

    Point is, any blacklist you do (and too-permissive whitelists) can be bypassed. The last link to my paper shows situations where even quote escaping can be bypassed.

    Even if these situations do not apply to you, it's still a bad idea. Moreover, unless your app is trivially small, you're going to have to deal with maintenance, and maybe a certain amount of governance: how do you ensure that its done right, everywhere all the time?

    The proper way to do it:

    • Whitelist validation: type, length, format or accepted values
    • If you want to blacklist, go right ahead. Quote escaping is good, but within context of the other mitigations.
    • Use Command and Parameter objects, to preparse and validate
    • Call parameterized queries only.
    • Better yet, use Stored Procedures exclusively.
    • Avoid using dynamic SQL, and dont use string concatenation to build queries.
    • If using SPs, you can also limit permissions in the database to executing the needed SPs only, and not access tables directly.
    • you can also easily verify that the entire codebase only accesses the DB through SPs...
    0 讨论(0)
  • 2020-11-22 14:50

    I've used this technique when dealing with 'advanced search' functionality, where building a query from scratch was the only viable answer. (Example: allow the user to search for products based on an unlimited set of constraints on product attributes, displaying columns and their permitted values as GUI controls to reduce the learning threshold for users.)

    In itself it is safe AFAIK. As another answerer pointed out, however, you may also need to deal with backspace escaping (albeit not when passing the query to SQL Server using ADO or ADO.NET, at least -- can't vouch for all databases or technologies).

    The snag is that you really have to be certain which strings contain user input (always potentially malicious), and which strings are valid SQL queries. One of the traps is if you use values from the database -- were those values originally user-supplied? If so, they must also be escaped. My answer is to try to sanitize as late as possible (but no later!), when constructing the SQL query.

    However, in most cases, parameter binding is the way to go -- it's just simpler.

    0 讨论(0)
  • 2020-11-22 14:51

    If you have parameterised queries available you should be using them at all times. All it takes is for one query to slip through the net and your DB is at risk.

    0 讨论(0)
  • 2020-11-22 14:53

    Input sanitation is not something you want to half-ass. Use your whole ass. Use regular expressions on text fields. TryCast your numerics to the proper numeric type, and report a validation error if it doesn't work. It is very easy to search for attack patterns in your input, such as ' --. Assume all input from the user is hostile.

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