3

我正在运行一个将在我的本地主机上打开的脚本。我的本地服务器是一个易受攻击的 Web 应用程序测试套件。

我正在尝试从 JavaScript 警报中确认 XSS 弹出窗口。例如:

http://127.0.0.1:65412/v?=0.2<script>alert("TEST");</script>

我需要使用 Mechanize 或 Nokogiri 确认弹出窗口是否发生。是否可以通过 Nokogiri 或 Mechanize 确认弹出窗口是否存在?

例如:

def page(site)
  Nokogiri::HTML(RestClient.get(site))
end

puts page('http://127.0.0.1:65412/v?=0.2<script>alert("TEST");</script>')
4

2 回答 2

2

Nokogiri 和 Mechanize 因为它建立在 Nokogiri 之上,所以可以解析 HTML 并返回<script>标签的内容。标签的内容是文本,所以此时有必要查看文本内部以找到您想要的内容:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<html>
<head>
<script>alert("TEST");</script>
</head>
</html>
EOT

script_content = doc.at('script').content # => "alert(\"TEST\");"

很容易检查此时是否存在子字符串:

script_content['alert("TEST");'] # => "alert(\"TEST\");"

或者:

!!script_content['alert("TEST");'] # => true

注意:Nokogiri 或 Mechanize 无法判断是否发生了弹出窗口,因为它会在浏览器运行 JavaScript 时发生。Nokogiri 或 Mechanize 都不理解或解释 JavaScript。只有像 Watir 这样的工具或解释 JavaScript 的工具才能做到这一点。

于 2016-11-27T01:53:24.067 回答
1

绝对不是,那是因为 Mechanize 和 Nokogiri 都没有运行 Javascript。

相反,您可以使用Selenium

像这样的东西:

require 'selenium-webdriver'

class AlertChecker
  Driver = Selenium::WebDriver.for :firefox
  def initialize(url)
    Driver.navigate.to url
  end
  def raise_alert(text)
    Driver.execute_script "alert('#{text}')"
    self
  end
  def safely_get_alert
    begin
      Driver.switch_to.alert
    rescue Selenium::WebDriver::Error::NoAlertOpenError
    end
  end 
end

用法:

alert_checker = AlertChecker.new("http://my.website")

alert = alert_checker.safely_get_alert
# => nil

alert_checker.raise_alert("hack")
alert = alert_checker.safely_get_alert
puts alert.text
# => 'hack'

# As far as I'm aware Selenium doesn't have a built-in way
# to tell you if it's an alert, confirm, or prompt.
# But you know it's a prompt, for example, you could also send
# keys before accepting or dismissing
alert.accept

alert = alert_checker.safely_get_alert
# => nil 

不过,Selenium 处理警报有一些棘手的问题。

如果不使用 or 之类的东西,您的代码无法检测到类型(提示、确认或警报rescuetry。一切都通过switch_to.alert.

此外,如果您的浏览器打开了警报,则除非您处理警报,否则您将无法运行任何后续命令。假设您navigate.to在警报打开时尝试;你会得到一个错误,你没有处理警报,你的navigate.to命令必须重新运行。引发此错误时,警报对象也将丢失。

以这种方式使用救援作为控制结构有点不吸引人,但我不知道有任何其他选择

于 2016-11-24T22:31:08.140 回答