RETURN $ecure;

Security, Technology and Life

UserJS URL Sanitizing

with 5 comments

I was reading a post by RSnake over at Darkreading and got to thinking about client-side security.  There seems to be very little we can do against most things for the average user. NoScript is fine for a tech-minded individual, but the average user will probably forget about it and wonder why a site is now missing functionality.

So what do you think of some javascript that could check the URL for typically bad characters(since JS can easily find html-entities/url encoding/etc.)  and then sanitize them somehow? This could mean removing them or properly entifying them. Sure it’s fine. But even Greasemonkey scripts on run after a page is loaded. How could we do this?  Let’s take a look at UserJS in Opera.

User JavaScript is loaded and executed as if it were a part of the page that you visit. It is run immediately before the first script on the page. If the page does not contain any scripts of its own, User JavaScript will be executed immediately before the page is about to complete loading. It is usually run before the DOM for the page has been completed. (Note that this does not apply to Greasemonkey scripts. “….”User JavaScript will not be loaded on pages accessed using the opera: protocol. By default, it is also not loaded on pages accessed using the https: protocol.

Oh! So it should run before any other script is run. This is good. We can check to see if a script was injected, then proceed to remove it. But what if the injection is inside javascript? It will be hard to tell if it’s valid or not. Well since we are using UserJS already, let’s look at the UserJSEvent object and event listeners.

if( location.hostname.indexOf('example.com') != -1 ) {
  window.opera.addEventListener('BeforeScript',
   function (e) {
       e.element.text = e.element.text.replace(/!=\s*null/,'');
    },
    false
  );
}

BeforeScript
Fired before a SCRIPT element is executed. The script element is available as the element attribute of the UserJSEvent. The content of the script is available as the text property of the script element, and is also writable:

UserJSEvent.element.text = UserJSEvent.element.text.replace(/!=\s*null/,”)

So with this, we can check the text of a script object before it fires to sanitize it, which we could set to do only if it contains echoed content. Just a note that this isn’t restricted to off-site JS like it can be in some browsers. UserJS has full access to remote files accessed via script src even before it executes.  The hardest part is obviously sanitizing, but with some work I don’t see it being a huge issue for some basic XSS protection on the client-side.  I’m sure you could even expand it to  search all scripts for things that are commonly malicious like sending document.cookie somewhere to help protect against persistent XSS.

Anyways, I’d love to hear feedback on this idea before I go run off and make it.

About these ads

Written by Rodney G

11/21/2007 at 6:03 pm

Posted in Security

Tagged with , , , , ,

5 Responses

Subscribe to comments with RSS.

  1. Yeah it’s a great idea but it has to be done with care because Javascript is so dynamic attackers could either extend or exploit filtering code.

    Gareth Heyes

    11/22/2007 at 2:37 am

  2. That’s one thing I forgot to mention! The methods of the opera object are not accessible from regular scripts! Plus you could use defineMagicFunction and BeforeScript to rewrite any code that tried to access the UserJS

    Kyran

    11/22/2007 at 7:04 am

  3. Yeah Opera security does rock but I’d like this sort of functionality in Firefox.

    Gareth Heyes

    11/23/2007 at 6:24 am

  4. Glad you like the User JS API :-)
    I have done something similar in browser.js (a “user script” all Opera installations run on all pages, providing various site-specific compatibility fixes) – protecting against the Acrobat Reader PDF javascript: URL exploit.

    I don’t know how exactly one could make this generic enough to be worthwhile. Like, looking in location.search for code that looks like SQL injection or HTML?

    BTW WordPress has taken some liberties with the code in the example :-)

  5. I’ve sent you a quick e-mail regarding location.hash and my new thoughts on this.
    And I know what browser.js is(and I love it!).

    Kyran

    05/3/2008 at 8:22 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: