<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Richard Lord &#187; Security</title>
	<atom:link href="http://www.richardlord.net/blog/tag/security/feed" rel="self" type="application/rss+xml" />
	<link>http://www.richardlord.net</link>
	<description>Actionscript/Flex, PHP and Java developer</description>
	<lastBuildDate>Mon, 23 Jan 2012 17:07:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>PHP Password Security</title>
		<link>http://www.richardlord.net/blog/php-password-security</link>
		<comments>http://www.richardlord.net/blog/php-password-security#comments</comments>
		<pubDate>Wed, 10 Oct 2007 15:45:34 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Best practice]]></category>
		<category><![CDATA[Free code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.bigroom.co.uk/blog/php-password-security/</guid>
		<description><![CDATA[<p>If you build websites that require users to register it's your responsibility to keep their passwords safe. And if you're storing the passwords in plain text then you're not doing your job properly. What happens if your database is stolen? It's not just your site that is compromised. Since most users use the same password on multiple sites, all those sites have also been compromised...</p>]]></description>
			<content:encoded><![CDATA[<p>If you build websites that require users to register it&#8217;s your responsibility to keep their passwords safe. And if you&#8217;re storing the passwords in plain text then you&#8217;re not doing your job properly. It may be that, <a href="http://reddit.com/info/usqe/comments/cuugl">like Reddit</a>, you think that storing passwords in plain text leads to a better user experience. I happen to agree with you. But then, like Reddit, what happens if your database is stolen? It&#8217;s not just your site that is compromised. Since most users use the same password on multiple sites, all those sites have also been compromised.</p>

<p>No data is entirely secure, and if anyone else has access to your webserver (the company managing the server for you?) or your database (the company storing the backups?) then you don&#8217;t have total control over the security anyway. So there&#8217;s always a chance your database could be stolen. So, the simple rule is to hash your passwords.</p>

<h3>Hashing</h3>

<p>A hash is a string derived from the original password via a one-way algorithm. In other words, it&#8217;s easy to create the hash from the original, but harder (when used for security, ideally impossible) to create the original from the hash. You store the hash in the database, and when the user signs-in you hash the password they sign-in with and compare it to the hash in the database. Something like this</p>

<pre class="code">if( $user->passwordhash == sha1( $_POST['password'] ) )</pre>

<p>That way, you never store the user&#8217;s password.</p>

<p>There are a number of hashing algorithms in PHP, of which md5 and sha1 are the most commonly used. Unfortunately, neither is as secure as they were once thought to be. It would be better to use a more secure hash, and if you have the Hash engine in your PHP installation (included by default since PHP 5.1.2) then you have access to many more algorithms. So a better example would be</p>

<pre class="code">if( $user->passwordhash == hash( 'whirlpool', $_POST['password'] ) )</pre>

<h3>Rainbow tables</h3>

<p>But there&#8217;s another problem. Once your database is stolen, the thief has plenty of time to crack the passwords using a simple <a href="http://www.codinghorror.com/blog/archives/000949.html">Rainbow Table attack</a>. This involves creating a large selection of hashes based on likely passwords (e.g. every word in the dictionary) and then comparing the hashes with the hashes in your database. Within an hour or so, half the passwords in your database will probably have been cracked.</p>

<p>To prevent this you should salt each password by adding a random string to it (called a salt or nonce). The time consuming part of a rainbow table attack is building the dictionary of hashes. Adding a random salt to the password means the thief has to build a whole new dictionary of hashes for each salt, making a rainbow table attack too time consuming to be viable. Each password should have a different salt, and the salt doesn&#8217;t even need to be secret.</p>

<h3>The Code bit</h3>

<p>So, for secure passwords you need code that looks something like this</p>

<pre class="code">// get a new salt - 8 hexadecimal characters long
// current PHP installations should not exceed 8 characters
// on dechex( mt_rand() )
// but we future proof it anyway with substr()
function getPasswordSalt()
{
    return substr( str_pad( dechex( mt_rand() ), 8, '0',
                                           STR_PAD_LEFT ), -8 );
}

// calculate the hash from a salt and a password
function getPasswordHash( $salt, $password )
{
    return $salt . ( hash( 'whirlpool', $salt . $password ) );
}

// compare a password to a hash
function comparePassword( $password, $hash )
{
    $salt = substr( $hash, 0, 8 );
    return $hash == getPasswordHash( $salt, $password );
}

// get a new hash for a password
$hash = getPasswordHash( getPasswordSalt(), $password );</pre>

<p>You don&#8217;t have to attach the salt to the hash, you can instead store them separately within the database, but I like keeping them together in a single string. Equally, the salt needn&#8217;t be in hexadecimal, but I like the symmetry with the hexadecimal hash.</p>

<p>Finally, <a href="http://www.matasano.com/log/958/enough-with-the-rainbow-tables-what-you-need-to-know-about-secure-password-schemes/">as Thomas Ptacek points out</a>, you don&#8217;t want the fastest hash algorithm in the world for this &#8211; a fast algorithm is more useful to an attacker than it is to you.</p>]]></content:encoded>
			<wfw:commentRss>http://www.richardlord.net/blog/php-password-security/feed</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Protecting a swf</title>
		<link>http://www.richardlord.net/blog/protecting-a-swf</link>
		<comments>http://www.richardlord.net/blog/protecting-a-swf#comments</comments>
		<pubDate>Wed, 21 Mar 2007 13:54:55 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.bigroom.co.uk/blog/protecting-a-swf/</guid>
		<description><![CDATA[<p>In my training courses I often get asked about protecting swf movies. There's two sides to this - one is encrypting the code to make it hard for others to decompile and use, and the other is limiting where the swf can be used from so that users can't simply place your swf on their website.</p>

<p>There are a number of commercial and free obfuscating and encryption tools to help protect your code so I'm not going to say any more about them (maybe in a later post). Here's a few ideas for how to limit where the swf movie may be used.</p>
]]></description>
			<content:encoded><![CDATA[<p>In my training courses I often get asked about protecting swf movies. There&#8217;s two sides to this &#8211; one is encrypting the code to make it hard for others to decompile and use, and the other is limiting where the swf can be used from so that users can&#8217;t simply place your swf on their website.</p>

<a name="obfuscators"></a><p>There are a number of commercial and free obfuscating and encryption tools to help protect your code, three of which are <a href="http://www.genable.com/aso.html">ASO</a>, <a href="http://www.amayeta.com/software/swfencrypt/">SWFEncrypt</a> and <a href="http://www.kindisoft.com/">SecureSWF</a>, so I&#8217;m not going to say any more about them (maybe in a later post). Here&#8217;s a few ideas for how to limit where the swf movie may be used.</p>

<h2>What domain is the swf running in?</h2>

<p>The swf can check to see what domain it&#8217;s running in and exit if the domain isn&#8217;t allowed. You can do this with a function like this</p>

<pre class="code">function isDomainAllowed( allowed:Array ):Boolean
{
    var lc:LocalConnection = new LocalConnection();
    var domain:String = lc.domain();

    for( var i:Number = 0; i < allowed.length; ++i )
    {
        if( domain == allowed[i] )
        {
            return true;
        }
    }
    for( var i:Number = 0; i < allowed.length; ++i )
    {
        if( domain.substr( - ( allowed[i].length + 1 ) ) )
                        == "." + allowed[i] )
        {
            return true;
        }
    }
    return false;
}</pre>

<p>This function receives  an array of allowed domains and checks the domain in which the movie is running against the array. If the swf is running in any of  the domains or a subdomain of any of them then the function returns true, otherwise it returns false.</p>

<p>You use it like this</p>

<pre class="code">var domains:Array = new Array(
    "bigroom.co.uk",
    "example.com",
    "localhost"      // allow local testing
    );
if( isDomainAllowed( domains ) )
{
    gotoAndPlay( "content" ); // play the movie
}
else
{
    gotoAndPlay( "forbidden" ); // display some error message
                                // - more about this later
}</pre>

<h2>What flash player is the swf running in?</h2>

<p>In the previous method, the localhost value in the array is to allow testing of the movie locally, in the Flash development environment or in a local web page. It also allows users to download the swf and run it locally or to load it into a projector. If you want to ban all local use of the swf then you can just remove the localhost value from the array of allowed domains. However, if you want to restrict the local use to some instances only (e.g. the Flash IDE only) you need to test what flash player the movie is running in. That works like this</p>

<pre class="code">function isPlayerAllowed( allowed:Array ):Boolean
{
    var player:String = System.capabilities.playerType;

    for( var i:Number = 0; i < allowed.length; ++i )
    {
        if( player == allowed[i] )
        {
            return true;
        }
    }
    return false;
}</pre>

<p>The possible values of System.capabilities.playerType are</p>
<ul>
<li>ActiveX - the active-x control used in Internet Explorer</li>
<li>PlugIn - the plug-in used in other web browsers </li>
<li>StandAlone - the stand alone player and projectors</li>
<li>External - the test movie mode in the Flash IDE</li>
</ul>

<p>So the isPlayerAllowed function is used like this</p>

<pre class="code">var players:Array = new Array(
    "ActiveX",
    "PlugIn",
    "External"      // allow local testing
    );
if( isPlayerAllowed( domains ) )
{
    gotoAndPlay( "content" ); // play the movie
}
else
{
    gotoAndPlay( "forbidden" ); // display some error message
}</pre>

<h2>Load a file from the server</h2>

<p>A third option is to try to load a file from your web server. If the load fails, abort
the movie. Something like this</p>

<pre class="code">function testWithServer( callback:Function ):Void
{
    var receiver:LoadVars = new LoadVars();
    receiver.onLoad = callback;
    receiver.load( "http://example.com/testswf.txt" );
}</pre>

<p>Which is used like this</p>

<pre class="code">function testResult( success:Boolean ):Void
{
    gotoAndPlay( "content" ); // play the movie
}
else
{
    gotoAndPlay( "forbidden" ); // display some error message
}

stop();
testWithServer( testResult );</pre>

<p>This is quite basic - The file can be an empty text file - it needs no content. The function succeeds if the file can be loaded and thus is dependent only on the cross-domain policy for the domain hosting the test file that's loaded. If the policy allows the movie to load the file then it succeeds. The advantage to this is that we can update the allowed domains for our swf simply by modifying the cross-domain policy file on the server - there's no need to touch the flash movie. <a href="http://www.adobe.com/livedocs/flash/8/main/00001621.html">(More info on cross-domain policy files here)</a></p>

<p>It's important that the url is not a relative url - that would enable someone to bypass the security simply by placing an appropriate file on their own server.</p>

<p>There are many ways that this method can be enhanced, for example</p>

<ul>
<li>by sending the domain to the server and recieving a response that indicates whether the domain is allowed (and logging any disallowed domains)</li>
 
<li>by generating a unique id each time the page containing the flash movie is loaded and passing it to the movie via the FlashVars. The swf then passes this back to the server when asking permission to run. The server allows each id to be used once only.</li>

<li>by using encryption in the query and response (see <a href="http://www.meychi.com/archive/000031.php">ASCrypt</a> for some actionscript encryption code).</li>
</ul>

<p>But the basic system of an absolute URL and one or more (you can give each swf a unique policy file that it loads via the System.security.loadPolicyFile() method) cross-domain policy files is enough in many cases.</p>

<h2>Conclusion</h2>

<p>Each of these three ideas can be used individually or all together. Personally, I like the way that the first two are contained within the flash movie and require no special content on the server. Alternatively, the last method lets you update the allowed domains without editing the flash movie itself so each have their advantages. Note that if your source code can be decompiled then all these tests can be circumvented by simply removing the test altogether, so you may want to take another look at those <a href="#obfuscators">encryptors and obfuscators</a>.</p>

<h2>What to do if playback isn't allowed?</h2>

<p>If your test reveals that the movie shouldn't be allowed to play, then what should you do? There's two basic policies you could turn to</p>

<ul>
<li>Tell the user what's going on - display a message like "This movie/game/whatever can be viewed at http://example.com/funkyswf.html".</li>
<li>Cause the player to crash - a simple <code>while( true );</code> creates an infinite loop to achieve this.</li>
</ul>

<p>I choose between these options based on specific circumstances. The second option gives a potential thief fewer clues as to what's going on, but you could use the first option to tell the thief where to legitimately obtain the swf (and how much it will cost).</p>

<p>I hope this is useful to you. What security techniques do you use?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.richardlord.net/blog/protecting-a-swf/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

