3

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>')
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
papasmurf
  • 303
  • 3
  • 9

2 Answers2

2

Nokogiri, and Mechanize because it is built on top of Nokogiri, can parse the HTML and return the <script> tag's contents. The tag's content is text so at that point it's necessary to look inside the text to find what you want:

require 'nokogiri'

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

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

It's easy to check to see if a sub-string exists at that point:

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

or:

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

Note: It's not possible with Nokogiri, or Mechanize, to tell if a pop-up occurred as that'd happen inside a browser as it runs the JavaScript. Neither Nokogiri or Mechanize understand or interpret JavaScript. Only a tool like Watir or that interprets JavaScript could do that.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
1

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

max pleaner
  • 26,189
  • 9
  • 66
  • 118
  • Well what about this, would there be a way to find it through the html? Like would there be a script tag to parse? – papasmurf Nov 25 '16 at 01:33
  • 1
    Probably the easiest way for sure to know the XSS occurs is to run the Javascript (cannot do with with Nokogiri / Mechanize). – max pleaner Nov 25 '16 at 01:41
  • Yeah I didn't think this was going to be easy – papasmurf Nov 25 '16 at 01:42
  • What do you mean to run the javascript? – papasmurf Nov 25 '16 at 14:35
  • 1
    Mechanize/Nokogiri just get the HTML. It includes Javascript, but that's never actually run. Like if you have a website that loads all its content through AJAX then you'd never see it. Selenium on the other hand uses an actual browser, so it can run the Javascript. – max pleaner Nov 25 '16 at 17:43
  • Really I just need to verify that the tag is there, if the tag is there then Nokogiri should be able to pick it up correct? – papasmurf Nov 25 '16 at 21:10
  • @papasmurf in that case maybe something as simple as `\`curl \`.include? %{alert("TEST")}` would suffice – max pleaner Nov 25 '16 at 21:12