views:

168

answers:

2

I need to be allow content from our site to be embeded in other users web sites. The conent will be chargeable so I need to keep it secure but one of the requirements is that the subscribing web site only needs to drop some javascript into their page.

It looks like the only way to secure our content is to check the url of the page hosting our javascript matches the subscribing site. Is there any other way to do this given that we don't know the client browsers who will be hitting the subscribing sites?

Is the best way to do this to supply a javascript include file that populates a known page element when the page loads? I'm thinking of using jquery so the include file would first call in jquery (checking if it's already loaded and using some sort of namespace protection), then on page load populate the given element.

I'd like to include a stylesheet as well if possible to style the element but I'm not sure if I can load this along with the javascript.

Does this sound like a reasonable approach? Is there anything else I should consider?

Thanks in advance,

Mike

+2  A: 

You can store the users domain, and a key within your local database. That, or the key can be an encrypted version of the domain to keep you from having to do a database lookup. Either one of these can determine whether you should respond to the request or not.

If the request is valid, you can send your data back out to the user. This data can indeed load in jQuery and and additional CSS reference.

Related:

  1. http://stackoverflow.com/questions/574944/how-to-load-up-css-files-using-javascript
  2. http://stackoverflow.com/questions/1828237/check-if-jquery-has-been-loaded-then-load-it-if-false
Jonathan Sampson
+1. As a side note, I would always be cautious about loading a script into my page from a third party site, especially if it's not over `https`. Amongst not being keen on allowing a third party access to my page's DOM, it opens up for potential MITM attacks. Most widget provider should use iframes to offer security to all parties involved. Iframes can be transparent and you could even offer a `get` parameter that provides the location of the css file.
Andy E
+1 @Andy. Good information.
Jonathan Sampson
Thanks for the information, I'll investigate further.
Mike
+3  A: 

It looks like the only way to secure our content is to check the url of the page hosting our javascript matches the subscribing site.

Ah, but in client-side or server-side code?

They both have their disadvantages. Doing it with server-side code is unreliable because some browsers won't be passing a Referer header at all, and if you want to stop caches keeping a copy of the script, preventing the Referer-check from taking place, you have to serve with nocache or Vary: Referer headers, which would harm performance.

On the other hand, with client-side checks in the script you return, you can't be sure your environment you're running in hasn't been sabotaged. For example if your inclusion script tag was like:

<script src="http://include.example.com/includescript?myid=123"&gt;&lt;/script&gt;

and your server-side script looked up 123 as being the ID for a customer using the domain customersite.foo, it might respond with the script:

if (location.host.slice(-16)==='customersite.foo') {
    // main body of script
} else {
    alert('Sorry, this site is not licensed to include content from example.com');
}

Which seems simple enough, except that the including site might have replaced String.prototype.slice with a function that always returned customersite.foo. Or various other functions used in the body of the script might be suspect.

Including a <script> from another security context cuts both ways: the including-site has to trust the source-site not to do anything bad in their security context like steal end-user passwords or replace the page with a big goatse; but equally, the source-site's code is only a guest in the including-site's potentially-maliciously-customised security context. So a measure of trust must exist between the two parties wherever one site includes script from another; the domain-checking will never be a 100% foolproof security mechanism.

I'd like to include a stylesheet as well if possible to style the element but I'm not sure if I can load this along with the javascript.

You can certainly add stylesheet elements to the document's head element, but you would need some strong namespacing to ensure it didn't interfere with other page styles. You might prefer to use inline styles for simplicity and to avoid specificity-interference from the page's main style sheet.

It depends really whether you want your generated content to be part of the host page (in which case you might prefer to let the including site deal with what styles they wanted for it themselves), or whether you want it to stand alone, unaffected by context (in which case you would probably be better off putting your content in an <iframe> with its own styles).

I'm thinking of using jquery so the include file would first call in jquery

I would try to avoid pulling jQuery into the host page. Even with noconflict there are ways it can conflict with other scripts that are not expecting it to be present, especially complex scripts like other frameworks. Running two frameworks on the same page is a recipe for weird errors.

(If you took the <iframe> route, on the other hand, you get your own scripting context to play with, so it wouldn't be a problem there.)

bobince
Thanks for the information, that's given me plenty to think about and clarified a few things.
Mike