Reputation: 313
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>')
Upvotes: 3
Views: 597
Reputation: 160621
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.
Upvotes: 2
Reputation: 26788
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
Upvotes: 1