Sunday 28 February 2016

Security by Certainty



We are becoming more and more aware of the consequences of security problems with it now becoming common place to see headlines about a hack, breach or loss of data.
The causes of these incidents is often a mixture of honest mistakes, incompetence or naivety, and unfortunately in the majority cases the exploit stems from a well known problem or vulnerability that could of been protected against.
The Open Web Application Security Project (OWASP) is a non-profit organisation trying to share knowledge to ensure that everybody can continually learn how to secure software and infrastructure, allowing everyone in the industry to protect each other by sharing their experiences.
As part of this mission OWASP have devised a set of core principles to ensure that security is built in to our coding, presented below are some of the themes of those principle.
Keep It Secure Stupid
As with so many aspects of software engineering following certain core principles brings unintended rewards, you succeed without even trying. 
Many security problems are caused by bugs with unfortunate consequences, the more complex a code base the more likely it is that these kind of defects will be accidentally created.
Following principle such as KISS and YAGNI while also applying strong separation of concerns will help minimise the surface area of any potential attack.
Proper engineering discipline we also make it easier to identify opportunities for defence in depth whilst also ensuring that everyone working on the code base understands the routes in and out of the system and how they should be secured.
Default to Secure
The majority of attacks that cause a system to give up more than it should arise from forcing an unexpected error state or otherwise causing some aspect of the system to fail.
This type of behaviour can be seen in attack such as buffer overflow or processing unvalidated input data such as a SQL injection attack.
Its is key in these situations to put no faith or trust in the world outside the system your working on, check everything and assume that any possible error could happen.
Once you have this attitude of distrust you can ensure that your code defaults to a secure position whenever these errors occur.
Not only is this producing a more secure system its also providing a better user experience by avoiding crashes or other undesirable behaviour.
Assume they Know Everything
Its an often spoken adage to avoid security by obscurity but unfortunately one that we don't always follow. 
The security of your system should not rely on secrecy of implementation, you should be in a position where an attacker who knows every aspect of your system is still unable to formulate a successful attack.
The security of a bank vault is not dependent on robbers not knowing its location, make or model, and in a similar fashion code should be protected from the security that comes from well understood and well implemented security protocols.
The importance of security in software engineering is only going to grow and will soon become a string all developers will need to have to their bow.
Security can't be left to the user and even if you or they don't consider the data in question sensitive it may well be the key that allows an attacker to compromise something the user does want to protect, thinking the world is out to get you and nobody can be trusted is in this circumstance is a very healthy attitude to take..

Sunday 7 February 2016

In Defence of OOP



Although probably still a minority opinion there are voices out there that say that Object Oriented Programming (OOP) is a failure and that procedural/functional programming is the new king of paradigms.
Assuming there is one hammer for all nails is a very limiting view of the world and there are definitely situations where OOP is not the most effective answer but in criticising its use we have to be sure we aren't just criticising bad practitioners.
It is all too easy to write bad OO code but does that mean OOP itself is bad? If you show me a language or paradigm where its impossible to write bad code then I'll show you a system where its impossible to creatively find solutions to difficult problems. 
Dragged Down by the Noun
When were first exposed to OOP at college or university were often asked to think about everything fitting into a noun model.
The idea behind this is to demonstrate the ability of OOP to map the problem domain, it can represent the model you have in your head as classes in your code.
Those arguing against OOP will point to the fragility and inadequacy of trying to represent everything this way, software performs tasks and we need verbs as much or maybe more than nouns.
Good naming of classes is difficult, it should provide a good description of what the class represents or the task it performs whilst maintaining encapsulation and abstraction to hide the detail, but this is generally caused because it forces you to think about the design of your system and how the blocks fit together.
I would argue that no paradigm should be aiming to absolve you from the responsibility of having to think about the design of your code, that is the essence of engineering.
Getting Ourselves into a State
Many attacks of OOP will point to the dangers of mutating state and the non-deterministic chaos that can ensue.
An abundance of state, especially when its presence is not clearly signalled, does lead to all sorts of problems with readability, testability, maintainability and can make it difficult to achieve high levels of performance from parallelisation and other techniques.
We should be trying to eliminate as much state from our code as possible and create a deterministic system whose outputs are predictable and testable given any input.
But is it realistic to remove state from the equation entirely? At some point our code has to interact with the real world where state exists in everything we do, we may chose to have this state exist only in a database but does that mean its been eliminated.
Most issues with state are around badly managing its transition and having it exist in more than one place masquerading under different names, good design will solve this problem while being realistic that it cant be remove entirely.
Inheriting Problems
A large number of the issues cited against OOP are symbolised by inheritance, detractors will provide examples of confusing spaghetti code with inheritance as the mechanism for confusion to spread.
I think this particular criticism of OOP is entirely justified, inheritance is the nuclear option that too many developers rely on as a crutch for any situation where its not clear what the relationship between different classes should be.
While its possible to do almost anything without having to use inheritance its unrealistic to try and eliminate it entirely from our thinking. Inheritance has its uses and is usually key to the frameworks that define the overall structure of our systems (MVC, MVVM etc).
My disagreement with OOPs detractors is that the problems with inheritance are so bad that it undermines the use of OOP entirely.
Any structure or paradigm for writing code that is useful enough to be applicable in many varied situations is also likely to provide enough rope to bad developers to get themselves into an awful mess.
We have now been working with OOP in mainstream software development for bordering on 30 years, we have used it to advance the state of our art and write software that solves an increasing number of diverse problems.
To now suggest that all of that progress has been a waste of time seems slightly frivolous and maybe even reckless, is it not more sensible to say that this experience has taught us that we can develop different ways of thinking for different problems.
Functional programming is a brave new world in software engineering and it will allow us to progress our industry into even more useful and innovative ways but any time we say one way of thinking is the answer to all ills we are making a mistake, in the same way that badly written code that ignores good engineering discipline and practices is not an argument that a whole generation of learning is wrong.