防止 JSON 域欺骗
Preventing JSON domain spoofing
场景如下。客户已经拥有一个电子商务网站,他们正在该网站上收集送货地址信息和信用卡数据。但是,他们注册了一项 SaaS 服务,该服务允许他们轻松更改信用卡表格 ,以便将全名和电子邮件 (不是信用卡信息)收集到营销系统中以用于其他目的。因此,他们从 SaaS 服务将 jQuery 片段粘贴到他们的页面中,并向他们的表单和表单字段标签添加一些 "data-" 属性,以便 SaaS 服务知道要拦截什么以及将哪个 SaaS 帐户拦截到哪里post数据。
好的,但是随后出现了安全问题。假设我们在该 SaaS 系统中有两个独立的客户。一个叫 Jack,拥有 jack.com,他的帐户 ID 是 100001。另一个叫 Nancy,nancy.com,和 100002。Jack 可以将片段添加到他的表单中并添加一些 "data-" 属性,但随后搞砸了,将其中一个数据属性中的帐户 ID 设置为 100002 而不是 100001。这意味着 Nancy 会突然在她的帐户中看到 Jack 的数据。不好!当然,解决方法是在 Jack 的 SaaS 帐户中进行一些设置,以便他只接受来自 jack.com 的数据,而 Nancy 只接受来自 nancy.com.
的数据
但是随后发生了潜在的漏洞利用。黑客所要做的就是在他自己的服务器上创建一个恶搞页面,他在其中形成类似 JSON,然后通过在他的工作站上更改 /etc/hosts 文件,使他看起来像 jack.com。然后他可以将成千上万的虚假营销表单信息发送到 Jack 的帐户中,因为 SaaS 服务认为这些信息来自 jack.com.
我可以在 jQuery 代码或 SaaS 服务使用的 PHP 代码中做些什么,以确保黑客无法像那样欺骗并且只有 Jack 是真实的客户数据已发送?
已回答的问题
Q1。 "How do you identify Jack and Nancy? By domain?"
A1。杰克有他的域名 jack.com。 Nancy 有她的域名 nancy.com。每个人都使用这种营销 SaaS 服务,但每个人也在选择他们在注册 SaaS 服务之前已经拥有的电子商务表格。他们在 SaaS 文档中被告知,"Just drop the scraper.js in your form page and add these data- tags to your form tag and html input, textarea, and select tags so that the scraper.js can intercept those form submits temporarily, glean the marketing data (full name and email, let's say) from that form, and then let that form submit on its workflow that you already had. The data- attributes would identify which account is to be used, as well as which marketing campaign and sub-campaign where this data should be stored at the SaaS service." 然而,在 scraper.js 的 jQuery 中,它将在 JSON 中传递 location.href 属性 以便它知道使用了哪个域——在此特定实例中为 jack.com 或 nancy.com。问题是 - location.href 可能会被黑客欺骗,他在他的工作站上为 jack.com 设置了一个 /etc/hosts 文件条目 127.0.0.1 并运行相同的副本 JSON代码。
Q2。 "What if you could use a callback mechanism from SaaS.com to jack.com? So, one of your data- attributes would specify the callback function to receive data back from SaaS.com, and then only save data when it gets the right response?"
A2。现在这是一个有趣的观点。是的,所以我想在 jack.com 上放置一个额外的 PHP 页面,它发出 "OK"。当 SaaS.com 从 jack.com 收到 JSON 数据 post 时,它向 jack.com 上的第二个 PHP 回调页面发送请求 file_get_contents() 以确保它不仅获得 OK 响应,而且获得 IP 地址和 SSL 证书数据的匹配。如果两者不同,则请求很可能是虚假的黑客请求,并且交易可以安全记录并拒绝。 (我可以很容易地进行 IP 地址验证,但我不确定如何在 PHP 中验证相同的两个 SSL 证书,如果这甚至被允许或可能的话。)当然,IP 地址可以被欺骗。
另一个安全层是第二个 PHP 页面可以使用 public/private 密钥交换在 SaaS.com 和 jack.com 之间进行通信检查,而不是简单地发出 "OK".
Q3。 "Why would you want to intercept payment information and send that off through Javascript?"
A3。绝对不。从未在此问题中指定发送付款信息。而是说全名和电子邮件之类的内容。是的,为了安全地发送数据,也需要使用 SSL 通信。而且,我们必须使用 JSONP to get around the CORS problem.
Q4。 "Wouldn't that require jack.com to have everything saved in a database for verification? If so, why bother with the SaaS app?"
A4。没有。一点也不。查看答案A2。使用该机制,SaaS 应用程序接收数据,但在发生两件事之前不信任它:
它回调 jack.com 到第二个页面,并确保它返回的响应与第一个发送表单数据的响应具有相同的 IP 地址。
它会在第二个页面中进行 public/private 密钥交换检查(黑客显然无法欺骗,除非他们有服务器访问权限)以确保没有发生 IP 欺骗。
Q5。等一下。 A2和A4有问题。初始发送请求的 IP 地址将来自用户的工作站,而不是服务器。因此,您无法以这种方式验证 IP。您必须使用另一种机制来验证有人在 jack.com 填写了表格,并且它不是来自黑客欺骗 jack.com.
A5。你是绝对正确的。我猜是因为我在另一个项目上稍微分心了,所以忘记了。我得再考虑一下。
TL;DR:如果您使用纯客户端集成(只是 javascript),则无法完全保护请求。
Accidentally/intentionally 发送数据到错误的客户端
您可以通过使用非连续的随机 UUID 作为帐户 ID 来缓解这种情况。例如,如果帐户 ID 看起来像 100001,那么有人可能会尝试使用帐户 ID 100002;但是,如果帐户 ID 看起来像 c3f80e491d44cd91664a0459a0777ed01
,从统计角度来看,某人不太可能将数据发送到未知帐户。
有意 spam/fictional 提交
这是在 Internet 上存储数据的任何形式的问题;如果没有一些服务器端代码的帮助,我不知道有什么办法可以解决这个问题。
您可以生成一个一次性令牌以包含在 json 有效负载中 - 这可以类似于通过 HMAC 保护的过时 JWT 令牌,或者使用共享密钥加密的一组消息然后被SAAS服务器去重
如果您打算开始涉及服务器端编程,那么这个额外的协商过程就变得有点无关紧要了 - 只需给电子商务网站一个 API 密钥,然后让他们 post 收到订单时的客户信息。
场景如下。客户已经拥有一个电子商务网站,他们正在该网站上收集送货地址信息和信用卡数据。但是,他们注册了一项 SaaS 服务,该服务允许他们轻松更改信用卡表格 ,以便将全名和电子邮件 (不是信用卡信息)收集到营销系统中以用于其他目的。因此,他们从 SaaS 服务将 jQuery 片段粘贴到他们的页面中,并向他们的表单和表单字段标签添加一些 "data-" 属性,以便 SaaS 服务知道要拦截什么以及将哪个 SaaS 帐户拦截到哪里post数据。
好的,但是随后出现了安全问题。假设我们在该 SaaS 系统中有两个独立的客户。一个叫 Jack,拥有 jack.com,他的帐户 ID 是 100001。另一个叫 Nancy,nancy.com,和 100002。Jack 可以将片段添加到他的表单中并添加一些 "data-" 属性,但随后搞砸了,将其中一个数据属性中的帐户 ID 设置为 100002 而不是 100001。这意味着 Nancy 会突然在她的帐户中看到 Jack 的数据。不好!当然,解决方法是在 Jack 的 SaaS 帐户中进行一些设置,以便他只接受来自 jack.com 的数据,而 Nancy 只接受来自 nancy.com.
的数据但是随后发生了潜在的漏洞利用。黑客所要做的就是在他自己的服务器上创建一个恶搞页面,他在其中形成类似 JSON,然后通过在他的工作站上更改 /etc/hosts 文件,使他看起来像 jack.com。然后他可以将成千上万的虚假营销表单信息发送到 Jack 的帐户中,因为 SaaS 服务认为这些信息来自 jack.com.
我可以在 jQuery 代码或 SaaS 服务使用的 PHP 代码中做些什么,以确保黑客无法像那样欺骗并且只有 Jack 是真实的客户数据已发送?
已回答的问题
Q1。 "How do you identify Jack and Nancy? By domain?"
A1。杰克有他的域名 jack.com。 Nancy 有她的域名 nancy.com。每个人都使用这种营销 SaaS 服务,但每个人也在选择他们在注册 SaaS 服务之前已经拥有的电子商务表格。他们在 SaaS 文档中被告知,"Just drop the scraper.js in your form page and add these data- tags to your form tag and html input, textarea, and select tags so that the scraper.js can intercept those form submits temporarily, glean the marketing data (full name and email, let's say) from that form, and then let that form submit on its workflow that you already had. The data- attributes would identify which account is to be used, as well as which marketing campaign and sub-campaign where this data should be stored at the SaaS service." 然而,在 scraper.js 的 jQuery 中,它将在 JSON 中传递 location.href 属性 以便它知道使用了哪个域——在此特定实例中为 jack.com 或 nancy.com。问题是 - location.href 可能会被黑客欺骗,他在他的工作站上为 jack.com 设置了一个 /etc/hosts 文件条目 127.0.0.1 并运行相同的副本 JSON代码。
Q2。 "What if you could use a callback mechanism from SaaS.com to jack.com? So, one of your data- attributes would specify the callback function to receive data back from SaaS.com, and then only save data when it gets the right response?"
A2。现在这是一个有趣的观点。是的,所以我想在 jack.com 上放置一个额外的 PHP 页面,它发出 "OK"。当 SaaS.com 从 jack.com 收到 JSON 数据 post 时,它向 jack.com 上的第二个 PHP 回调页面发送请求 file_get_contents() 以确保它不仅获得 OK 响应,而且获得 IP 地址和 SSL 证书数据的匹配。如果两者不同,则请求很可能是虚假的黑客请求,并且交易可以安全记录并拒绝。 (我可以很容易地进行 IP 地址验证,但我不确定如何在 PHP 中验证相同的两个 SSL 证书,如果这甚至被允许或可能的话。)当然,IP 地址可以被欺骗。
另一个安全层是第二个 PHP 页面可以使用 public/private 密钥交换在 SaaS.com 和 jack.com 之间进行通信检查,而不是简单地发出 "OK".
Q3。 "Why would you want to intercept payment information and send that off through Javascript?"
A3。绝对不。从未在此问题中指定发送付款信息。而是说全名和电子邮件之类的内容。是的,为了安全地发送数据,也需要使用 SSL 通信。而且,我们必须使用 JSONP to get around the CORS problem.
Q4。 "Wouldn't that require jack.com to have everything saved in a database for verification? If so, why bother with the SaaS app?"
A4。没有。一点也不。查看答案A2。使用该机制,SaaS 应用程序接收数据,但在发生两件事之前不信任它:
它回调 jack.com 到第二个页面,并确保它返回的响应与第一个发送表单数据的响应具有相同的 IP 地址。
它会在第二个页面中进行 public/private 密钥交换检查(黑客显然无法欺骗,除非他们有服务器访问权限)以确保没有发生 IP 欺骗。
Q5。等一下。 A2和A4有问题。初始发送请求的 IP 地址将来自用户的工作站,而不是服务器。因此,您无法以这种方式验证 IP。您必须使用另一种机制来验证有人在 jack.com 填写了表格,并且它不是来自黑客欺骗 jack.com.
A5。你是绝对正确的。我猜是因为我在另一个项目上稍微分心了,所以忘记了。我得再考虑一下。
TL;DR:如果您使用纯客户端集成(只是 javascript),则无法完全保护请求。
Accidentally/intentionally 发送数据到错误的客户端
您可以通过使用非连续的随机 UUID 作为帐户 ID 来缓解这种情况。例如,如果帐户 ID 看起来像 100001,那么有人可能会尝试使用帐户 ID 100002;但是,如果帐户 ID 看起来像 c3f80e491d44cd91664a0459a0777ed01
,从统计角度来看,某人不太可能将数据发送到未知帐户。
有意 spam/fictional 提交
这是在 Internet 上存储数据的任何形式的问题;如果没有一些服务器端代码的帮助,我不知道有什么办法可以解决这个问题。
您可以生成一个一次性令牌以包含在 json 有效负载中 - 这可以类似于通过 HMAC 保护的过时 JWT 令牌,或者使用共享密钥加密的一组消息然后被SAAS服务器去重
如果您打算开始涉及服务器端编程,那么这个额外的协商过程就变得有点无关紧要了 - 只需给电子商务网站一个 API 密钥,然后让他们 post 收到订单时的客户信息。