我可以从其他网站呈现表单吗?

时间:2010-10-16 06:42:12

标签: php security forms csrf

我在网站A上有一个用户,我需要将他登录到网站B(不在我的控制之下),但不会损害他在网站B上的密码。网站B没有API,这使得它比应该。

我的第一个选择是在网站A上呈现我自己的表格,用户在我的表格中输入他的网站B密码,我以某种方式安全地将他的网站B密码传递给网站B以登录他。这意味着我必须首先通过密码从客户端安全地发送到我的服务器,然后再次从我的服务器安全地传递到最终网站。这就是我猜我必须要做的,但我没有计划如何安全地实现这两个跳,所以我担心我可能会以某种方式暴露用户的密码。

所以我想到了第二个选项,就是将同一个网站B从网站B渲染到我的网站上。但是网站B上的表格是较大页面的一部分,所以可以这样做吗?

  • 如何从完整页面的代码中隔离表单本身的代码
  • 如何在我的网站上展示表格。我希望用户看到它。 iframe浮现在脑海,但从未使用过它
  • 当用户点击提交按钮或者我的网站上的表单以某种方式使其无效时,表单仍然有效

这是我想到的两种不同的解决方案。我欢迎他们每个人的答案,并欢迎提出可能更容易的替代第三种方法的答案。

7 个答案:

答案 0 :(得分:7)

只要您在自己的网站上使用SSL,就不会有损害用户密码的重大风险(除非您正在进行某种金融交易,请澄清)。

我的建议是,不要复制他们的表格。而是复制该表单生成的HTTP POST。您可以完全以编程方式执行此操作,用户永远不会离开您的站点,但(在大多数情况下)结果将是用户也登录到他们的站点。

如果要处理某种散列字段,请以表格形式(以编程方式)请求其表单页并使用您收到的任何值将返回发送到第二个站点,以便请求验证。他们的服务器不知道请求不是来自浏览器(实际上,如果您愿意,可以将用户代理添加到HTTP头中)。

我已经使用这种方法来对抗Verizon的网站和LinkedIn(两者都是出于合法目的)并且有效。

回顾一下:

  1. 了解HTTP POST的结构。

  2. 将登录表单添加到您的网站。

  3. 在您的代码中处理请求,使其看起来像POST 网站预计。

  4. 从您的代码发布到他们的网站。

  5. 在您的网站上显示对用户的响应(如果需要), 重定向,无论如何。

答案 1 :(得分:3)

这完全取决于您要发布的服务器如何处理CSRF [跨站点请求伪造],因为这基本上就是您正在做的事情。例如,如果他们使用的是相对较新的Django,那么来自外部服务器的POST请求将默认失败,除非它们包含csrf cookie值。

如果您可以控制要发布的服务器,则可以解决这个问题。

答案 2 :(得分:3)

我会尝试概述一个解决方案,但它可能不正确,甚至不是你想要的,这绝对是不切实际的。

根据我对XSRF的了解,如果目标网站完成了作业,您将无法模仿您域名中的表单提交。

除了目标站点之外,唯一可以访问用户凭据的是浏览器。所以你真正需要做的是成为一个浏览器。这意味着您必须说服用户他可以将您的登录信息提供给其他站点。我不知道你怎么能这样做,我不相信那样的东西。 (另一种选择是欺骗他(网络钓鱼),但这是非法的,我认为你甚至不会考虑它。)

在您设法说服用户向您提供他的数据后,您仍然必须像浏览器一样行事。您必须实现一个系统,用于为每个用户存储cookie,以便在您登录时创建会话。

执行此操作后,您将使用用户的数据登录,但用户不会。因此,您还需要通过您的网站实现用户所需的任何其他操作。


我的建议:

与目标站点联系并设置可用于从站点对用户进行身份验证的协议。有一些非常酷的iframe技术可以做到这一点。阅读这篇文章,获得一份称职的演讲http://softwareas.com/cross-domain-communication-with-iframes

或者让用户打开一个带有该站点登录页面的弹出窗口。确保弹出窗口显示地址栏。

答案 3 :(得分:2)

我并没有真正得到你想做的事情,如果只是登录网站你可能会做这样的事情:
Mainsite

<iframe id="logon" src="/logonto-other.html"></iframe>

/ logonto-other.html

<form onsubmit="top.logon.style.visibility='none';" action="http://other-site.com/login" method="post">
  <dl>
    <dt><label for="user">Name</label></dt>
      <dd><input name="user" />
    <dt><label for="pass">Password</label></dt>
      <dd><input name="pass" />
  </dl>
  <?php //code that acquires hash from other site
    // Don't know site B so can't write this one yet.
  ?>
  <input type="submit" value="Login" />
</form>

这样用户只会登录到其他网站,你的互动能力仍然有限(或者,我认为,我从未学过同源策略,因为我从未觉得有任何限制我的工作。也许今天的浏览器更严格。

关于“2跳”的事情,您的服务器A上是否有证书和SSL / HTTPS支持?服务器B有这个吗?你认为你可以让用户信任你的密码吗?一个提示是你添加了一个解释情况的段落和用户可以联系站点B的链接,以增加对它们施加OAuth和/或OpenID的压力吗?

即使您的服务器上没有HTTPS,也可以使用JavaScript或Java小程序来加密密码(在网络上的某个地方必须有PGP)。 ,如果浏览器地址栏变为绿色,则用户可以更轻松地决定是否信任您。

想要回答一些问题,我们是否可以知道B站点是什么?你究竟想做什么,也许我们可以一起解决这个问题。

祝你好运。

答案 4 :(得分:1)

要将表单与较大的页面隔离,请找到<form></form>标记,并仅复制它们之间的任何元素。现在将该表单放在您的页面上,其操作仍然指向它在原始网站上指向的URL。密码永远不会通过您的服务器。

答案 5 :(得分:1)

请参阅:Sockets

  1. 研究SiteB的登录表单HTML,以收集字段名称,期望值和操作URL的列表。
  2. 使用相同的字段名称在您自己的网站上重新制作表单。操作URL应指向您自己服务器上的处理脚本。此时需要注意的是,如果站点B在其登录表单页面加载时使用了一些特殊的令牌字段或cookie集。如果是这种情况,请使用套接字连接并获取Site B登录页面的新副本。你需要知道HTTP message standards and proper request body structure才能解决这个问题。然后,解析检索到的文本,以便在您自己的页面上使用令牌字段或cookie名称和值。
  3. 用户在表单上输入站点B的用户名和密码。在提交时,表单结果将传递给您的处理程序脚本。
  4. 您的处理程序脚本使用套接字作为常规POST请求连接到站点B的操作URL目标。此POST请求包括站点B在前几个步骤中给出的任何cookie和令牌名称/值。您需要再次遵循HTTP协议消息结构指南才能将其关闭。
  5. 网站B使用您的用户信息进行身份验证。您的处理程序脚本正坐在那里等待响应。
  6. 站点B响应处理程序脚本。您需要研究典型的响应,站点B返回知道如何解析任何响应文本(并再次学习如何解析HTTP消息),包括返回的cookie头。
  7. 您的处理程序脚本需要将与用户匹配的日志与站点B成功验证后返回的任何cookie值保持在一起。在将来对站点B的任何请求中,再次使用套接字作为用户进行篡改,并传递cookie头/ val用于将他们(IE:你的)登录会话ID发送到站点B.
  8. 请注意,您可能希望保持公开诚实的对话,了解您使用网站B做什么,或者您可以liable for civil action

答案 6 :(得分:0)

您所描述的场景可能很难实现。您面临的主要问题是如何将登录凭据发布到站点B,使得成功登录本身返回的cookie最终在用户的浏览器中并且属于站点B,这样站点B就可以获取它们。用户实际上在那里导航。

有些人建议将表单发布到服务器上的PHP文件中,然后让它从服务器到服务器进行登录。这个解决方案几乎不可行。即使站点B接受您的服务器 - 服务器登录(它可能会,因为您可以伪造任何您想要的浏览器),它将您的网络服务器将获取新的cookie,并且您的会话将与之关联的网络服务器的IP。即使您将cookie返回到浏览器,它也会将其保存到您的站点(站点A),并且在浏览器到达时不会将其提交到站点B,因此用户将保持注销状态B站点。

因此,您在这里唯一能做的就是在您的服务器上托管其网站的登录表单。这意味着您必须向浏览器发送一个表单,该表单的ACTION指向站点B的登录表单。这也意味着无论何时用户单击登录按钮,控件都会转移到站点B:用户将离开您的站点而您将失去他。

第二种方法存在两个主要技术问题:一种是站点B可能具有XSS预防功能,实际上可能会阻止您将内容发布到其登录页面。另一个问题是,如果您的网站使用SSL,浏览器会唠叨您将表单提交到其他网站的大量时间。这些都不是你自己能解决的问题。

唯一干净的解决方案是真正与网站B坐下来并制定一些关于通用身份验证或至少是身份验证API的计划。您可以尝试使用表格交叉解决方案,但您可能会遇到不喜欢的问题。