防止SQL注入

huangapple go评论95阅读模式
英文:

Prevent SQL injection

问题

问题1:

我有以下的MySQL查询语句,它工作得很好,但我刚刚发现这不是一个安全的方法,因为它容易受到SQL注入的攻击。如你所见,如果我想将其作为参数传递,where子句就成了一个问题。

_, err := dbmap.Select(&response.AppsData, "SELECT...", ?)

非常感谢任何建议。

where := ""

for i := 0; i < len(acl_user_apps); i++ {
	fmt.Println(acl_user_apps[i].AppId)
	fmt.Println(acl_user_apps[i].Permissions)

	if where == "" {
		where = "WHERE Apps.id=" + strconv.Itoa(acl_user_apps[i].AppId)
	} else {
		where = where + " OR Apps.id=" + strconv.Itoa(acl_user_apps[i].AppId)
	}
}

query := "SELECT Apps.*, GROUP_CONCAT(DISTINCT IFNULL(AppCategoryMatches.category_id,'-1') SEPARATOR ',') as temp,   GROUP_CONCAT(DISTINCT IFNULL(AppCategories.category_name,'-1') SEPARATOR ',') as tmp_name FROM Apps LEFT JOIN AppCategoryMatches ON AppCategoryMatches.app_id=Apps.id LEFT JOIN AppCategories ON (AppCategoryMatches.`category_id` = AppCategories.id) " + where + " GROUP BY Apps.id ORDER BY " + sort_by + " " + order_by + " LIMIT " + limit + " OFFSET " + offset)
_, err := dbmap.Select(&response.AppsData,query)

问题2:我也想知道是否有人遇到过传递ORDER参数的问题...

_, err := dbmap.Select(&response.AppsData,
		"SELECT Apps.*, GROUP_CONCAT(DISTINCT IFNULL(AppCategoryMatches.category_id,'-1') SEPARATOR ',') as temp, GROUP_CONCAT(DISTINCT IFNULL(AppCategories.category_name,'-1') SEPARATOR ',') as tmp_name FROM Apps LEFT JOIN AppCategoryMatches ON AppCategoryMatches.app_id=Apps.id LEFT JOIN AppCategories ON (AppCategoryMatches.category_id = AppCategories.id) GROUP BY Apps.id ORDER BY ?", "title")

这个ORDER语句非常简单...为什么它不起作用?

英文:

Question 1:

I have the below MySQL query which works fine but I've just discovered this is not a safe approach as its open to SQL injection. As you can see the where clause is an issue if I wanted to pass as an argument.

_, err := dbmap.Select(&amp;response.AppsData, &quot;SELECT...&quot;, ?)

Any advice much appriciated.

where := &quot;&quot;

for i := 0; i &lt; (len(acl_user_apps)); i++ {
	fmt.Println(acl_user_apps[i].AppId)
	fmt.Println(acl_user_apps[i].Permissions)

	if where == &quot;&quot; {
		where = &quot;WHERE Apps.id=&quot; + strconv.Itoa(acl_user_apps[i].AppId)
	} else {
		where = where + &quot; OR Apps.id=&quot; + strconv.Itoa(acl_user_apps[i].AppId)
	}
}

query := &quot;SELECT Apps.*, GROUP_CONCAT(DISTINCT IFNULL(AppCategoryMatches.category_id,&#39;-1&#39;) SEPARATOR &#39;,&#39;) as temp,   GROUP_CONCAT(DISTINCT IFNULL(AppCategories.category_name,&#39;-1&#39;) SEPARATOR &#39;,&#39;) as tmp_name FROM Apps LEFT JOIN AppCategoryMatches ON AppCategoryMatches.app_id=Apps.id LEFT JOIN AppCategories ON (AppCategoryMatches.`category_id` = AppCategories.id) &quot; + where + &quot; GROUP BY Apps.id ORDER BY &quot; + sort_by + &quot; &quot; + order_by + &quot; LIMIT &quot; + limit + &quot; OFFSET &quot; + offset)
_, err := dbmap.Select(&amp;response.AppsData,query)

Question 2: Also just wondering if anyone has ever had issues passing ORDER argument...

_, err := dbmap.Select(&amp;response.AppsData,
		&quot;SELECT Apps.*, GROUP_CONCAT(DISTINCT IFNULL(AppCategoryMatches.category_id,&#39;-1&#39;) SEPARATOR &#39;,&#39;) as temp, GROUP_CONCAT(DISTINCT IFNULL(AppCategories.category_name,&#39;-1&#39;) SEPARATOR &#39;,&#39;) as tmp_name FROM Apps LEFT JOIN AppCategoryMatches ON AppCategoryMatches.app_id=Apps.id LEFT JOIN AppCategories ON (AppCategoryMatches.category_id = AppCategories.id) GROUP BY Apps.id ORDER BY ?&quot;, &quot;title&quot;)

This ORDER is the simplest thing ever... why isnt it working?

答案1

得分: 7

你绝对不想自己"转义"任何字符串,也不要拼接字符串来构建查询。

  1. Go的database/sql(http://golang.org/pkg/database/sql/)包默认支持参数化查询,例如db.Query("SELECT * FROM users WHERE id=? AND active=?", id, userStatus),其中?作为占位符,由MySQL处理变量。

  2. 你可以(与参数化查询结合使用)使用查询构建器,例如mgutz/dat,如果你不擅长编写原始SQL语句,它可以帮助你。类似的包括sqlx,还可以帮助在应用程序中将查询打包/解包到结构体或映射中。

在这个教程中还有一个很好的指南(http://go-database-sql.org/index.html)来使用Go的数据库包。我强烈建议阅读它。

英文:

You absolutely don't want to be "escaping" any strings on your own, nor concatenating strings to make queries.

  1. Go's database/sql (http://golang.org/pkg/database/sql/) package supports parameterised queries by default - e.g. db.Query(&quot;SELECT * FROM users WHERE id=? AND active=?&quot;, id, userStatus) - where ? acts as a placeholder for mySQL to handle your variables.

  2. You can (in combination with parameterised queries) use a query builder like mgutz/dat that can help if you're not great at writing raw SQL. A package like that or sqlx also helps pack/unpack queries to/from structs or maps in your application.

There's also a great guide in this tutorial for using Go's database package. I highly suggest reading it.

答案2

得分: -2

我不了解Go语言。但是大多数语言都有用于转义字符串的函数(例如PHP的示例:http://php.net/manual/en/function.mysql-real-escape-string.php)。如果你只是将整数插入到查询中,你只需要将字符串值转换为整数。

可以参考这个链接:http://astaxie.gitbooks.io/build-web-application-with-golang/content/en/09.4.html,也许你会找到一些答案。

至于你的ORDER - 你能在这里放上你正在调用的完整SQL查询吗?

英文:

I don't know Go language. But most of languages have function for escaping strings (PHP example: http://php.net/manual/en/function.mysql-real-escape-string.php). If you're inserting only integers to your query, you only need to convert values from string to int.

Check this out: http://astaxie.gitbooks.io/build-web-application-with-golang/content/en/09.4.html maybe you'll find some answers.

And about your ORDER - can you put here complete sql query that you're calling?

huangapple
  • 本文由 发表于 2015年6月15日 18:37:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/30843058.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定