• How to combat hotlinking your Adobe Flash SWF file

    Hotlink Denial controls the html container only. Hotlinking is another word for embedding. For example, you can embed a Youtube video on your website, they even provide a snip of code to make that possible. A user can look at the source code of your html page, copy the embed/object tags (or swfobject) and place that in a html page on their website. You can do the same with img tags, for example. If you want users to do that, it's called embedding; if you don't want them to do it, it's called hotlinking. Use this package when you don't want your users to be able to do this.

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

    Code:
    package com.wowza.wms.plugin.collection.module;
    
    import com.wowza.wms.amf.*;
    import com.wowza.wms.client.*;
    import com.wowza.wms.module.*;
    import com.wowza.wms.request.*;
    
    public class ModuleHotlinkDenial extends ModuleBase {
    
    	public void onConnect(IClient client, RequestFunction function,
    			AMFDataList params) {
    		
    		getLogger().info("ModuleHotlinkDenial onConnect: " + client.getClientId());
      
    		String flashver = client.getFlashVer().toLowerCase();
    		getLogger().info("ModuleHotlinkDenial Client Flashver: " + flashver);
    		
    		try
    		{ 
    			String[] allowedEncoder = null;  
    			    
    			allowedEncoder = client.getAppInstance().getProperties().getPropertyStr("AllowEncoder","").toLowerCase().split(","); 
    			if ( allowedEncoder != null )
    				{ 
    				for (int i = 0; i < allowedEncoder.length; i++) 
    				{  
    					if (flashver.startsWith(allowedEncoder[i].trim()) && allowedEncoder[i].length()>0) 
    					{ 
    						getLogger().info("ModuleHotlinkDenial Encoder Allowed: "+flashver+" matches "+allowedEncoder[i]); 
    						client.acceptConnection();
    						return;
    					} 
    				} 
    			} 
    		} 
    		catch (Exception e) 
    		{
    			getLogger().info("ModuleHotlinkDenial Exception: " + e.getMessage()); 
    		}
    
    		boolean reject = true;
    		String[] domainLocks = null;
    		String[] domainUrl = null;;
    			
    		try 
    		{ 
    		domainLocks = client.getAppInstance().getProperties().getPropertyStr("domainLock").toLowerCase().split(",");
    		String pageUrl = client.getProperties().getPropertyStr("connectpageUrl").toLowerCase();
    		domainUrl = pageUrl.split("/");
    		getLogger().info("domainLock: " + client.getAppInstance().getProperties().getPropertyStr("domainLock").toLowerCase());
    		getLogger().info("pageUrl: " + pageUrl);
    		for (int i = 0; i < domainLocks.length; i++)
    		{ 
    			if (domainLocks[i].trim().startsWith("*"))
    			{
    				String lock = domainLocks[i].trim().substring(1);
    				if (domainUrl[2].endsWith(lock))
    				{
    					reject = false;
    				}
    			} 
    			else if (domainUrl[2].equalsIgnoreCase(domainLocks[i].trim()))
    			{
    				reject = false; 
    			}
    		}
    		} 
    		catch(Exception ex)
    		{
    			reject = true;
    		}
    		if (reject)
    		{
    			getLogger().info("Client Rejected. IP: " + client.getIp());
    			client.rejectConnection();
    		}
    	}
    
    }
    Then add this Module last in the Modules section of your Application.xml
    Code:
    <Module>
    	<Name>Hotlink Denial</Name>
    	<Description>Hotlink Denial Module</Description>
    	<Class>com.wowza.wms.plugin.collection.module.ModuleHotlinkDenial</Class>
    </Module>
    And this Property section to the Properties section below the Modules in the Application.xml:
    Code:
    <Property>
    	<Name>domainLock</Name>
    	<Value>localhost,mysite.com</Value>
    </Property>
    <Property>
    	<Name>AllowEncoder</Name>
    	<Value>Wirecast</Value> <!--FM, Wirecast-->
    </Property>
    The listed domain names or IP address in domainLock, above, must be fully qualified domain names. If your site is www.mysite.com, you must add "www.mysite.com" to the list. Or you can use a wildcard, e.g., "*mysite.com".

    A compiled version of this module is included in the Wowza Modules Collection. Download and unzip the collection, then copy /lib/wms-plugin-collection.jar from the package to the Wowza /lib folder. Then restart Wowza.



    Comments 47 Comments
    1. mustihi83 -
      I want to use Hotlink Denial Module for a live streaming Application. I am using Wirecast for broadcasting Flash RTML stream.

      Should the IP of the broadcaster be given in the domainLock property? Otherwise it's rejected. What can one do if the broadcaster has a dynamic IP?

      When I add the IP of the broadcaster to the domainLock values, I don't see any "rejected" connections in the log. Despite that, when I try to view the video, I get the error "Stream not found".

      bye,
    1. rrlanham -
      Use the AllowEncoder property to address this issue. Add to the Application.xml /Properties list, at bottom of that file.

      Code:
      <Property>
      	<Name>AllowEncoder</Name>
      	<Value>FM</Value>
      </Property>
      The Value "FM" works in most cases. It is what the userAgent for FMLE 2.5, 3, 3.2 start with, and Wirecast and other encoders often use the same userAgent. If not, look in the access log and you see the userAgent of the encoder. Copy that to AllowEncoder Property Value

      Richared
    1. mustihi83 -
      Hello,

      this is what I see:

      Code:
      #Version: 1.0
      #Start-Date: 2011-01-14 22:16:22 CET
      #Software: Wowza Media Server 2.2.3 build26454
      #Date: 2011-01-14
      #Fields: x-severity	x-category	x-event	date	time	c-client-id	c-ip	c-port	cs-bytes	sc-bytes	x-duration	x-sname	x-stream-id	x-spos	sc-stream-bytes	cs-stream-bytes	x-file-size	x-file-length	x-ctx	x-comment
      INFO	vhost	vhost-start	2011-01-14	22:16:22	-	-	-	-	-	1.651	-	-	-	-	-	-	-	Tilda	-
      INFO	server	comment	2011-01-14	22:16:22	-	-	-	-	-	2.588	-	-	-	-	-	-	-	-	ModuleRTMPAuthenticate.onAppStart: SecureToken is off
      INFO	server	comment	2011-01-14	22:16:22	-	-	-	-	-	2.588	-	-	-	-	-	-	-	-	ModuleRTMPAuthenticate.onAppStart: Authorization password file: /home/Video/Tilda/conf/publish.password
      INFO	server	comment	2011-01-14	22:16:22	-	-	-	-	-	2.589	-	-	-	-	-	-	-	-	ModuleStreamRecord.onAppStart
      INFO	application	app-start	2011-01-14	22:16:22	-	-	-	-	-	2.594	-	-	-	-	-	-	-	_definst_	live/_definst_
      INFO	session	connect-pending	2011-01-14	22:16:22	410517287	158.42.45.33	-	3334	3073	0.188	-	-	-	-	-	-	-	158.42.45.33	-
      INFO	server	comment	2011-01-14	22:16:22	-	-	-	-	-	2.596	-	-	-	-	-	-	-	-	onConnect HotlinkDenial Module: 410517287
      INFO	server	comment	2011-01-14	22:16:22	-	-	-	-	-	2.597	-	-	-	-	-	-	-	-	Flashver: Wirecast/FM 1.0 (compatible; FMSc/1.0)
      INFO	server	comment	2011-01-14	22:16:22	-	-	-	-	-	2.597	-	-	-	-	-	-	-	-	Client Rejected. IP: 158.42.45.33
      INFO	session	connect	2011-01-14	22:16:22	410517287	158.42.45.33	-	3334	3073	0.191	-	-	-	-	-	-	-	158.42.45.33	-
      INFO	session	disconnect	2011-01-14	22:16:23	410517287	158.42.45.33	-	3350	3361	0.256	-	-	-	-	-	-	-	410517287	-
      INFO	session	connect-pending	2011-01-14	22:16:23	1315980531	158.42.45.33	-	3416	3073	0.126	-	-	-	-	-	-	-	158.42.45.33	-
      INFO	server	comment	2011-01-14	22:16:23	-	-	-	-	-	2.894	-	-	-	-	-	-	-	-	onConnect HotlinkDenial Module: 1315980531
      INFO	server	comment	2011-01-14	22:16:23	-	-	-	-	-	2.894	-	-	-	-	-	-	-	-	Flashver: Wirecast/FM 1.0 (compatible; FMSc/1.0)
      INFO	server	comment	2011-01-14	22:16:23	-	-	-	-	-	2.895	-	-	-	-	-	-	-	-	Client Rejected. IP: 158.42.45.33
      INFO	session	connect	2011-01-14	22:16:23	1315980531	158.42.45.33	-	3416	3073	0.128	-	-	-	-	-	-	-	158.42.45.33	-
      INFO	session	disconnect	2011-01-14	22:16:23	1315980531	158.42.45.33	-	3432	3419	0.193	-	-	-	-	-	-	-	1315980531	-
      INFO	session	connect-pending	2011-01-14	22:16:23	33146442	158.42.45.33	-	3625	3073	0.132	-	-	-	-	-	-	-	158.42.45.33	-
      INFO	server	comment	2011-01-14	22:16:23	-	-	-	-	-	3.198	-	-	-	-	-	-	-	-	onConnect HotlinkDenial Module: 33146442
      INFO	server	comment	2011-01-14	22:16:23	-	-	-	-	-	3.199	-	-	-	-	-	-	-	-	Flashver: Wirecast/FM 1.0 (compatible; FMSc/1.0)
      INFO	server	comment	2011-01-14	22:16:23	-	-	-	-	-	3.199	-	-	-	-	-	-	-	-	Client Rejected. IP: 158.42.45.33
      INFO	session	connect	2011-01-14	22:16:23	33146442	158.42.45.33	-	3625	3073	0.136	-	-	-	-	-	-	-	158.42.45.33	-
      INFO	session	disconnect	2011-01-14	22:16:23	33146442	158.42.45.33	-	3625	3345	0.205	-	-	-	-	-	-	-	33146442	-
      INFO	session	connect-pending	2011-01-14	22:16:23	1568678060	158.42.45.33	-	3327	3073	0.133	-	-	-	-	-	-	-	158.42.45.33	-
      INFO	server	comment	2011-01-14	22:16:23	-	-	-	-	-	3.507	-	-	-	-	-	-	-	-	onConnect HotlinkDenial Module: 1568678060
      INFO	server	comment	2011-01-14	22:16:23	-	-	-	-	-	3.507	-	-	-	-	-	-	-	-	Flashver: FMLE/3.0 (compatible; FMSc/1.0)
      INFO	session	connect	2011-01-14	22:16:23	1568678060	158.42.45.33	-	3327	3073	0.135	-	-	-	-	-	-	-	158.42.45.33	-
      INFO	stream	create	2011-01-14	22:16:24	1568678060	158.42.45.33	-	3468	3457	0.0	-	1	0	0	0	-	-	-	-
      INFO	stream	destroy	2011-01-14	22:16:34	1568678060	158.42.45.33	-	3561	3792	10.418	-	1	0	0	0	-	-	-	-
      INFO	session	disconnect	2011-01-14	22:16:35	1568678060	158.42.45.33	-	3561	3792	11.721	-	-	-	-	-	-	-	1568678060	-
      INFO	session	connect-pending	2011-01-14	22:16:36	1728715387	158.42.45.33	-	3334	3073	0.134	-	-	-	-	-	-	-	158.42.45.33	-
      INFO	server	comment	2011-01-14	22:16:36	-	-	-	-	-	16.265	-	-	-	-	-	-	-	-	onConnect HotlinkDenial Module: 1728715387
      INFO	server	comment	2011-01-14	22:16:36	-	-	-	-	-	16.266	-	-	-	-	-	-	-	-	Flashver: Wirecast/FM 1.0 (compatible; FMSc/1.0)
      INFO	server	comment	2011-01-14	22:16:36	-	-	-	-	-	16.266	-	-	-	-	-	-	-	-	Client Rejected. IP: 158.42.45.33
      INFO	session	connect	2011-01-14	22:16:36	1728715387	158.42.45.33	-	3334	3073	0.135	-	-	-	-	-	-	-	158.42.45.33	-
      INFO	session	disconnect	2011-01-14	22:16:36	1728715387	158.42.45.33	-	3350	3361	0.203	-	-	-	-	-	-	-	1728715387	-
      INFO	session	connect-pending	2011-01-14	22:16:36	117978844	158.42.45.33	-	3416	3073	0.12	-	-	-	-	-	-	-	158.42.45.33	-
      INFO	server	comment	2011-01-14	22:16:36	-	-	-	-	-	16.554	-	-	-	-	-	-	-	-	onConnect HotlinkDenial Module: 117978844
      INFO	server	comment	2011-01-14	22:16:36	-	-	-	-	-	16.554	-	-	-	-	-	-	-	-	Flashver: Wirecast/FM 1.0 (compatible; FMSc/1.0)
      INFO	server	comment	2011-01-14	22:16:36	-	-	-	-	-	16.555	-	-	-	-	-	-	-	-	Client Rejected. IP: 158.42.45.33
      INFO	session	connect	2011-01-14	22:16:36	117978844	158.42.45.33	-	3416	3073	0.122	-	-	-	-	-	-	-	158.42.45.33	-
      INFO	session	disconnect	2011-01-14	22:16:36	117978844	158.42.45.33	-	3416	3419	0.182	-	-	-	-	-	-	-	117978844	-
      INFO	session	connect-pending	2011-01-14	22:16:37	867274070	158.42.45.33	-	3625	3073	0.127	-	-	-	-	-	-	-	158.42.45.33	-
      I tried all possible combinations but no way
    1. rrlanham -
      The userAgent is shown in the logs:
      Code:
      Wirecast/FM 1.0 (compatible; FMSc/1.0)
      So change the AllowEncoder Property to:
      Code:
      <Property>
      	<Name>AllowEncoder</Name>
      	<Value>Wirecast</Value>
      </Property>
      (It is also possible in Wirecast to change the userAgent, but nevermind that, the above will work with HotLinkDenial)

      Richard
    1. mustihi83 -
      I have found the problem. May it be a bug?

      I am doing RTMP Flash streaming, thus I need rtmpauthenticate module. However, I have found that hotlinkdenial module is not working when rtmpauthenticate module is in use. It started working when I disabled rtmpauthenticate.

      Do you have any suggestions?
    1. rrlanham -
      Try changing the order of the Modules in the Application.xml. If ModuleHotlinkDenial is last, switch it with ModuleRTMPAuthenticate, or vice-versa.

      Richard
    1. mustihi83 -
      ok, changing their order solved the problem.
    1. shamrock -
      Did you put the Property section in the 'Properties' section at the end of the Application.xml ? rather than straight after the module entry ? as it does not go straight after the module.

      Shamrock
    1. morphious -
      Hi I have 2 issues with this Hotlinking script.

      1. when I try to connect to to Localhost to test, the Localhost points to 127.0.0.1 and this is rejected. Client Rejected. IP: 127.0.0.1 So I added the IP of the local machine and tried to connect to this IP form the local machine and it is rejected as well. All 3 address are in the domainLock Value :-(

      2. I am using JW player 5.5 and this in in fact working and blocked correctly on the RTMP part of the connection. but when it falls back to http ( for HTML5 to IOS devices ) it allows the video to play with no blocking. it is the second part of this that is not blocking.

      Here is my code so you can try it too.

      -----------------------------------------------------

      <script type='text/javascript' src='jwplayer/jwplayer.js'></script>
      </head>
      <body>
      <div id="player"></div>
      <script type="text/javascript">
      jwplayer('player').setup({
      'id': 'playerID',
      'width': '640',
      'height': '480',
      'provider': 'rtmp',
      'autostart': 'true',
      'streamer': 'rtmp://xxx.xxx.xxx.xxx/FDcamin1',
      'file': 'FDcam1.stream',
      image:'../images/FDcam1.jpg',
      skin: "../jwplayer/skins/fdlive/fd.xml",
      'modes': [
      {type: 'flash', src: 'jwplayer/player.swf'},
      {
      type: 'html5',
      config: {
      'file': 'http://xxx.xxx.xxx.xxx:1935/FDcamin1/FDcam1.stream/playlist.m3u8',
      'provider': 'video',
      'x-webkit-airplay': 'allow'
      }
      }
      ]
      });

      </script>

      ------------------------------------------------------------

      -D
    1. rrlanham -
      On the first problem, maybe your Application.xml changes were not properly reloaded. I tested with Flash app served from html container at 127.0.01 without that IP in domainLock and with, and was denied and allowed resp, as expected.

      On the second problem, HotlLinkDenial only works for Flash apps. For iOS you can check httpSession.getIpAddress() in onHTTPSessionCreate, and do httpSession.rejectSession()

      http://www.wowzamedia.com/forums/con...h-and-San-Jose)

      Richard
    1. rrlanham -
      Added multiple encoder handling from Andrew.
    1. dragelec -
      This module work ok. But when i want to save live stream by using vlc, it appeared error like this:
      [stderr] Server error: Connection failed: Application rejected connection.
      [stderr] [0x8a7e30] access_avio access error: Failed to open url using libavformat
      [stderr] [0x7f9034001940] main input error: open of `rtmp://112.197.2.11/live/sctv7.stream' failed: (null)
      [stderr] [0x7f9034001940] main input error: Your input can't be opened
      [stderr] [0x7f9034001940] main input error: VLC is unable to open the MRL 'rtmp://112.197.2.11/live/sctv7.stream'. Check the log for details.
      How can i fix it???pl help me
    1. rrlanham -
      What are the corresponding comments in the Wowza access log?

      If you are push publishing a stream to Wowza application that has Hotlinkdenial installed, the access log should reveal the userAgent, then you can add that to the AllowedEncoder list

      Alternatively, you can use this pull method with VLC:
      http://www.wowzamedia.com/forums/con...erver-(MPEG-TS)

      Richard
    1. dragelec -
      My access log likes this:
      MPEGTS.handleRTPPacket: Out of sync: 0x80 - - - 179.103 - - -
      2011-07-08 09:31:07 ICT comment server WARN 200 - RTPDePacketizerMPEGTS.handleRTPPacket: Out of sync: 0x80 - - - 179.118 - - -
      2011-07-08 09:31:07 ICT comment server WARN 200 - RTPDePacketizerMPEGTS.handleRTPPacket: Out of sync: 0x80 - - - 179.158 - - -
      2011-07-08 09:31:08 ICT comment server WARN 200 - RTPDePacketizerMPEGTS.handleRTPPacket: Out of sync: 0x80 - - - 179.227 - - -
      2011-07-08 09:31:08 ICT comment server WARN 200 - RTPDePacketizerMPEGTS.handleRTPPacket: Out of sync: 0x80 - - - 179.293 - - -
      2011-07-08 09:31:08 ICT connect-pending session INFO 100
      I have changed AllowEncoder to WIN, but it didn't work.
    1. dragelec -
      2011-07-08 09:31:08 ICT comment server INFO 200 - ModuleHotlinkDenial onConnect: 1196606951 _defaultVHost_ live _definst_ 179.334 - - -
      2011-07-08 09:31:08 ICT comment server INFO 200 - ModuleHotlinkDenial Client Flashver: WIN 10,3,181,22 _defaultVHost_ live _definst_ 179.334 - -
      2011-07-08 09:31:08 ICT comment server INFO 200 - domainLock:

      Flashver is WIN
    1. rrlanham -
      I don't think there is a problem with HotLinkDenial. Re-reading, I see rtmp in VLC... I've never seen that work. Try rtsp

      Richard
    1. dragelec -
      Hi Richard
      When saving live streaming with vlc, vlc worked with rtmp (i'm sure). But when i added hotlinkDenial, it didn't work. I have seen it log, flashver was WIN, so how can i added AloowEncode????
    1. randall -
      Did you try:

      Code:
      <Property>
      	<Name>AllowEncoder</Name>
      	<Value>WIN</Value> 
      </Property>
    1. dragelec -
      Yes, I have already tried it , it didn't work
    1. rrlanham -
      Did you figure this out? If not, zip up conf *and* logs folders and send them to support@wowzamedia.com.

      Make sure what you send is current state that you have tested, i.e. that there is logging from testing with that configuration.

      Richard