2015/03/28

Cynical bugger that I am...

I can be a little cynical sometimes though going through the morning news it seems there's been a couple of rather heartwarming moves by a some  of our overlords today...

Microsoft to require suppliers to provide paid leave to workers (though Bill doesn't look too happy in the photo he's got my respect for the work of the Gates Foundation).


Apple boss Tim Cook 'to donate millions' to charity (and he can pay my sons university fees if he wants to as well!).


I suspect the shareholders of neither MS or Apple will care much though as it doesn't really affect them and there's a long way to go yet to address the inequality but... oops, there goes my cynicism again... :)

 

2015/03/26

Security Vulnerability Review

Secunia have released an interesting report on the number of vulnerabilities found across various products. There's much talk about MS and non-MS products which kind of makes sense from a Windows perspective but the report also contains a list of "20 core products" with most vulnerabilities identified in 2014.

Trouble is the report doesn't specify where and how this "core" list was compiled; contrary to the 50 portfolio products which is based on the Secunia client running on Windows devices.

If it's the same Secunia client - and I suspect it is since the number of vulnerabilities match for those products in both lists where I would expect some potential variance (Chrome on Windows v OSX for example) - then it's rather odd that OSs such as Oracle Solaris and Gentoo Linux crop up... Hypervisors perhaps...

Another shocking thing for me was the number of IBM products in that top 20; 8 out of 20! Really? 40% of the products with most vulnerabilities are from IBM? Of course few people use these things (IBM Tivoli Composite Application Manager for Transactions anyone?) but it's possible the stats are skewed due to too little data but it doesn't sing well for big-blue... other than perhaps noting that they seem to find-'em and fix-'em.

... and that Java was #17 on the list is more worrying. That beastie is everywhere and riddled with problems...

2015/03/09

Session Abolition

I've been going through my bookcase; on orders from a higher-being, to weed out old, redundant books and make way for... well, I'm not entirely sure what, but anyway, it's not been very successful.

I came across an old copy of Release It! by Michael T. Nygard and started flicking through, chuckling occasionally as memories (good and bad) surfaced. It's an excellent book but made me stop and think when I came across a note reading:
Serve small cookies
Use cookies for identifiers, not entire objects. Keep session data on the server, where it can't be altered by a malicious client.

There's nothing fundamentally wrong with this other than it chimes with a problem I'm currently facing and I don't like any of the usual solutions.

Sessions either reside in some sort of stateful pool; persistent database, session management server, replicated memory etc., or more commonly exist stand-alone within each node of a cluster. In either case load-balancing is needed to route requests to the home node where the session exists (delays in replication means you can't go to any node even when a stateful pool is used). Such load-balancing is performed by a network load-balancer, reverse proxy, web-server (mod_proxy, WebSphere plugin etc.) or application server and can work using numerous different algorithms; IP based routing, round-robin, least-connections etc.

So in my solution I now need some sort of load-balancer - more components, joy! But even worse, it's creating havoc with reliability. Each time a node fails I lose all sessions on that server (unless I plumb for a session-management-server which I need like a hole in the head). And nodes fails all the time... (think cloud, autoscaling and hundreds of nodes).

So now I'm going to kind-of break that treasured piece of advice from Michael and create larger cookies (more likely request parameters) and include in them some every-so-slightly-sensitive details which I really shouldn't. I should point out this isn't is criminal as it sounds.

Firstly the data really isn't that sensitive. It's essentially routing information that needs to be remembered between requests - not my credit card details.

Secondly it's still very small - a few bytes or so but I'd probably not worry too much until it gets to around 2K+ (some profiling required here I suspect).

Thirdly, there are other ways to protect the data - notably encryption and hashing. If I don't want the client to be able to read it then I'll encrypt it. If I don't mind the client reading the data but want to make sure it's not been tampered with, I'll use an HMAC instead. A JSON Web Token like format should well work in most cases.

Now I can have no session on the back-end servers at all but instead need to decrypt (or verify the hash) and decode a token on each request. If a node fails I don't care (much) as any other node can handle the same request and my load balancing can be as dumb as I can wish.

I've sacrificed performance for reliability - both in terms of computational effort server side and in terms of network payload - and made some simplification to the overall topology to boot. CPU cycles are getting pretty cheap now though and this pattern should scale horizontally and vertically - time for some testing... The network penalty isn't so cheap but again should be acceptable and if I avoid using "cookies" for the token then I can at least save the load on every single request.

It also means that in a network of micro-services, so long as each service propagates these tokens around, the more thorny routing problem in this sort of environment virtually disappears.

I do though now have a key management problem. Somewhere, somehow I need to store the keys securely whilst distributing them to every node in the cluster... oh and don't mention key-rotation...

2015/02/28

A little chit-chat

It's been a while since I posted anything so  I thought I'd write an article on the pros and cons of chatty interfaces...

When you're hosting a sleep-over for the kids and struggling to get them all to sleep you'll no doubt hear that plaintiff cry "I'm thirsty!", usually following in quick succession by 20 other "Me too!"'s...

What you don't do is walk down the stairs, fetch a glass from the cupboard, fill it with milk from the fridge and take it back upstairs... then repeat 20 more times - you may achieve your steps-goal for the day but it'll take far too long. Instead you collect all the orders, go downstairs once, fill 21 glasses and take them all back upstairs on a tray (or more likely just give them the bottle and let them fight it out).

And so it is with a client-server interface. If you've a collection of objects on a client (say customer records) and you wanted to get some more info on each one (such as the address) you'd be better off asking the server the question "can you give me the addresses for customers x, y and z?" in one go rather than doing it three times. The repeated latency, transit time and processing by the server may appear fine for a few records but will very quickly deteriorate as the number of records rises. And if you've many clients doing this sort of thing you can get contention for resources server side which breaks things for all users - even those not having a wee natter...

Is chatty always bad?

It comes down to the atomicity of requests, responsibility and feedback.

Atomicity...

If it's meaningful to ask a question like "can you give me the address for customer x, account-balance for customer y and shoe-size for customer z?" then by all means do so, but most likely that's really three separate questions and you'll get better reuse and maintainability if you split them out. Define services to address meaningful questions at the appropriate granularity - what is "appropriate" is for you work out...

Responsibility...

You could break the requests out server side and have a single request which collects lots of data and returns this at once rather than having lots of small requests go back-and-forth. This model is common for web-pages which contain data from multiple sources - one requests for the page, server collects data from sources and combines this in one response back to the user. Problem is, if any one of the the sources is performing badly (or down) the whole page suffers and your server chokes in sympathy as part of a cascading failure. So is it the responsibility of the server to collate the data and provide a unified view (often it is) or can that responsibility be pushed to the client (equally often it can be)? If it can be pushed to the client then you can actually improve performance and reliability through more chatty round-trips. Be lazy, do-one-thing-well, and delegate responsibility as much as possible...

Feedback...

Your end-user is a grumpy and impatient piece of wetware incapable of acting repetitiously who seeks instant gratification with minimal effort and is liable to throwing the tantrums of a two year old when asked to "Please wait...". God help us all if you send them an actual error... To improve usability you can trigger little round-trip requests to validate data asynchronously as they go and keep the user informed. This feedback is often enough to keep the user happy - all children like attention - and avoids wasted effort. Filling in a 20 page form only to have it rejected because of some cryptic checkbox on page 3 isn't going to win you any friends. And yet it is still o' so common... I generally work server-side and it's important to remember why we're here - computers exist for the benefit of mankind. User interface development is so much more complicated than server-side and yet simplicity for the user has to be the goal.

So chatty is generally bad for performance and reliability though it can though be good for UX and depending on where the responsibility sits, can improve things overall.

However, as we move towards a micro-services based environment the chatter is going to get louder and more disruptive. Understanding the nature and volumetrics of the questions that are asked of services and ensuring they are designed to address these at the correct granularity will help keep the chatter down whilst making the code more maintainable and reusable. As always, it's never black-and-white...

 

 

2015/02/02

ForgeRock License Confusion

IANAL which doesn't help me understand the ForgeRock license situation which looks to be as clear as mud.


Blogs like this suggest I'm not the only one to be confused.


Wikipedias page on ForgeRock suggests it's only the binaries you need a license for (if you compile yourself then is this ok?).


And the OpenAM project site suggests two licenses apply. Though one of these (the first one) states "This License represents the complete agreement concerning subject matter hereof" so how can they then go on to apply another "non-commerical" Creative Commons license constraint?


Joy! :(

2015/01/24

Don't Build Your Own Security Solution!

There are only three reasons why building your own security solution is a good idea:

  1. Security through obscurity - There's less likelihood that anyone will find the holes because no-one else is using it. This is just as well since your home-grown solution is probably riddled with them (see below).

  2. Risk v Cost - You've weighed the risk, baulked at the cost and decided the benefits aren't affordable.

  3. You're unique! - Some organisations may be unique and/or have unique problems for which there is not an off-the-shelf solution. You may be NASA or a top secret government department, or you could be one of the big internet organisations operating at the edge of technology and scale (fb, Google or the like) or it may just be your business to develop security products.


It's a fair bet that #3 doesn't apply to you and if you think the costs are too high then I suspect you've not really understood the problem.

There are many reasons why you shouldn't build your own security solution and should buy off-the-shelf instead:

  1. Risk - The suppliers of security product are much more likely to understand the potential security issues and deal with them correctly than your in-house developers. You may have some really nice people working for you but despite their assurances, they're not the experts. The most basic of attack vectors; weak passwords, code-injection, CSRF, XSS etc., can be left exposed by an in-house team who don't have the experience or knowledge to address them correctly. This point really can't be stressed enough. I do not consider myself to be a security expert but I have seen problems in every single home-grown solution I've come across.

  2. Features - Even basic administration capabilities require effort to implement - adding users, granting permissions, password resets, password rotation, revoking access etc. Add to this the expanding list of security patterns and protocols which may need to be supported (basic-auth, forms-based-auth, single-sign-on, WS-Sec, SAML, OAuth, multi-factor authentication etc.) and the range of vulnerabilities you need to address (buffer-overflow, virus scanning, intrusion detection etc.) and a home-grown effort can start to look pretty pathetic. Standards also evolve to improve quality and make interoperability easier and many off-the-shelf products will implement these accordingly. A home-grown effort likely won't efficiently lend itself to being manipulated to support such standards as they evolve - in either a qualitative or interoperable way.

  3. Swiss cheese - Buying an off the shelf solution isn't going to solve your problems overnight and your developers will still need to employ secure development practices in case something gets through. However with many layers of security (especially where from a variety of suppliers) comes additional protection. Every product will have holes but you hope the holes don't all line up allowing something through. The more layers the better though home-grown layers have lots of holes.

  4. Support - As new vulnerabilities are discovered you'll have (should have) a support contract in place with the supplier to provide patches to address these as they arise. With an in-house solution you'll probably never know you've a problem until it's too late. Furthermore, the obscurity benefit is a millstone around your neck. Finding developers to support the solution will become increasingly difficult (and expensive) as the years go by. No developer wants to be left supporting pre-historic software, it's a dead-end career role.

  5. Maintenance - As technology marches on, the environment in which you operate changes. Constant upgrades in browsers, operating systems and devices means you've got to continue to develop solutions just to remain compatible with your users. The time and costs this consumes can quickly mount. The same issue can be charged at commercial vendors and you should ensure your supplier has the mind to consider the upgrade path before you sign on the dotted line.

  6. Blame! - Ultimately if something goes wrong you'll have someone to shout at, sue and/or get emergency fixes from. You can still do the same for in-house solutions, it's just that you'll be the one being screamed at and if the breach is bad enough you could well be scanning jobserve sooner than you wanted.

  7. Cost - If you can afford to fund development to address the risks, develop, maintain and support a fully featured product then by all means do so. Odds are that you can't.


I could (and do) levy many of these issues at any home-grown solution and not just security but I fear security is the most heinous case as it's taking risks with other peoples data.

Ultimately we need to ask the fundamental question as to whether it's our business to be writing some software product or whether we should focus on our own specific goals and let someone else, someone more qualified, do that for us.

In the case of security it's almost always better to buy off the shelf.

Voyaging dwarves riding phantom eagles

It's been said before... the only two difficult things in computing are naming things and cache invalidation... or naming things and som...