papasmurf papasmurf - 9 days ago 5
Ruby Question

How to confirm a JavaScript popup using Nokgiri or Mechanize

I'm running a script that will open up on my localhost. My local server is a vulnerable web app test suite.

I'm trying to confirm a XSS popup from a JavaScript alert. For example:

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


I need to confirm the popup happened using either Mechanize or Nokogiri. Is it possible to confirm that the popup is there with Nokogiri or Mechanize?

For example:

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

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

Answer

Definitely not, and that's because neither Mechanize or Nokogiri run Javascript.

Instead, you could use Selenium.

Something like this:

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

Usage:

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 

There are some tricky things with Selenium's handling of alerts, though.

There's no way for your code to detect the type (prompt, confirm, or alert) without using something like rescue or try. Everything is reached through switch_to.alert.

Also, if your browser has an alert open you cannot run any subsequent commands unless you handle alert. Say you try and navigate.to while the alert is open; you'd get an error along the lines of You didn't handle the alert and your navigate.to command would have to be rerun. When this error is raised, the alert object will be lost as well.

It's a little unappealing to use rescue as a control structure in this way but I'm not aware of any other option

Comments