优秀的编程知识分享平台

网站首页 > 技术文章 正文

Go 中的安全编码 - 输入验证(gog安全码)

nanyue 2024-11-02 12:18:24 技术文章 6 ℃

介绍


本文目标是:

  • 了解无论您使用哪种编码语言都适用的通用安全编码进行最佳实践。
  • 了解使用 Go 编码时如何应对 OWASP 十大(2017)安全风险。

特别是这个:

  • 了解数据清理和最佳实践。
  • 了解输入验证和最佳实践。

在此先感谢您的时间!

通用安全编码最佳实践

在开始本节之前,我想强调以下几点:当你为生活而编码时,我真的认为你有责任在你的理解范围内尽可能地做到最好。希望这种理解将通过自我激励的学习不断增长。这包括拥有嵌入到您的编码实践中的安全注意事项。请记住,无论您编写什么代码,都反映了您的专业精神。此外,您的代码构成了一个应用程序,该应用程序可能会在现实世界中以一种或另一种方式影响/影响人们。以此为荣!

让我们开始!

实践涉及以下几个领域:

  • 输入验证
  • 输出编码
  • 身份和认证管理
  • 会话管理
  • 访问控制
  • 密码实践
  • 错误处理、日志记录和指标
  • 数据保护
  • 通讯安全
  • 系统配置
  • 数据库安全
  • 文件管理
  • 内存管理
  • 其他

请注意,此列表基于OWASP SCP 快速参考指南 (v2)。但是,您会找到的内容还包括多年来获得的知识,并突出了一些额外的要点。

输入验证

每当讨论输入验证时数据清理都会与之共存。请注意,有些人也使用术语数据验证;不幸的是,它的用法并不一致,有时相当于输入验证,而其他一些则相当于数据清理。另外,我希望您记住,数据清理的应用因域而异:例如数据擦除、数据处理、数据隐私等。无论如何,我们需要澄清每个术语及其过程,我认为最好的方法是做它的上下文和例子。

对,所以,让我们考虑一个有表单的网站,并且在表单中只有一个用于电子邮件地址的输入字段。为了简单起见,我们假设一个真实的人填写了表单并点击了提交按钮。

在继续之前,我希望您考虑以下问题:

  1. 填写表格的人是普通用户还是恶意用户有关系吗?
  2. 或者,或者,如果一个脚本填写了表格?

两者的答案都是:不,不是。您应该始终为最坏的情况做好准备:默认情况下,所有输入的数据都是不安全的。有趣的是,有一个完整的对话与我之前的陈述有关:已知的已知、已知的未知和未知的未知。我不会在本文中讨论它,但是如果您有兴趣,请在评论部分告诉我。记住这一点,让我们继续!

在这个领域和上下文中,数据清理意味着:删除(或转换)任何具有恶意目的的数据(即字符)。换句话说,您希望数据在验证之前是安全的。但是,您应该始终考虑可用性和实用的方法。鉴于我们正在处理电子邮件地址输入字段,我们不能简单地从收到的输入中删除数据。因此,如果数据不合适,我们应该停止与数据相关的进程并向用户返回消息;消息应该提醒用户可以使用的字符(正面反馈)和/或在这种情况下,电子邮件地址的标准语法。

请记住,与数据相关的进程应始终在受信任的系统(例如后端)上进行,否则它们可能会被恶意用户/脚本禁用/绕过(例如前端)。

输入示例:

example<script>alert('Tacos!');</script>@domain.com

通过阅读上面的输入,我们可以直接判断这肯定不是电子邮件地址,而且它正试图通过数据传递脚本有效负载。但是,这种欣赏来自我们的视觉解读。

从编码的角度来看,应该通过应用以下前提来实施数据清理:什么是允许的?这也称为允许列表。建议在阻止列表的前提下使用这种方法:什么是不允许的?原因很简单:对于允许的和不允许的,你有一组已知的有限可能性。

在任何编码语言中实现允许列表的最有效方法可能是使用regex。

Golang 正则表达式示例:

package main

import (
	"fmt"
	"regexp"
)

func main() {
	input := "example<script>alert('Injected!');</script>@domain.com"

	re := regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*#34;)

	fmt.Printf("Pattern: %v\n", re.String()) // print pattern	
	fmt.Printf("\nEmail: %v :%v\n", input, re.MatchString(input))
}

结果):

Pattern: ^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$

Email: example<script>alert('Injected!');</script>@domain.com :false

是的,所以,我们已经看到了如何使用 Golang 实现正则表达式。

是为了数据清理吗?不。

当您处理现实世界的应用程序时,您将不得不捕获其他类型的输入,具体取决于您的应用程序。因此,这里有六点需要考虑:

  1. 在执行数据清理之前始终执行数据规范化;规范化很重要,因为在 Unicode 中,同一个字符可以有许多不同的表示形式,这会对数据清理过程产生负面影响;请查看 Golang 编码示例的链接。
  2. 如果您接收路径(例如目录、链接等)作为输入,请在执行数据清理之前对其进行规范化;绝对或相对路径可用于恶意目的,因为它们可能包含文件链接,例如符号(软)链接、硬链接、快捷方式、阴影、别名和连接;因此,它们应该得到彻底的解决;此外,请记住您的方法并验证它是否适用于您预期的操作系统。

Golang 规范化示例:

package main

import (
	"fmt"
	"path/filepath"
)

func main() {
	input := "/usr/local/bin/kubectl"
	
	resolvedPath, _ := filepath.EvalSymlinks(input)

	fmt.Printf("Input: %v :%v\n", input, resolvedPath)
}

结果):

Input: /usr/local/bin/kubectl :/usr/local/Cellar/kubernetes-cli/1.17.2/bin/kubectl
  1. “默认情况下所有输入数据都是不安全的”假设也适用于隐藏的表单字段、URL、HTTP 标头内容等。
  2. 请注意,可以尝试对您的系统进行双重编码或其他形式的混淆攻击,并且可以通过规范化来解决它们。
  3. 检查空字节:<%00>。
  4. 检查换行符。

数据清理结束后,应进行输入验证。正如术语明确指出的那样,输入验证确保数据遵守适用于/定义为一种输入类型的规则。这意味着什么……如果一种输入与知识领域或业务规则相关联,那么,应该强制执行其中规定的任何特征。对于我们根据存储能力或处理目的定义的规则也是如此:例如,我们允许为此类输入存储多少字符。

为了理解输入验证,让我们考虑一个有表单的网站,并且在表单中只有一个输入字段first name。同样,为了简单起见,我们将对表单的使用/填写做出与之前相同的假设。

输入示例:

John Alejandro Dumas Patricio O'Neil

这是一个非常有趣的例子。技术已经足以连接世界大部分地区,这在我们提供服务时产生了巨大影响。让我们从数据清理的角度开始。某些实现不允许使用 <'> 作为名字的一部分。就个人而言,我认为这没有考虑到全球化和连通性。用户不需要从外国访问网站,他/她的名字就不会符合“预期”的限制。我鼓励您阅读这篇文章,以便您做出适当的决定:世界各地的个人姓名

话虽如此,在数据清理之后可以进行什么样的输入验证?假设我们的数据存储中的名字有 30 个字符空间的限制。这个输入是否有效?

Golang 示例:

package main

import (
	"fmt"
)

func main() {
	input := "John Alejandro Dumas Patricio O'Neil"

	fmt.Printf("First name: %v :%d\n", input, len(input))
}

结果):

First name: John Alejandro Dumas Patricio O'Neil :36

从上面的结果中,我们可以看出它不是一个有效的输入,因为它超过了允许的最大字符数。请注意,上面的实现是一个非常简单的实现,它也可以使用正则表达式来执行。我认为代码应该尽可能简单,但这取决于你想要实现你的方法有多“花哨”。

话虽如此,在输入验证方面还有几点需要您考虑:

  1. 无论您实现什么输入验证功能/方法,都让它们集中可用;这也适用于数据清理;理由是您希望在您的应用程序和团队中使用相同级别的标准。
  2. 所有验证失败都应导致输入拒绝。
  3. 验证数据类型和数据范围;确保在适当的时候进行边界检查。

结论

我们现在已经涵盖了这两个术语,那么它们与 OWASP Top 10 有什么关系呢?

输入验证和数据清理与以下内容直接相关:

  • A1:注射
  • A4:XML 外部实体 (XXE)
  • A7:跨站脚本(XSS)

在下一篇文章中,我将介绍解决输出编码后的 OWASP 十大风险。

延伸阅读:

  • 十大安全编码实践
  • 前 25 个软件错误

希望您发现本教程很有用,如果您这样做了,或者如果您需要进一步的帮助,请不要犹豫,在下面的评论部分告诉我!再次感谢您的宝贵时间!


最近发表
标签列表