Thursday, March 11, 2010

Debugging private variables in Flex

Introduction
Proudly brought to you from the dept of thuggery, buggery and skullduggery, here is a bit of a hack which enables you to access another classes private variables in a semi-controlled manner.

You want to do what?!?
Many out there should be shaking their heads right now. Yes, I agree, a belligerant attitude towards breaking a canonical axiom in Object Oriented programming rarely ends well, however, given the right situations, and preventative steps, it can be a useful way to get around certain... how shall we say... issues..

As always with dirty rotten hacks, let's investigate the rule we are breaking, followed by when you definitely should not break it.

Why private variables are good
Private variables help in preventing an anti-pattern known as Action at a Distance. If you just let any old programmer from any old class, access any old variable, and change it, you are opening yourself up for a real world of hurt.

Why private variables are bad
Most programmers follow Test Driven Development and a good Separation of Concerns philosophy. These two requirements can be at loggerheads at times, as although you want to shield your application from becoming a mess of spaghetti with a good selection of private and protected variables, when it comes to testing, the same protections that keep programmers out, keep your test framework out as well.

When, where and why you want to break encapsulation
My first year lecturer was a pretty cool dude who always wore a sarong, no shoes, and more than one occasion rode into our lecture theatre on his motor cycle.

We once asked him why you should not be able to access private variables from the outside, even from instances of the same class. His response, was for us to imagine that we are all instances of the class of students. We definitely should not be able to just start messing with each others privates. The discussion abruptly ended there.

But when would it be acceptable to access a private variable? The answer is, whenever your are performing diagnostics. It isn't a bad thing for your doctor to have access to private areas in the process of diagnosing a problem, is it? It is the same for your code.


Let's get down to code
We'll start off with the ArgumentFunctionPair object. This is basically an argument chain, followed by a function that's invoked outside passing the value out.
public class ArgumentFunctionPair
{
public var argument:String;
public var functionVar:Function;
public function ArgumentFunctionPair(argument:String, functionVar:Function)
{
this.argument=argument;
this.functionVar=functionVar;
}
}

Here we have the visitInternal function that gets attached to your class that you wish to allow to have the visitor.
//reflective function to test properties and values for unit testing purposes
protected function visitInternal(errorFunction:Function, argFunctionPair:ArgumentFunctionPair):Boolean
{
var integrityOK:Boolean=false;
var returnObj:Object;
try
{
returnObj = this[argFunctionPair.argument];
}
catch(e:Error)
{
errorFunction("ERROR: " + argFunctionPair.argument + " was not found.");
}
finally
{
argFunctionPair.functionVar(returnObj);
return integrityOK;
}
}


So why go throught this elaborate ruse?
It's all about preventing a visitor from changing a private internal. You never know when you'll get some sort of clever programming getting in there and thinking he can just sneak a change in when you're not looking.

With this sort of methodology, it makes it quite a bit harder to turn the function into a method to access the classes private variables.

Tuesday, March 2, 2010

Security in the Cloud - Avoiding the equivalent of an open relay

Few things strike terror in the hearts of seasoned administrators. An open relay is one of those things.


What is an open relay?

An open relay comes from the good old days of Internet, when mail servers would simply receive requests to send out messages to other mail servers. It was built on a model of trust, and was conceived before anyone saw a benefit to sending out messages regarding cheap places to buy viagra to completely random strangers.

An open relay costs big money. Not only due to bandwidth used, but due to blacklisting of your server due to spam reports.


So how does this apply to cloud?

I saw a demo from Dan Orlando on how to integrate an Adobe Air application with S3. Very cool stuff, and definitely worth looking into.

In summary, he's providing an example on how you can access your S3 bucket.

The first second I saw this application, I thought to myself. Awesome! This could be used to collaborate with files, to be able to send information to an online repository so that multiple people can access it.

Then I came to the realisation that each person would need to have a public/private access key for the bucket. This is not reasonable to do in a large system. I've researched the topic a bit and discussed with a few people, and they have a range of ideas, each one more terrifying to me than the next.

Why is this terrifying? Because you are basically giving a third party user the keys to your cloud platform. Why is this a problem?

Show me the money!

It is a problem. It doesn't take a genius to realise that giving a nefarious person access to a storage system to place files is just simply a bad idea. Why?

1. Phishing port

A place to store files on the internet, such as pictures etc. You take the heat, you pay for the bandwidth, they get to sell their Viagra/Tic Tacs.

2. Dark Side File store

From everything from WAREZ to undescribable images/movies that will get Interpol kicking down your door, your platform can be used for some pretty darn nasty stuff.

Let's not forget Trojans, virii etc.

3. Other access to Amazon

If they only gain access to your bucket, it isn't inconceivable that with your root key some black hat won't be able to spawn off a few EC2 servers to crack a few SSL key pairs or otherwise do numerous bits of distributed number crunching. After all, this is what Grid, er, I mean Cloud Computing was designed for!

Not to mention that you'll be getting quite a huge bill at the end of it all.

What should I NEVER do under any circumstances?

As Amazon quite clearly states. Give out, or embed your secret key in your Flex/AIR applications.

The problem is that to communicate directly from the client to S3, as far as I can tell you must have the private key included in the communication.

A RESTful state of unREST

In the good old days where programmers were programmers, and compilers were compilers, there was a level of automatic obfuscation present, as when you compiled your executable, it went to machine/byte code, and that was the end of it.

Unfortunately, with applications like Flex, all you need to do is to run the .SWF file through something like trillix, there is absolutely no way to keep your procedures secret. Including your authentication mechanism.

So let's say you run a login service in a Mid-Tier like JAVA, although it could be PHP, Ruby, whatever. Let's say that the user supplies their username/password to authenticate, and is then passed a private key to access a set of buckets. Problem solved, right?

Wrong.

There is no expiry on this key at this point in time, and it grants you complete and unabridged access to the bucket.

What are some possibilities for security?

Token Based Authenticated Security

If it would be possible to allow for a set of tokens, and a set of permissions to be placed to the files on S3, then that is ideal.

S3 is not about services that need to be allowed, but rather permission to read data. If you are blocked from reading the data, you have satisfied the security requirements. If you have access to the data where you should, and only where you should, you have met the user requirements.

I am unaware of a token based authentication service from AWS. If you could store your private key on your JAVA/PHP/whatever mid tier, securely held behind your standard security perimeter, you could then authenticate the username/password from the service. The service would call AWS, and register a token with a set expiry date, with a set of permissions.

The token would then be sent to the client, and the client could use the security priviliges which were previously authenticated.

Other

Ladies and Gentlemen of the Internet, please comment on any other ideas you might have on this topic. Also, watch this space, as I will be updating it as more information/AWS functionality comes to light.