Symfony Panther - 访问安全的 iframe?

Posted

技术标签:

【中文标题】Symfony Panther - 访问安全的 iframe?【英文标题】:Symfony Panther - Access a secure iframe? 【发布时间】:2021-07-07 13:46:49 【问题描述】:

我正在尝试在我的 Symfony 5 应用程序中使用 Panther 来填写 Stripe 支付表单。我的 Stripe 字段由 Stripe 本身从我的表单中生成的 iframe 管理。

(查看 Stripe Elements 表单示例的第二个示例:https://stripe.dev/elements-examples/,这些字段位于 Stripe 托管的 iframe 中。这与我自己的表单相同)

<form>

  // input in main iframe
  <div class='row'>
  <div class='field'>
      <input id="example2-address" data-tid="elements_examples.form.address_placeholder" class="input empty" type="text" placeholder="185 Berry St" required="" autocomplete="address-line1">
    </div>
  </div>
  
  //stripe iframe
  <div class='row'>
    <div class='field'>
      <iframe name='__privateStripeFrame9208'>
        <html>
          <body>
            <form class='ElementsApp is-empty'>
              <input class="InputElement is-empty Input Input--empty" autocomplete="cc-number" autocorrect="off" spellcheck="false" type="text" name="cardnumber" data-elements-stable-field-name="cardNumber" inputmode="numeric" aria-label="Credit or debit card number" placeholder="1234 1234 1234 1234" aria-invalid="false" value="">
            </form>
          </body>
        </html>
      </iframe>
    </div>
  </div>
</form>
//Get iframe
$creditCardFrame = $this->client->findElement(WebDriverBy::cssSelector("#card-number > .__PrivateStripeElement > iframe"));

// returns : "iframe" and "__privateStripeFrame6225"
var_dump($creditCardFrame->getTagName(), $creditCardFrame->getAttribute('name'));

// Switch to iframe. (It should work no ?)
$this->client->switchTo()->frame($creditCardFrame);

// Trying to send keys in my own input (not a stripe field. It's on the default iframe). And I can.
$this->client->findElement(WebDriverBy::name('card-owner'))->sendKeys('my name');

// Trying to send keys in the cardnumber input (in a stripe iframe). Can't locate it.
$this->client->findElement(WebDriverBy::name('cardnumber'))->sendKeys("4242 4242 4242 4242");

这些 iframe 似乎受到保护,因为当我切换到其中一个 iframe 时,看起来我停留在我的默认框架上,并且我无法访问输入 Stripe 的框架。在我看来,这是因为这些是安全的。

我本来想给你一个错误,但问题是 switchTo() 方法没有被编程为返回错误。

验证它是否成功的唯一方法是尝试填写实际在那个 iframe 中的字段,我尝试过的东西,给了我错误

“找不到元素...”

但是,如果我尝试填写 默认 iframe 中的字段,它会起作用,这意味着 iframe 没有发生变化。

正如您在上面的代码中看到的那样,我确保我用这个指向一个 iframe:

// returns : "iframe" and "__privateStripeFrame6225"
var_dump($creditCardFrame->getTagName(), $creditCardFrame->getAttribute('name'));

我根据这个问题 https://github.com/symfony/panther/issues/446 检查了这是否是正确的方法,但我不明白为什么我会做错。

这就是为什么我怀疑 iframe 是安全的,阻止我访问它

有没有办法访问它?

【问题讨论】:

那么当您说“无法访问”时,究竟出了什么问题?一个错误?出乎意料的输出?请明确和具体。与其告诉我们某事没有发生,不如告诉我们您希望它做什么,然后告诉我们它实际上做了什么——这样会提供更多信息。 我很想给你一个错误,但问题是 switchTo () 方法没有被编程为返回错误。验证它是否成功的唯一方法是尝试填写一个实际在该 iframe 中的字段,我尝试过,给我错误 "Could not locate element ..." 。但是,如果我尝试填写默认 iframe 中的字段,它会起作用,这意味着 iframe 更改没有发生。我将更新我的第一篇文章以使其更清晰。 (更新后) 所以这是第一个返回该错误的findElement 调用,对吗?您确定元素名称正确吗?您向我们展示的 HTML 实际上并没有明确 iframe 中的 HTML 是什么样子。 不,这是最后一个。第一个findElement() 将 iframe 的元素返回给我。然后switchTo() 不会向我返回任何错误。然后,第二个findElement() 确实找到了该元素(但它对应于主 iframe 中存在的一个元素,因此它不起作用)。最后,最后一个findElement()给我一个错误“Could not locate element ...”关于HTML代码的细节,你可以在这个地址查看第二个例子:stripe.dev/elements-examples 对不起,任何相关的 HTML 都需要在问题中显示 here。这就是这个网站的工作方式——一个与问题相关的完整信息库,不依赖可能会改变或消失的外部资源,也不依赖志愿者去翻阅一大堆源代码来找到你具体在说什么关于并且已经知道。请把相关的 HTML 放在这里给我们。谢谢。 【参考方案1】:

无法访问 Stripe Elements iframe 的内容。 Stripe Elements 使用的 iframe 旨在防止您通过设计来访问其内容,以便reduce your PCI compliance burden(已添加重点):

对于已开发自己的集成并使用Checkout 或Stripe.js and Elements 从客户那里收集卡详细信息的用户,您有资格使用最简单的 PCI 验证方法:SAQ A。Stripe 会自动创建一个组合的 SAQ A和您的合规证明 (AoC),您可以在您帐户的 compliance settings 中下载,您无需采取任何行动来提交您的 PCI 合规性证明。

这是可能的,因为 Checkout 和 Elements 将所有包含卡片数据的表单输入都托管在从 Stripe 的域(而不是您的域)提供的 iframe 中,因此您客户的卡片信息永远不会接触到您的服务器

Browsers do not allow access to iframes from another origin 默认情况下。有 ways 可以使用 iframe 进行跨域通信,但它需要 iframe 内的代码来侦听和/或响应发送给它的消息,而 Stripe 的 iframe 没有此代码。

【讨论】:

以上是关于Symfony Panther - 访问安全的 iframe?的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 - 添加控制器安全性以限制用户对特定博客的访问

如果安全拒绝某个角色的访问,则在 Symfony3 中触发一个 Jquery 函数

Symfony2 - 将安全访问控制设置为只允许匿名身份验证

Symfony2 - 为用户和类别使用控制器安全性

Symfony - 安全/路由设置以启用受密码保护的用户页面

Symfony 4 - 安全性 - 从多个防火墙相互共享上下文