在数据方面,我对XSS有一个非常基本的问题。虽然常见的预防技术是对数据进行编码,但编码是否需要双向进行,即在服务器端,当它向浏览器发送一些响应时,或者在将数据发送到服务器之前,我们是否也需要进行编码(比如用户输入数据,如搜索字段(?
在数据插入页面DOM之前对其进行编码(严格来说,只有可能包括用户输入的数据,但很多时候它更容易应用于所有数据(。在不同的场景中,这意味着不同的事情,这会导致很多混乱。
要直接回答其中一个问题,在将数据发送到服务器之前,或者在将数据插入数据库或其他内容之前,不需要对数据进行编码。一般情况下,您不会在请求端对数据进行编码。原因是在复杂的应用程序中,您不知道数据将在哪里以及在什么上下文中呈现,对于不同的上下文,您可能需要不同的编码。输入层与此无关,但这不仅仅是一个架构问题,在知道如何渲染数据之前,您无法选择编码。
当然,这并不意味着你不把它编码成任何";输出";它在请求过程中直接进入。例如,如果你有一个SQL数据库,你可以应用编码来防止SQL注入,但这是通过使用适当的数据访问层、参数化查询等自动完成的。如果它在请求过程中进入xml,你也可以应用适当的xml编码,等等。但这与XSS无关,而是防止其他注入漏洞,这些事情很可能是由你的语言或框架自动完成的,除非你正在做一些不寻常或不太频繁的事情。
您还可以将输入验证应用于任何输入,您可以验证格式(例如电子邮件地址或日期(,也可以验证所需的字符集,等等
但总的来说,在没有任何实际编码的情况下,在从客户端接收数据时存储数据并没有错。事实上,在大多数情况下,这是正确的做法(见下文中的例外情况(。
然后,每当数据以任何方式输出,以HTML形式呈现,用于后端查询(可以是LDAP、SMTP、SQL或其他任何类型(时,您都会根据您在其中使用数据的上下文应用适当的编码。对于HTML,您会应用HTML编码,但对于javascript(HTML可以包含javascript块,这也适用!(,您会使用javascript编码。一般来说,这是一个输出。
话虽如此,还是有一些。。。好吧,让我们称之为特例。
现代javascript应用程序(如单页前端(可能在不与服务器通信的情况下管理大量数据。用户输入有时会被写得到处都是,等等。在这种情况下,每当SPA将内容插入页面DOM时,它的工作就是应用适当的编码。这主要意味着使用您选择的框架的安全设施,默认情况下,大多数现代框架都非常擅长这一点,但您需要知道实际编码的内容和方式,以防止XSS。在复杂的SPA中,这一点并不简单。可能最复杂的情况是,当你想故意从客户端接收html(比如你有一个html编辑器小部件(,将其保存到服务器上,然后再次在SPA中显示,可能在编辑时带有预览功能,但这是一个单独的(大(主题,需要小心。
";不在数据库中编码内容";规则可能是大型、复杂的遗留应用程序。有时,您无法保证数据的所有(遗留(前端都会应用正确的编码,因此您可能会决定在将数据写入数据库之前对其进行编码。这样做的问题是,您甚至无法正确地编写新代码,因为如果再次应用编码,数据将被双重编码,这也是错误的。