Wowza Community

Hot Linking, Secure Token, Allow Domains, General Security

Richard’s suggestion is a good one. It will tie the .swf file to your html page. If you change the html page name or path you will need to modify the code that is verifying this.

BTW, I will try to integrate this type of check into the MediaSecurity package. We have been more focused on securing the connection between the Flash player and Wowza Pro. Certainly faciliting the security between the hosting web page and the swf is also of interest. If other have suggestions on approaches to making this more secure please jump in and let me know.

Charlie

I don’t know about .htaccess either, but I think it could work. Test and see.

If you can modify the source code of the Player you can use the Actionscript solution above, the one with External Interface.

Richard

Sorry about the oversight. Posts do get lost in the shuffle sometimes.

The examples are AS3. It’s an easy client-side way to do this. Here is the solution more complete:

private var href:String = "";
if (ExternalInterface.available)
{
href = ExternalInterface.call("function(){return window.location.href;}");
}
if (href != "YourWebsite.com")
{
// handle bad domain.
}

Notice that this method does not depend on javascript in the html container, it injects a little javascript so users can’t see it what you are checking. And it doesn’t depend on an html container either, if the swf is playing by itself the check will fail

Richard

Just take out “private” if the var is declared inside a function. If you want the var available to different functions declare it outside a function with private keyword.

I think this will work to prevent the primary concern. Be specific what href should match. I don’t know if it will prevent other tricks.

Richard

var href:String = "";

Put it in com.jeroenwijering.models.RTMPModel.as in the load() function.

Add import to the top:

import flash.external.ExternalInterface;

And modify load() function:

/** Load content. **/
override public function load(itm:Object):void {
// Add from here:
var href:String = "";
if (ExternalInterface.available)
{
href = ExternalInterface.call("function(){return window.location.href;}");
}
if (href != "YourWebsite.com")
{
// handle bad domain.
return; // just refuse to load RTMPModel and your done. You don't owe anyone an explanation.
}
// end Add
	item = itm;
	position = 0;
	model.mediaHandler(video);
	connection.connect(item['streamer']);
	model.sendEvent(ModelEvent.BUFFER,{percentage:0});
	model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING});
};

Richad

Right, I modified my post above for the 4.4 version.

Richard

Yes, but trace it out and see exactly what it is and don’t forget about localhost. This is what I get from what I am working on now:

href=

http://localhost/ChatApp/ChatApp.html?debug=true#

Richard

Like this:

trace(href);

Using trace statements in Flash editor is basic. I would spend a few days learning Flash at this point. That will save you a lot of time. lynda.com has tons of videos. Or get a Flash book that teaches Flash editor basics. I did both when I was ramping-up on Flash.

Richard

Create a new Wowza Module Class with the Wowza IDE and modify the onConnect like this:

public void onConnect(IClient client, RequestFunction function,
			AMFDataList params) {		
String ip = client.getIp();
// handle ip
}

I have a Wowza module with allow and deny ip lists. Checks the allow list first then the deny list. contact richard.lanham@gmail.com

Richard

Here is a complete Wowza Module to deny hotlinking server-side. Compile this in the Wowza IDE:

package com.lakesidetechnical.security;
import com.wowza.wms.amf.*;
import com.wowza.wms.client.*;
import com.wowza.wms.module.*;
import com.wowza.wms.request.*;
public class HotlinkDenial extends ModuleBase {
	public void onConnect(IClient client, RequestFunction function,
			AMFDataList params) {
		getLogger().info("onConnect: " + client.getClientId());
		String pageUrl = client.getProperties().getPropertyStr("connectpageUrl").toLowerCase();
		String domainLock = client.getAppInstance().getProperties().getPropertyStr("domainLock").toLowerCase();
		
		boolean reject = !pageUrl.startsWith(domainLock);
		
		if (reject)
			client.rejectConnection();
	}
}

Then add this Module last in the Modules section of your Application.xml

Hotlink Denial

Hotlink Denial Module

com.lakesidetechnical.security.HotlinkDenial

(note that I cannot get rid of the space between the “a” and “l” in HotlinkDenial above, be sure to edit that out)

And this Property section to the Properties section below the Modules in the Application.xml:

domainLock

http://localhost

This zip file includes a compiled jar file:

http://wms.lakesidetechnical.com/hotlinkdenial.zip

Richard

Ok…not that there was any doubt but I placed a link to my swf on a different domain on a different server and low and behold, I was able to play my member videos with no problem.

I’ve now added the following to my htaccess to prevent hot linking. It did prevent my test page from working but I don’t know if it’s a good idea or not.

RewriteEngine on

RewriteCond %{HTTP_REFERER} !^$

RewriteCond %{HTTP_REFERER} !^http://([-a-z0-9]+.)?mydomain.com [NC]

RewriteRule .(jpg|jpeg|png|gif|swf)$ - [NC,F]

I looked up some obfuscator programs and one (http://www.kindisoft.com) looked promising as it has ‘Encrypted Domain Lock.’ Of course it’s the professional version and costs $400.

I need to eventually allow other domains to access my free material. My plan (which I already started) was to create a new app with its own secure token and hand out the swf with the matching secure token. I originally thought this would be enough for security. Obviously I need more. I guess using the obfuscator program I could make a custom swf for each new domain but that would be a lot of extra work.

Tying the .swf file to the html page also sounds like a lot of work. I have many unique pages each with their own unique video (times 2 when you add in the member section) and it’s constantly growing.

Just sharing and thinking out loud.

Regards,

Jake

You could just link them to your domain. In onConnect handler do something like this:

String pageUrl = client.getProperties().getPropertyStr("connectpageUrl");
boolean reject = !pageUrl.startsWith("http://my.domain.com");

Then accept/reject the connection based on this info. That way only the domain part needs to match.

Charlie

Thanks for your suggestion Charlie.

I know it’s not your job to act as programming instructor/advisor but not only do I not know how to implement what you suggested, I don’t even know what part of my posting your suggestion is referring to.

I think I’m coming to the realization I’m in over my head :eek:

Can you comment on the htaccess hot link protection?

Best Regards,

Jake

Put it in com.jeroenwijering.models.RTMPModel.as in the load() function.

Add import to the top:

import flash.external.ExternalInterface;

And modify load() function:

/** Load content. **/
override public function load(itm:Object):void {
// Add from here:
var href:String = "";
if (ExternalInterface.available)
{
href = ExternalInterface.call("function(){return window.location.href;}");
}
if (href != "YourWebsite.com")
{
// handle bad domain.
return; // just refuse to load RTMPModel and your done. You don't owe anyone an explanation.
}
// end Add
	item = itm;
	position = 0;
	model.mediaHandler(video);
	connection.connect(item['streamer']);
	model.sendEvent(ModelEvent.BUFFER,{percentage:0});
	model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING});
};

Richad

Thanks Richard! This looks like something even I can try. Just to clairify however, all I need to change is;

if (href != “YourWebsite.com”)

I’m away from the office at the moment but will post my (successful) results later.

Best Regards,

Jake

Yes, but trace it out and see exactly what it is and don’t forget about localhost. This is what I get from what I am working on now:

href=

Richard

well…no luck so far. the preview image appears but nothing happens when I click on it.

I’m using JW Player 4.4.198

I’ve tried MyDomain.com, www.MyDomain.com and http://www.MyDomain.com but none of them worked.

I’ve tried moving the ‘import flash.external.ExternalInterface;’ line around in the top of the file with no luck.

I don’t know how to trace it out. I Googled trace as3 and there were a lot of suggestions but I don’t understand them.

I checked the logs and nothing is showing up there.

Help:confused:

@Rikison, I haven’t tried your method yet. Does it require the actual html page or just the domain?

@Richard, Okay…after days of trying to understand the trace(); thing and how to perform it I almost gave up. I finally came across a plugin for FF that displays all trace requests/functions/what ever it’s called. That’s when I realized it was looking for a specific html page and not just the domain. Once I added my html test page address to the AS I was able to get it to work.

Can you confirm that this is indeed correct (the entire address…http://www.mydomain.com/somefolder/wowzatest.html is needed)?

If this is the case, please forgive me for stating the obvious, does that mean I need a different swf player for every video that’s on a different html page? As of right now, I have 24 different videos on 24 different pages and that number is growing weekly.

Also, if I don’t encrypt the swf, couldn’t someone decompile it and remove the request. Again, if that’s the case, why bother with this and not go right for the obfuscater.

@Charlie, any development the module front?

Thanks!

I have not had a chance to test but I wanted to say thanks to everyone!

Wow, this post seems very similar to the one I posted the other day. However you seem to have gotten a much better response. :slight_smile:

Since a few days has passed since my post I spent a good 2 days trying to figure something out. Im also the man with every hat for my business and feel very similar to you.

I dont mind sharing what took me an insane amount of hours and a huge headache. I scoured the web and tried every as3 actionscript I could find. I finally ended up with this:

/*
fast&dirty domain lock in as3
by dx0ne http://dx0ne.laislacorporation.com
based on http://www.flashrights.com/domaincontrol.htm
*/
gotoAndStop(1);
import flash.events.*;
import flash.display.LoaderInfo;
function enterFrameHandler(event:Event):void {
	var url:String=stage.loaderInfo.url; //this is the magic _url successor
	var urlStart:Number = url.indexOf("://")+3;
	var urlEnd:Number = url.indexOf("/", urlStart);
	var domain:String = url.substring(urlStart, urlEnd);
	var LastDot:Number = domain.lastIndexOf(".")-1;
	var domEnd:Number = domain.lastIndexOf(".", LastDot)+1;
	domain = domain.substring(domEnd, domain.length);
	
	if (domain != "nothing" && domain != "domain1.com" && domain != "domain2.com") {
		gotoAndStop(34);
	}
}
addEventListener(Event.ENTER_FRAME, enterFrameHandler);

Change the domain1.com and so on to your domain, and add as many domains as you want.

Now I will explain how I got it to work with the JW player. Basically download the .fla source code from the JW Player 4.4 HERE.

Open the FLA and make a new layer and paste the above code on frame one. Make another layer and put a keyframe on frame 34 and put whatever you want there, a link to your site maybe or a bad message.

I also added this to my .htaccess which is a little different than yours, Im not sure which is better.

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://domain1.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://domain2.com/.*$ [NC]
RewriteRule [^hotlinked].(swf)$ http://domain1.com/flashfile.swf [R,NC]

Same goes with the flash code, I saw someone else pasted some code but Im not sure which is better.

The question I have is, can I improve on anything to help this problem? Is the other flash code better? Having something supported by wowza would be the best option, please help us out Charlie!

OK, I tried the other flash script posted before mine and it looks like its as2 and not as3. the new jw player is as3 only from what I can tell. Is that correct?

Im trying that code in Flash CS4 and Im getting a compiler error.

1013: The private attribute may be used only on class property definitions.

Source: private var href:String = "";

Any ideas how to fix it?

Also, does this prevent against people simply putting the embed into a folder that is named what your website is? So for example:

www.otherdomain.com/files/yourdomain.com/embedpage.html

And even worse than that is does this help again dns masking where I here they can set up a dns zone or something to be called your domain.