Flash Security at the end of Flash era

Flash era is rapidly wrapping up and it is important to ensure the security of Flash applications we leave behind us.

Danger of crossdomain.xml

crossdomain.xml specifies the following:

  • If https://other-domain.com/evil.swf can read data from your domain https://mycorp.com/user-mail
  • If other crossdomain policies can be found on your domain e.g. https://mycorp.com/relaxed-app/user-supplied-file.csv

If you don’t provide or provide inappropriate https://mycorp.com/crossdomain.xml and some data on your domain is protected by:

  • Cookies
  • HTTP Authentication
  • Other ambient user credential e.g. client certificate

then attacker can steal that data without user even noticing.

Example: https://mail.mycorp.com allowing all everybody access it. Then if I just embed invisible SWF on kachurovskiy.com homepage and make it load https://mail.mycorp.com then I’ll get all your mail without you even knowing about it.

Overly broad crossdomain.xml

If your crossdomain.xml contains <allow-access-from domain="*"/> then you’re in trouble unless your domain serves only public data. Same stands true for allowing untrusted domains or domain that allow user-controlled data to be served from them.

No crossdomain.xml

If you don’t have /crossdomain.xml malicious SWF can ask Flash Player to load crossdomain policy from https://mycorp.com/userfiles/vasily.txt on your server and gain access to all URLs under https://mycorp.com/userfiles/!

The safest /crossdomain.xml

Ultimate SWF Security Solution

Delete all SWF that are no longer needed. Every SWF file is a chance for attacker to:

  • Execute attacker-supplied JavaScript by e.g. making your app call navigateToURL(new URLRequest("javascript:alert(1)"))
  • Use SWF as a proxy to make requests to your domain if your SWF calls System.allowDomain()
  • List goes on

Moving SWFs to a cookie-less domain

Moving SWF to a cookie-less domain prevents attacker from making use of:

  • JavaScript injection bugs
  • Security.allowDomain("*") bugs

You can still allow SWF to interact with main domain by allowing that particular domain, see for example YouTube’s crossdomain.xml, just double check that you’re not using Security.allowDomain() at the same time.


If https://mycorp.com/mail.swf will execute Security.allowDomain("*") or Security.allowDomain("other-domain.com") then https://other-domain.com/evil.swf will be able to load your SWF and access all it’s content, variables and methods. It’s likely to give evil.swf access to all the information and actions available to mail.swf and in general to https://mycorp.com which may be problem as you already know.

The safest solution is to remove all Security.allowDomain() calls or at least get a really good understanding what you are allowing by calling this method. This is especially true for AS 2.0 since it has content loading method attached to the display tree.

Hosting user files

This is not really related to Flash but is too often overlooked. There is a very good reason why all Google products serve all user supplied content from separate domains e.g. googleusercontent.com. Find out why.

Learn more

This is just a quick overlook of common Flash-related security issues that is intentionally short so that you don’t fall asleep reading.

This post is powered by book The Tangled Web – awesome and rewarding reading for Web Developer.

Spark AdvancedDataGrid

I have used the logic from Spark Tree to build AdvancedDataGrid based on Spark DataGrid and it seem to work nice:

View Source

Since AdvancedDataGridcontains a few code and uses a lot of Spark Tree logic I’ve decided to add it to the Spark Tree project in GitHub.com instead of creating a separate library.

Note: you will not see disclosure icons unless you specify corresponding item renderer for some column: <s:GridColumn itemRenderer="com.sparkTree.DefaultTreeADGItemRenderer"/>

Download SparkTree4.5.swc for Flex SDK 4.5 and higher.

Please report bugs in comments or to the GitHub Issue Tracker.

Pronto 4

I’m happy to present the project I’ve been working on for the last 2 years.

Continue reading “Pronto 4″

FTheme.com launch

FTheme.com is my new library that hopefully will make a small revolution in Flex 4 styling and skinning. New application look can be created in Notepad, loaded at runtime and change everything from application background bitmap fill to the CheckBox-es size.

Hope that you enjoy existing looks (NightSky is my favorite). Looking for forward for your feedback and new exciting looks.

Year summary

It was a good year, thank you for reading this blog – hope it is useful at least sometimes :) Starting from the 20-th August 2010 when this blog was opened:

  • More than 2900 people came and read more than 5000 pages
  • Average time on site for each visitor was more than 2 minutes.
  • 600 visitors came from USA, 585 from Russia and 222 from Ukraine.
  • Most popular posts were Spark Tree and storing icons in external ZIP.
  • 45% were using Firefox, 31% Chrome and 10% Safari.

Here is some personal statistics according to the StatSVN:

  • In this year I’ve committed 277 559 lines of code that is 1 100 lines/day.
  • 45% lines were modifications and 55% were new.

One of my next posts is going to be about the look&feel customization system that we are developing in CommuniGate for Pronto:

It’s super-powerful, lightweight and fully backward-compatible (while runtime Flex styles in SWFs are not).

Spark Tree on GitHub

I’ve just uploaded Spark Tree component to the GitHub so if you’ve got some updates or bug fixes – please send pull requests :) Also the package is changed – now it’s com.sparkTree.

Download SparkTree.swc
Download source code

AMFPHP in convinient and reliable way

Remoting with AMFPHP greatly simplifies the client-server application logic. Now I’m going to simplify it’s usage. No responders, no listeners or clients. Just one call(...) and one callback function:

  1. private function init():void
  2. {
  3.     new Gateway("http://localhost/amfphp/gateway.php");
  4. }
  6. private function listButton_clickHandler(event:MouseEvent):void
  7. {
  8.     listButton.enabled = false;
  9.     call("Persons.listPersons", 10, listPersonsCallback);
  10. }
  12. private function listPersonsCallback(object:Object, errorText:String):void
  13. {
  14.     listButton.enabled = true;
  15.     listButton.errorString = errorText;
  16.     if (errorText)
  17.         return;
  19.     // handle persons from object
  20. }

Here is the Persons.php service:

  1. < ?php
  2. class Persons
  3. {
  5.     var $link;
  7.     public function __construct()
  8.     {
  9.         $link = mysql_connect(DB_HOST, DB_USER, DB_PASS);
  10.         if (!$link)
  11.             throw new Exception("DB connection error" . (PRODUCTION_SERVER|> ? "" : ": " . mysql_error()));
  12.         if (!mysql_select_db(DB_NAME))
  13.             throw new Exception("DB selection error" . (PRODUCTION_SERVER|> ? "" : ": " . mysql_error()));
  14.     }
  16.     function listPersons($limit)
  17.     {
  18.         $query = sprintf("SELECT * FROM persons LIMIT %d",
  19.             mysql_real_escape_string($limit));
  20.         $this->_handleResultError($result = mysql_query($query)));
  22.         return $result;
  23.     }
  25.     // utility function
  26.     function _handleResultError(&$result)
  27.     {
  28.         if (!$result)
  29.             throw new Exception("query error" . (PRODUCTION_SERVER|> ? "" : ": " . mysql_error()));
  30.     }
  32. }

Download Gateway.as and call.as

Callback function can have the following signatures depending on the application logic:

  • function():void
  • function(errorText:String):void
  • function(object:Object, errorText:String):void

Easy solution for one annoying HGroup/VGroup layout issue

Text elements in horizontal and vertical layouts are sometimes coward. When text is small, layout looks nice:

If the text is controlled by user and layout is not smart enough, it can look this way:

“Logout” button is invisible, search field is cropped.

It happens when HGroup or VGroup (horizontal/vertical layouts) are used since giving elements as much space as they require is their logical behavior. My colleague Nikita Petrov has shown me a very easy to avoid this:

Storing icons in external ZIP and seamless work with composite icons

There are a lot of ways to work with icons in Flex, e.g.:

  • Use @Embed(...) directive inline
  • Use [Embed(...)] metatag and store all icons in class like Assets.as

All this is good until you have too much assets because:

  • Each Embed directive takes huge time during compilation
  • Developer can not optimize memory/CPU usage via passing one BitmapData to the same Bitmaps instead of creating new BitmapData for each icon
  • Embed sometimes fails during incremental compilation

Another huge problem I’m going to address today is the runtime icons layering. Imagine you need these 9 icons (thanks to webappers.com):

The simple solution is just to embed all of them. But wouldn’t it be better to store and load only these 6 icons? You can compose them in runtime!

Continue reading “Storing icons in external ZIP and seamless work with composite icons”

Cloud Layout

Here is the CloudLayout.as [plain] that does nice Web 2.0 tag cloud:

View Source