Sandcastles & Security

Posted by on July 27, 2010
 

By the time I was 10, my mom stopped buying me electronic toys. While the first few days would go well, it was just a matter of time before I’d turn it into a mass of wires and circuitry. While I’d sometimes manage to turn it into something else, often it would merge with other masses of wires and circuitry. Unfortunately, I’m pretty sure Marco and Cal are on their way to a similar conclusion..

After playing with Flex off and on for a couple of months, I decided I would try to break it. I’m not a security guy at heart, but I’ve listened closely and improved my own stuff, so I quickly came up with four ways that I might be able to cause problems with Flex. Here are my results with each. To be clear, it is not my goal to be a nefarious troublemaker and break everything. My goal is to find out where things could break.

First, the easiest to get started with is general web access. If we can get a Flex application to load a specific URL, we might be able to make it misbehave. Out of the box, there are a few different ways to do this. We can use the URLLoader (immediately below) or if you’re using AIR, the HTMLLoader (second sample), but either way it’s just a handful of lines of code:

var loader:URLLoader = new URLLoader();
var path:String = txtURL.text;
var request:URLRequest = new URLRequest(path);
loader.addEventListener(Event.COMPLETE, captureContent);
loader.load(request);

This assumes another function – captureContent – is written but all it does is add the content into a TextArea. As far as I can find, this one is secure. The local client doesn’t execute anything in the content, it simply loads it as a string. In order for anything to be executed, the client would specifically have to parse it out. This seems like a lot of effort since if you can do that, you can try a simpler attack using ActionScript itself.

var container:Sprite;
var html:HTMLLoader = new HTMLLoader();
html.height = 400;
html.width = 400;
html.height = 600;
var urlReq:URLRequest = new URLRequest(“http://www.adobe.com/”);
html.load(urlReq);
container.addChild(html);

This sample was lifted from the documentation from the HTMLLoader documentation on Adobe’s site.

Since this can render HTML and even Javascript, it seems like it will be more successful. Luckily, there are a handful of things – namely eval(), setTimeOut(), setInterval(), and new function() declaration  – that are immediately blocked by the engine itself and even generate errors. More importantly, this executes within its own sandbox with even less permissions than the core engine and without access to any of the AIR API’s. This sandbox keeps its own browser history and cookies and is fully manipulable from the AIR libraries but not vice versa.

Next, let’s see what we can do closer to home with simple network access. If I can look at the resources on your network – computers, file shares, printers, coke machines – I may be able to scan them for vulnerabilities or steal the design documents for your BFG 9000. To get started, I went with their basic SocketMonitor class. With three lines of code, I was able to monitor network connectivity. While not my immediate goal, it seems like the easiest way to detect when I should work off a local cache or interact with the server. This will be useful in the web2project AIR client, but for now, back to my nefarious plans… when I attempted to scan the network or connect to specific machines with anything beyond a boring http request, I couldn’t accomplish anything useful. That is, until I discovered NativeProcess, but more on that later..

Next, let’s see what we can do to the filesystem. For a malicious troublemaker, this approach would be the most difficult – they’d have to get the user to download and run the application with the hope that AIR is installed – but it’d also be the most powerful. For someone like me just seeing what the limits are and where I might run into trouble, we’ll take it easy and not break everything. So let’s see what we can delete. With two lines of code – the trace statements are debugging – I was able to delete a key file:

var myFile:File = new File(‘C:/xampp/php/php.ini’);
trace(myFile.exists);
trace(myFile.nativePath);
myFile.deleteFile();

But maybe I don’t want to delete files and maybe just collect information. In that case, a simple myFile.load() will get the contents of the file.

Since I was previously more familiar with Flash in the browser, I was surprised digging deeper in the security sandbox clarified it. Just as any application installed in your local environment, an AIR application inherits its permissions from the user running it. While there’s not much to do to further lock AIR down, you should ensure that all applications from from sources you trust.

Next, we can attempt database access. While the SQLite library is built into AIR out of the box, connecting to MySQL or SQL Server is not possible without an additional library. More importantly, since the recommended way of “connecting” to one of these databases is through an XML or AMF-based service layer, this isn’t likely to be an effective attack. That said, interacting with SQLite is quite simple so you could attempt to connect to other SQLite databases for other applications. Fortunately, it’s almost trivial to encrypt your database in an AIR application, so this is a remote possibility at best.

Finally, after much investigation, I found the biggest opportunity for trouble: the NativeProcess class. This class – only available since AIR 2 SDK released last month – allows AIR to interact directly with other applications on the host operating system. You can start processes, kill process, execute shell scripts, or just do things on the command line in general. Obviously, this can be trouble. As a simple test, I started a new process within an infinite loop and watched the debugger crawl. To finish the earlier thought, once you have command line access, you can scan the network, connect to file shares, and even interact with printers. Since these commands will have to be operating system specific, it would be difficult to build a general purpose tool, but you could accomplish some creative tasks.

Of course, we can behave ourselves and use this to create amazing things too. There’s even an example on creating your own screen recorder in AIR 2..

Overall, I was hoping to break Flex and see where I might be able to cause some problems or protect myself from problems. I found a few places – like with the HTML processing and filesystem access – that could be problematic and should be handled with care, but realistically, a Flex/AIR application behaves exactly like you’d expect any desktop application to behave. Granted, as web developers we’ve rarely had to worry about that, but it’s something we need to consider and get used to as we work on the desktop more and more.


About the author—Keith Casey has been a developer for over a decade and helps organize various tech communities. Previously, he was a professional agitator within the Washington, DC until he decided to explore Austin, TX in 2010. To pay the bills, he works as a Developer Evangelist for Twilio to get good tools to good developers so they can build great things. Previously, he built large-scale PHP-based systems for organizations ranging from major news companies to small non-profits. In his spare time, he is a core contributor to web2project, works to build and support the Austin PHP community, co-founded the HubAustin coworking space in South Austin communities, blogs regularly at CaseySoftware.com and is completely fascinated by monkeys.