CFScript中的动态SQL

时间:2011-05-06 05:59:35

标签: sql coldfusion sql-injection

我需要在我的SQL查询中添加if条件。我提出了这个解决方案,但它不起作用,我不知道为什么。

local.platformId = arguments.platformId ? "AND platforms.id = #arguments.platformId#" : "";

local.pages = new Query(dataSource=variables.wheels.class.connection.datasource);
local.pages.setSQL
("
    SELECT          COUNT(games.id) AS totalRecords
    FROM            games
    INNER JOIN      platforms ON games.platformId = platforms.id 
    WHERE           0=0
:platform
");

local.pages.addParam(name="platform", cfsqltype="CF_SQL_VARCHAR", value=local.platformId);      
local.pages = local.pages.execute().getResult();

我收到错误:You have an error in your SQL syntax; check ... near ''AND platforms.id = 1' ''' at line 6

任何想法如何解决这个限制并仍然确保SQL注入的安全性?

3 个答案:

答案 0 :(得分:6)

我喜欢使用savecontent:

savecontent variable="local.sql"{
    WriteOutput("
        SELECT          COUNT(games.id) AS totalRecords
        FROM            games
        INNER JOIN      platforms ON games.platformId = platforms.id 
        WHERE           0=0
    ");
    (arguments.platformId)
      ? WriteOutput("AND platforms.id = :platform")
      : WriteOutput("");
}

local.pages = new Query(dataSource=variables.wheels.class.connection.datasource);
local.pages.setSQL(local.sql);
if (arguments.platformId){
    local.pages.addParam(name="platform", cfsqltype="CF_SQL_VARCHAR", value=arguments.platformId);
}
local.pages = local.pages.execute().getResult();

答案 1 :(得分:3)

addParam相当于在CFML中使用cfqueryparam。所以它期望value属性像'1'或'foobar',而不是一点SQL。而只需将platformID的值设置为arguments.platformid或空字符串。然后直接参考WHERE子句中的:platform。

local.platformId = arguments.platformId ? arguments.platformId : "";

local.pages = new Query(dataSource=variables.wheels.class.connection.datasource);
local.pages.setSQL
("
    SELECT          COUNT(games.id) AS totalRecords
    FROM            games
    INNER JOIN      platforms ON games.platformId = platforms.id 
    WHERE           platforms.id = :platform
");

local.pages.addParam(name="platform", cfsqltype="CF_SQL_VARCHAR", value=local.platformId);      
local.pages = local.pages.execute().getResult();

这篇文章有一些很好的信息:http://www.bennadel.com/blog/1678-Learning-ColdFusion-9-Using-CFQuery-And-Other-Service-Tags-In-CFScript.htm

答案 2 :(得分:2)

为什么不设置SQL并在代码中的条件语句中添加param?

local.pages = new Query(dataSource=variables.wheels.class.connection.datasource);
local.baseSQL = "
    SELECT          COUNT(games.id) AS totalRecords
    FROM            games
    INNER JOIN      platforms ON games.platformId = platforms.id 
    WHERE           platforms.id = :platform
";

if(StructKeyExists(arguments, "platformId")
{
  local.baseSQL &= "AND platforms.id = :platformId";
  local.pages.setSQL(baseSQL);
  local.pages.addParam(
    name="platformId", 
    cfsqltype="CF_SQL_VARCHAR", 
    value=arguments.platformId);
}
else
  local.pages.setSQL(baseSQL)
local.pages = local.pages.execute().getResult();