ColdFusion Query - Injection Protection

I ask this question a little vaguely because I need to know the answer. Can someone be kind and explain if and how the injection can occur in the following code?

<cfquery> select * from tableName where fieldName = '#value#' </cfquery> 

I am particularly interested in learning about injection attempts and other malicious entries, and not about best practices or input validation to handle "normal" user input. I see that people strongly advocate the use of CFQueryParam, but I don’t think I see this. If user input has been checked for consistency with the database schema (for example, so that the input is numeric for the fields of a numeric database), is there anything else obtained using CFQueryParam? What does <cfqueryparam CFSQLType = "CF_SQL_VARCHAR"> that '#value#' does not?

+1
source share
3 answers

Doesn't magically execute CF in the CF query tag when you wrap evaluated variables in single quotes?

Yes, it converts ' to '' for you.

Now guess which SQL you will get from this code:

 <cfset value = "\'; DROP TABLE tableName -- " /> <cfquery> select * from tableName where fieldName = '#value#' </cfquery> 


The cfqueryparam tag works; using query parameters, solves SQL injection.

Any custom written attempts to check, disinfect, or shield (all separate things, by the way) are at best as good as knowing the developer of the database system the code is working with.

If the developer is not aware of other methods of evacuating or changing the values ​​between validation / escaping and visualizing them in SQL, or even if the code base is ported to another database system and seems to be in order, there is a chance of breaking user code.

When it comes to security, you don't need such an opportunity. So use cfqueryparam.

+2
source

Update:

While this is an answer to part of your question, Peter’s answer is better because it directly addresses your question: “Why use cfqueryparam when CF automatically adds protection by escaping single quotes?”. Answer: In short, because the latter does not always work. Binding variables do.


He says that in the docs he “avoids string variables in single quotation marks”, but doesn't do it “magically” wrong in the CF query tag when you wrap evaluated variables in single quotes?

Yes, most versions automatically avoid single quotes as a security measure for those who do not use cfqueryparam. However, as Scott noted, it is better to use cfqueryparam (i.e., bind variables) because they ensure that parameters are not executed as sql commands . Variables work, even when auto-escaping fails, as Peter’s answer shows .

However, sql intrusion protection is just a side effect of using bind variables. The main reason for using binding variables is performance. Bind variables, prompting databases to reuse query plans , rather than creating a new plan each time # parameter # is changed. This reduces compilation time, improving performance.

Cfqueryparam also has a number of other benefits:

  • Provides data type checking (length, value, type, ...)
  • Provides attributes that simplify the handling of "lists" and null values
  • Performs a data type check before any sql is sent to the database, preventing useless calls to the database

Although this does not really apply to string columns, IMO is another important reason for using it - accuracy. When you pass a quoted string to the database, you rely on implicit conversion . Essentially, you leave this to the database to figure out how best to perform the comparison, and the results are not always what you expected. (Date strings are a prime example). You may end up with inaccurate results or sometimes slower queries, depending on how the database decides to execute sql. Using cfqueryparam avoids these problems by eliminating the ambiguity.

+8
source

To answer the first part of your question, set the following for the #value# variable:

 someValue'; DELETE FROM tableName WHERE '1' = '1 

will execute this request:

 <cfquery> select * from tableName where fieldName = 'someValue'; DELETE FROM tableName WHERE '1' = '1' </cfquery> 
0
source

All Articles