SWF Hotlinking Protection - JW Player 6

Hello, I found this post about protecting the swf from hotlinking.

This might be what I need. I need to stop people form being able to just grab the source code and play my live stream from anywhere.

https://www.wowza.com/docs/how-to-combat-hotlinking-your-adobe-flash-swf-file

Does anyone know if this works with JW Player? Or does it only work with certain players?

Also, does it require a wowza premium add-on because I am using a trial right now for testing.

thanks

It must not work. The directions were pretty straight forward.

I added the .Jar file in the lib directory… then added the and to the correct place.

Restarted wowza server… but can still play the video through the jwplayer 6 from anywhere.

Any tips?

What this does is prevent hotlinking, where someone uses an absolute URL to your web server and player .swf file to display your player in their website.

For basic protection you need SecureToken and to use RTMPE or RTMPS protocols.

Richard

Roger’s outline shows what goes where (On the Web Server, 1, 2, 3). If you want to implement something like this but need help you can post in the Find a Consultant forum, or write to support@wowza.com and ask for the list of independent consultants.

Otherwise, you can use the built-in security measures for pretty good security.

Richard

There is an example here:

https://www.wowza.com/docs/how-to-use-the-imediastreamnamealiasprovider2-interface

And here is the ServerSide API

Richard

Yes, right, this is not built-in. The built-in security features are documented in The Security Overview

Richard

Hi,

The module checks the web page that the player is launched from and allows the connection if it matches the list. It will not prevent someone from iframing your player page or using a direct link to your swf file and passing the parameters in on the link.

To prevent this, you need regular hotlink protection enabled on your website. this is normally done with a .htaccess file in the folder on the web server that only allows listed referrers to access the files.

This tool, will generate the required .htaccess file. You need to make sure you do not allow blank referrers and set it to block access to swf and possibly js file extensions. If blank referrers is allowed then someone will still be able to type your swf url directly into their browser.

Roger.

Hi,

Secure token will only allow a player with the correct token to connect to the Wowza Server. It will not stop someone from downloading your player and putting it on their own website.

Setting Connections/AutoAccept to false and Connections/AllowedDomains to your own domains in the Application.xml will prevent an swf from another domain from connecting to your server which will block someone who has downloaded your player or has compiled their own player with your token.

<Connections>
	<AutoAccept>false</AutoAccept>
	<AllowDomains>localhost,*yourswfdomain.com</AllowDomains>
</Connections>

ModuleHotlinkDenial will check the Web Page Referrer to see if it is allowed to connect to your server. It will not prevent someone from linking directly to your player swf file and passing the params in the link.

<Property>
	<Name>domainLock</Name>
	<Value>localhost,*yourwebdomain.com</Value>
</Property>

Web site Hotlink Protection will prevent someone from directly linking to the swf file.

None of the above will prevent someone from iframing your web page or player. The way to stop that is control access to the actual player and page. Require users to be logged in somehow but don’t make it automated.

All of these methods on their own can be bypassed fairly easily but combined make it difficult but not impossible for someone who is determined to bypass your security.

The best method would be to encrypt the stream name on your web server dynamically along with some other information that would be unique to the connection and would only be known by the web server and the Wowza server. When the request comes in, decrypt the stream name and check the information. If it passes, allow the stream to be played.

Example.

On the Web Server:

  • Have the following information:

  • Secret Value

  • Users ip address

  • Actual Stream Name

  • Current Timestamp

  • Any other values you want.

  • Create an MD5 hash of these values.

    $hash = md5(<secret>:<ip>:<stream-name>:<timestamp>[:<any-other-values>])
    
  • The Wowza server will know the secret and the ip address but it needs the stream name and timestamp and any extra values. The more information you use, the harder it will be to bypass but could also lead to playback problems for legitimate users.

    Create a base64 encode of the md5 hash and the other values that Wowza needs.

    $name = base64Encode(<hash>:<stream-name>:<timestamp>[:<any-other-values>])
    

    This base64 value is the stream name you use in the player. It will be unique for every player request and will work for all player types.

    On the Wowza server, you would have to create a module that can decode the information and check it. This can be done with a module that implements the IMediaStreamNameAliasProvider(2) interface.

    The interface has resolvePlayAlias methods where you would decode the information and allow or deny the stream playback. If you allow teh playback, you return the real stream name from this method. If you deny it then you return null.

    The process the reverse to what is done on the web server.

  • Base64 decode the requested name to get the separate values.

    String[] values = Base64.decode(name).split(":");
    
  • Create an md5 hash of the locally known values and the extra values extracted from the requested name.

    String testStr = localSecret+":"+client.getIp();  //  Start with the locally know information.
    for(int i = 1; i < values.length; i++)
    {
    	testStr += ":"+values[i];  //  Add the information extracted from the requested name;
    }
    String localHash = MD5DigestUtils.generateHash(testStr);
    boolean isGood = localHash.equalsIgnoreCase(values[0]));
    if(isGood)
    {
    	return values[1];
    }
    return null;
    
    
  • If this local has value matches what is extracted from the requested name then you are fairly confident that the connection is legitimate.

    You can take this further by checking the timestamp is within a specified time frame or more than just 1 attempt is being made to play the stream or you can make a call back to the web server to validate any information further. Any of these callbacks would be invisible to the end user. You could invalidate the requested name after it has been used once but this would require the player to refresh for every play request.

    This is just an example of what could be done. As you can see, it is a lot more work than the standard methods.

    Roger.

Hi,

The base64 encode would just be the stream name part of the url. The rtmp address part would be standard. JW Player has no way of knowing it needs to decode the file parameter.

rtmp://wowzaIP:1935/live/[encoded-stream-name]

On the server, your custom module would decode the stream name.

Roger.

Right, but it still allows hotlinking. I can copy the page source along with the jwplayer folder and play it from anywhere.

On the wowza site it shows to be an add-on… maybe you have to pay for it to enable the feature… though the tutorial does not say that.

I read up on the token but I cant have users typing in a code each time they change to a new camera stream…

From the looks of it RTMPE does not stop people from being able to copy your source code and connect to it any time they want.

I am not sure where to go from here… Maybe I will see if they have a paid support line…

thanks

The method you are talking about won’t stop people from just copying the page source will it?

Or will it?

That is what I am trying to stop. People can just copy the html… download the jwplayer files… and watch the video from our cameras whenever they want…

thanks

Thank you! This seems like a great option. So even if people copy the source code it wont matter because that link wont be active for long… :slight_smile:

Question. Where how will the wowza server know the secret? Is there a certain place in the config that we are supposed to put the secret phrase, timestamp, etc.?

The Wowza server will know the secret and the ip address but it needs the stream name and timestamp and any extra values.

One last question.

In this scenario where would this script with all the encrytping code go?

Would it go on my web server where the pages with the video embeded will be?

Would it be called when the page loads or something?

thanks

Is there an sdk for wowza? Or any documentation about how to implement the IMediaStreamNameAliasProvider2-interface module?

I see how to add the in to the Application.xml file… but I cant find any documentation about editing the actual module.

Is this correct?

To use this method I need to install the wowza IDE and create a module from scratch that implements the IMediaStreamNameAliasProvider(2) interface. ?

thanks

wow ok thanks. yeah i had no idea what was involved… i just got a link to a document that showed that you have to install eclipse and the ide etc.

i was thinking i would just paste the info into a conf file on the wowza server… :slight_smile:

When I put the base64 encoded url into jw player 6 it gives an error and won’t play…

This is what it looks like in the player:

That is the base url of my rtmp url:

file: “rtmp://wowzaIP:1935/live/camera.stream”

Is that what you meant by putting the base64 path into the player?

Thanks

OK, I see… so you have to have the module in place first.

The module is what decodes it from base64 so wowza can understand it…

Is that about what it should look like in the player though?

Just the base64 string in there like that?

thanks

OK, I got the IDE installed… and got a custom application / module running with no errors.

Now I just need to code that module to decode the base64 stream name.

Question.

Do I need to use the IMediaStreamNameAliasProvider2 module found here: ?

https://www.wowza.com/docs/how-to-use-the-imediastreamnamealiasprovider2-interface

Or can I just start with a new empty module and write the java code to decode the stream name?

I am not sure if I need creating an IMediaStreamNameAliasProvider2 module…

Or just creating a new module that does the decoding…

Hope that makes sense.

Thanks for your time

I just thought about something…

If I put the encoded “secret phrase” into the code of the web page… wont users just be able to copy it and decode it?

Then once they have the decoded stream name and “secret phrase” they can still connect…

Or am I missing part of the equation?

Thanks