在第三方调用的WebHook中对用户进行身份验证


Authenticate User In Third Party Invoked WebHook

我有一个

  1. 用户可能登录也可能不登录我的网站
  2. 用户向第三方服务提交表格,以及
  3. 第三方服务完成它的工作,然后在我的站点上调用一个"webhook",转发所有$_POST数据

因此,举例说明:

    +---------------------+         +---------------------------+
    | mysite.com/form.php |-------->| thirdparty.com/submit.php |
    +---------------------+         +---------------------------+
                                                  |
                                                  v
                                    +---------------------------+
                                    |   mysite.com/webhook.php  |
                                    +---------------------------+

如果用户在提交表单时已登录,那么我如何在webhook中告知并验证这一事实

例如,我可以天真地设置一个隐藏字段

<input type="hidden" name="loggedOn" value="true" />

但任何人都可以恶搞。我想我可能会通过用户的密码散列,

<input type="hidden" name="passwordHash" value="$2a$08$Lg5XF1Tt.X5TGyfb43vBBeEFZm4GTXQhKQ6SY6emkcnhAGT8KfxFS" />

有效地使webhook再次"登录",但这不可能是正确的,因为这会将用户的密码哈希暴露给客户端。

我认为使用会话机制一定有更好的方法可以做到这一点,但我对会话是新手。也许我错过了合适的词汇?有人能给我指引正确的方向吗?谢谢


编辑:

经过进一步的研究,我认为正确的方法是将隐藏表单字段sid设置为会话id session_id(),以便将其传递给webhook,webhook将使用会话id继续会话session_id($_POST['sid']); session_start();。我现在的问题是,这是否是规范的(安全的)解决方案。

用户的SessionID无论如何都是已知的,并且无论如何都可以被中间人方法嗅探。因此,如果你担心安全可能会被"黑客入侵"(而且你不能使用SSL),那么你会实现IP跟踪、代理跟踪等。所有细节都可能被欺骗或伪造,甚至可能更改错误会话(尽管很少,但移动设备上的IP除外),但这是一个额外的层。

因此,基本的解决方案是创建一个session_id,作为表单的一部分传递,然后按照您/Steve的建议使用它。

您不能使用IP或代理标头,因为这些标头已丢失。所以你需要看看你能用什么。

在复杂性和安全性不断增加的顺序中:

  1. 除了帖子之外,第三方网站是否向你传递了任何数据?检查收割台;你可能会发现他们通过发起IP、发起推荐人或代理。你可以把它们作为最简单的防御线——它们应该与原始数据(你可以存储在会话中)相匹配。

  2. 在网站上创建表单时,请创建另一个唯一ID并存储在会话中。将其传递到表单的隐藏字段中,当您从"thirdparty.com"获取表单数据时,您可以检查唯一ID是否与会话中的ID匹配。然后从会话中删除uniqueID,这意味着它只能使用一次。(这就是他在回答中提到的NONCE pd40。)

  3. 如果您可以使用javascript,那么在提交时捕获,也可以将详细信息发送到您的服务器。您的服务器将已在会话中包含详细信息。当"thirdparty.com"回复你时,打电话给会议,检查细节是否匹配。(如果你不想在会话中存储所有细节,你可以对其进行MD5——返回时MD5应该匹配)。你也可以给它加上时间戳——如果你不这样做的话;I don’’’’我不会在60秒内收到回复,然后事情进展有点慢[根据需要调整时间戳,但要慷慨]。

  4. 然而,我的首选(也是我们使用的)是让您自己的服务器接收表单数据,然后使用Curl向thirdparty.com生成POST请求。实际上不需要webhook——你只需要在继续处理自己之前检查响应——用户永远不会意识到有第三方被调用,交互是在你自己和服务器之间进行的。

此外,如果你真的很担心,记录下任何你认为"无效"的电话。你会发现,用户在做对之前会尝试黑客攻击几次,所以永远不要透露你已经认定他们是黑客(除非有假阳性的机会;所以要小心)并登录。如果你从一个IP收到5个无效请求(例如),那么你可以假设来自该IP的所有后续请求都是不可靠的,即使是好的。记录日志,这样你就可以监控了。

最后一点:SSL总是最好的,如果你能实现的话

希望这能让您了解可以实现的选项。

使用会话ID有助于跟踪谁提出了请求并提供一些安全保护。

你也可以考虑让每一个请求的第三方包含:

  • nonce用于检测重播
  • 用于检测旧请求的时间戳
  • 随每个请求发送的数字签名或hmac。您将对可能被篡改的任何值进行签名/散列,并在webhook中验证这些值

如果将用户会话存储在数据库中,这会更容易。当然,任何人都可以传递该表单(伪造它),但如果在触发"webhook"时,您在会话表中检查了有效的会话密钥,那么就可以继续了。