【问题标题】:Prevent SQL Injection in Go Postgresql防止 Go Postgresql 中的 SQL 注入
【发布时间】:2021-01-18 01:40:55
【问题描述】:

我在 Go 中的 postgresql 注入论坛上进行了研究,发现了一些关于 SQL 注入的有用信息,如下所示:

How to execute an IN lookup in SQL using Golang?

How can I prevent SQL injection attacks in Go while using "database/sql"?

但我仍然需要一些建议,因为我在 Go 中的代码使用了不同类型的代码和用例。 我需要建议的一些用例/问题是这样的

  1. 使用查询循环进行多次插入,例如 INSERT INTO a (a1,a2,a3) VALUES (%d,%d,%s) 使用 fmt.Sprintf,我知道使用 sprintf 不好。那么对于插入的这个循环查询有什么解决方案吗? 例如:INSERT INTO a (a1,a2,a3) VALUES (%d,%d,%s),(%d,%d,%s),(%d,%d,%s)
  2. 如果参数使用%d 而不是%s,使用 fmt.Sprintf 生成查询是否安全?
  3. 使用 Prepare 语句和 Query 是安全的,但如果我使用函数 Select(使用 $1、$2)和函数 NamedQuery(使用 struct named)怎么办? 例如:Select * from a where text = $1 -> 使用这个$1 安全吗? 和 例如:Select * from a where text = :text -> 这在 NamedQuery 函数中安全吗?

请各位大侠指教。谢谢!

【问题讨论】:

标签: sql postgresql go sql-injection


【解决方案1】:

首先,通常更喜欢使用 db 占位符? 1 美元等。

  1. 是的,使用带有整数参数的 fmt.Sprintf 来构建 SQL 是安全的,但如果可以的话,值得避免,但您的第三个参数是 %s - 避免使用并使用?
  2. 是的,将 fmt.Sprintf 与整数参数一起使用是安全的,但 %s 或 %v 风险更大,我会避免,想不出你为什么需要它。
  3. 在这里使用占位符,然后是安全的。

一般规则:

  • 默认使用占位符,应该很少使用 %d(例如在您的 IN 查询中)
  • 在任何验证或使用之前将参数解析为整数等类型
  • 尽可能避免字符串连接,并特别注意字符串参数
  • 始终对列名和表名等内容进行硬编码,切勿根据用户输入生成它们(例如 ?sort=mystringcolname)
  • 始终验证您获得的参数仅是为该用户授权的参数

【讨论】:

  • 您好,感谢您的建议.. 1. 我忘了把问题放在问题 1 中,您能帮我解决这个问题吗? 2. 会那样做,我会尽量不使用 %s 3. 我明白了.. 所以这是安全的吧?我想如果我使用 1 美元,他们可以注入类似 1 OR text = "asda" 的东西,谢谢!
  • 他们不能。当您使用数据库的占位符(如$1)时,它会告诉数据库“我正在单独传递此参数的值”,然后它会传递该值。该值只是一个值,它不被视为查询的一部分;这就是它使 SQL 注入成为不可能的原因。
  • Adrian 是正确的,您可以安全地使用 $1 进行注入(尽管您在使用它时仍然可以通过信任用户输入来引入漏洞,例如允许访问您没想到的排序模式或搜索查询如果您天真地将用户输入用于订单子句、选择表等 - 例如,您采用参数排序并将其直接用于订单,让用户对 super_secret_key 字段上的记录进行排序并提取信息)。
  • 哦,我明白了...谢谢大家!需要一些关于问题的建议,所以现在我有一个查询插入,我根据 insert into a (a1,a2) values (%d,%s) ,(%d,%s) 之类的项目的 len 重复附加,其中 %d,%s 是重复的,有什么解决方案吗?还是我只是像values ($1,$2), ($3,$4) 或任何其他想法一样重复附加这个?我尝试像values (?,?), (?,?) 这样搜索,但在我测试时它对我不起作用
  • 是的 $1 $2 等应该可以工作。不同的方法/数据库需要不同的占位符,所以检查一下。
猜你喜欢
  • 1970-01-01
  • 2014-12-08
  • 2023-03-18
  • 2011-06-12
  • 1970-01-01
  • 2011-04-30
  • 2013-02-28
  • 2011-04-25
相关资源
最近更新 更多