2017-09-19 18 views
0

我試圖使用COALESCE來處理Go中的sql注入。COALESCE正在返回一個文本類型而不是Postgres中的time_stamp類型

query := `SELECT mc.company_name_full, msc.company_id, msc.cdate, %s 
      FROM %s AS mc INNER JOIN %s AS msc 
      ON (mc.id = msc.company_id) 
      WHERE %s AND 
      msc.company_id = COALESCE($1, msc.company_id) AND 
      mc.company_name_full ~* COALESCE($2, mc.company_name_full) AND 
      msc.cdate >= '2017-07-01' AND 
      msc.cdate <= '%s'` 
query = fmt.Sprintf(query, selectParam, companyTable, statsTable, whereParam, time.Now().Local().Format("2006-01-02")) 

此查詢的工作,但是當我嘗試使用COALESCE與TIME_STAMP

query := `SELECT mc.company_name_full, msc.company_id, msc.cdate, %s 
      FROM %s AS mc INNER JOIN %s AS msc 
      ON (mc.id = msc.company_id) 
      WHERE %s AND 
      msc.company_id = COALESCE($1, msc.company_id) AND 
      mc.company_name_full ~* COALESCE($2, mc.company_name_full) AND 
      msc.cdate >= COALESCE($3, '2017-07-01') AND 
      msc.cdate <= COALESCE($4, '%s')` 

,但我得到這個錯誤

pq:operator does not exist: timestamp without time zone >= text 

我能做些什麼,以確保COALESCE返回時間戳類型?

回答

4

可以text字符串到timestamp,像這樣:

`SELECT mc.company_name_full, msc.company_id, msc.cdate, %s 
     FROM %s AS mc INNER JOIN %s AS msc 
     ON (mc.id = msc.company_id) 
     WHERE %s AND 
     msc.company_id = COALESCE($1, msc.company_id) AND 
     mc.company_name_full ~* COALESCE($2, mc.company_name_full) AND 
     msc.cdate >= COALESCE($3, '2017-07-01'::timestamp) AND 
     msc.cdate <= COALESCE($4, '%s'::timestamp)` 

一般警告:

我不是太熟悉轉到語法,但從我可以告訴,%s這裏是Sprintf用於直接格式化(插值),所以這些在你的where子句stil l技術上允許SQL注入

Anywhere的可能(和一些事情,如表名,這真的不是,但即使在這種情況下,你需要從那裏被插入的變量來作爲小心地),綁定應用過的。

例如爲什麼time.Now().Local().Format("2006-01-02")不能作爲綁定傳遞並且不能插入?響應

更新從OP評價:

Go lib/pq package doc,在該示例的代碼:

rows, err := db.Query(`SELECT name FROM users WHERE favorite_fruit = $1 
    OR age BETWEEN $2 AND $2 + 3`, "orange", 64) 

$1$2綁定。也就是說,該庫處理逃逸他們(轉到pq包是圍繞純Postgres的一個轉到包裝的libpq庫),並應防止SQL注入。他們綁定(即連接到)隨後傳遞的參數。

例如$1映射到"orange"$2映射到64

在原始查詢的到%s參考,相比之下,直接格式化 - 這意味着沒有的Postgres爲基礎的(的libpq)逃逸,正因爲如此,從SQL注入沒有保障。這些值只是簡單地通過。

Go formatting的更多詳細信息。

+0

我不太熟悉術語極間和綁定,你介意提供一個例子嗎? –

+0

@richard_d_sim:添加到我的原始答案。 – khampson

2

除了@ khampson的回答,CAST(表達式類型)可以轉換類型。

還同意sql注入的風險;自身合併不是防止它的有效方法。

使用準備的查詢&綁定通用參數替換的參數。要替換表名變量,去sql包還沒有提供標準接口(in progress),所以使用數據庫庫特定的引用函數,例如:QuoteIdentifier。另請參閱postgres parameter quoting示例。

相關問題