为什么在反序列化期间使用UTF-8编码比ASCII更好?

5
我想将代表RESTful网络服务响应的JSON文件反序列化为相应的类。我一直在使用System.Text.ASCIIEncoding.ASCII.GetBytes(ResponseString),并从Microsoft Docs上了解到,出于安全原因,使用UTF-8编码而不是ASCII更好。
现在我有点困惑,因为我不知道这两者之间(关于安全性问题)的真正区别。有人可以告诉我使用UTF-8而不是ASCII进行反序列化的实际优势吗?

5
你为什么要使用ASCII.GetBytes呢?在反序列化JSON(或任何其他格式)时不需要这样做,你需要一个类似Json.NET或System.Text.Json的JSON序列化程序。如果文本中包含7位US-ASCII范围之外的任何字符,则不能使用ASCII。该范围之外的任何字符都将被替换为“?”。“大于U+007F的任何Unicode字符都会转换为ASCII问号(“?”)”。 - Panagiotis Kanavos
4
出于安全原因——想象一下,如果您的超强密码被替换成了 ????? - Panagiotis Kanavos
1
非常感谢!当然我正在使用Json序列化器,很抱歉没有提到它,我的兴趣是我使用ASCII时会面临哪些安全风险!无论如何,感谢您的评论,现在我对安全问题有了一个想法!例如,如果我使用ASCII编码,我会冒读取响应中ASCII无法读取的某些字符的风险吗? - Warios
2
@Marios ASCII 可以描述 128 个独特的代码点;UTF-8 可以描述 1.1M 个独特的代码点。因此... ASCII 只能处理可能值的 0.015%。好吧,实际上分布不均匀,但是...你懂的。 - Marc Gravell
@MarcGravell 现在我明白了,非常感谢!事实上,这意味着在我们这个时代使用ASCII编码这种类型的数据是令人尴尬的! - Warios
显示剩余4条评论
2个回答

8

编码器的最终目的是获取你原本要获取的数据。ASCII仅定义了一个非常小的7位值范围; 任何超出此范围的内容都无法处理,你可能会得到垃圾或?,如果载荷包含一些甚至存在远程有趣文本

现在; 当你的应用程序遇到无法处理的数据时会发生什么?我们不知道,但这确实可能会在你无法处理负载时导致安全问题。

在这个连接世界中,如果由于右到左标记而无法正确存储和显示客户名称等信息(或者将其名称倒置打印),那就真的很尴尬了。世界上大多数人每天使用ASCII之外的东西。

由于UTF-8是ASCII的超集,并且UTF-8基本上赢得了编码战:您最好只使用UTF-8。


1

由于并非每个字节序列都是有效的编码字符串,因此会出现不希望的转换而导致漏洞,这些漏洞可以被聪明的攻击者利用。

让我引用一篇黑帽白皮书关于Unicode安全的内容:

字符编码和Unicode标准也存在漏洞。通常这些漏洞与实际使用中的实现相关。以下分类可能会使应用程序容易受到攻击,特别是对于那些没有构建以防止相关攻击的应用程序: - 视觉欺骗 - 最佳匹配映射 - 字符集转换和字符映射 - 标准化 - 过长的UTF-8规范化 - 过度消耗 - 字符替换 - 字符删除 - 大小写处理 - 缓冲区溢出 - 控制语法 - 字符集不匹配
考虑以下示例。在U+017F LATIN SMALL LETTER LONG S的情况下,大写和规范化操作将字符转换为完全不同的值。在某些情况下,可以利用这种行为创建跨站点脚本或其他攻击场景。
当发生最佳匹配映射时,软件漏洞就会出现。以下是一些例子: - 最佳匹配映射不可逆,因此数据无法恢复。 - 可以操纵字符以绕过字符串处理过滤器,例如跨站点脚本(XSS)过滤器、WAF和IDS设备。 - 可以操纵字符以滥用软件中的逻辑。例如,当字符可用于访问文件系统时。在这种情况下,最佳匹配映射到类似../或file://的字符可能会造成破坏。
如果您实际上正在存储二进制数据考虑使用base64或十六进制代替

感谢您的努力!实际上,当您指出来后,我清楚地意识到使用ASCII编码这种类型的数据有点天真和风险太大! - Warios

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接