只要您正确清理和处理输入,您就可以安全地允许 src 属性。为此,您应该首先通过有效 URL 字符的白名单对其进行清理,对其进行规范化,然后验证它是否指向有效图像。
您提到的白名单是第一步(也是重要的一步)。要实现白名单,只需删除对 URL 无效的每个字符。还要验证 URL 的格式是否正确,这意味着它指向用户应该能够访问的有效资源。例如,用户不应该通过传入file://sensitive.txt
或其他方式访问服务器上的本地文件。如果 http 或 https 是唯一应该使用的协议,请检查 URL 是否以这些协议开头。如果您特别偏执,您可能会完全拒绝该请求,因为很明显它已被篡改。白名单很重要,但单独的白名单并不能保证功能的安全。
规范化很重要,因为许多攻击依赖于提交最终将您带到某个位置的 URL,但可能会滥用计算机与生俱来的缺乏推理的能力来获取它不应该得到的东西。这也将有助于消除相同资源的重复路径,这可能会提高性能(或者至少允许您通过不重新检查自上次检查以来未更改的已知文件来提高性能。但请注意这一点,因为可以欺骗最后修改日期,以便攻击者可以在您已经“检查并信任”它之后交换恶意文件)。
要验证您指向的图像是否有效,请打开文件并读取前几个字节。不要简单地信任文件扩展名,尽管在打开文件之前先检查它(为了性能和安全)。每种图像格式都有特定的字节模式可供您检查。JPEG 是一个值得一看的好方法。恶意用户仍有可能将 shellcode 或其他攻击代码放入包含正确标头的图像文件中,但要做到这一点要困难得多。这将是一个性能瓶颈,因此如果您实施它,请进行适当的计划。