By Jean-Christophe Collet, Senior Software Engineer at Olympe
The Log4J incident back in December served as a stark reminder that software vulnerabilities and security breaches only get more disastrous with time. The exponential increase of software complexity is, I believe, at the root of the problem.
When I got started as a developer things were simple (well, at least a lot simpler than now). Single threaded, single core, 8-bits CPUs with very limited memory (4K if you can believe it), you could almost run the whole thing in your head. On top of that the extremely limited resources at your disposal prevented you from getting overly ambitious.
Then computers started becoming more powerful, and complicated, at an alarming rate, thanks to the exponential nature of Moore’s Law. So, naturally software developers became more ambitious with multi-tasking operating systems like Unix at their disposal. Thankfully that’s also when open-source gave us tools and libraries to help manage the increasing complexity. But that came at the cost of managing external dependencies and, sometimes wildly different naming conventions or coding styles. For instance bcopy and memcpy serve the same function but do not agree on what argument should be first: the source or the destination. This made writing and maintaining software significantly more difficult.
At a reasonably early point in my career I adopted the K.I.S.S. design principle (‘Keep It Simple, Stupid!’ for the uninitiated) as one of the most valuable principles of software engineering. Unfortunately that growing complexity was making it harder and harder to stick to it. Then Java came along and taught us all to K.I.S.S. again. I am convinced that two reasons for the sky-rocketing popularity of Java were that it provided consistent APIs and documentation for the core libraries. It made writing and understanding somebody else’s code that much easier. Javadoc, the tool that extracts API documentation from comments in the code itself, was a game changer.
So, thanks to Java, software development got a tad simpler again. For a short while…
Fast forward two decades and today things are again exponentially more complicated. Now we have to deal with application servers, containers, a whole range of mobile devices, Continuous Integration, Continuous Deployment, Identity Providers, Machine Learning, micro-services, package repositories… The list seems endless. Just looking at technology requirements in job postings makes your head spin.
Things are so complicated nowadays that most developers spend their days in their favorite search engine looking up how to accomplish a particular task within the application framework(s) they are currently using. They usually end up on sites like StackOverflow where they tend to copy-paste the answer without fully understanding it.
Quite often this includes pulling yet another package from Maven or NPM which, at best will increase the size and dependency tree of your app, and at worst introduce severe security holes (Hello Log4J!). It is good practice to avoid re-inventing the wheel, but sometimes you end up pulling an 18-wheeler truck into your dependency tree when you only need the wheel. Do not think for a minute that I am exaggerating, I have seen this more often than I care to remember. And so we end up here:
If that was not bad enough, more frequently than you would think the answers you find on these sites will be incorrect, at least for your actual use case.
Recent studies have found that an alarming percentage of highly rated answers to security related problems were, in fact, lowering the security (for instance by accepting any certificates instead of the ones you should)
- Stack Overflow Considered Harmful?
- Secure Coding Practices in Java: Challenges and Vulnerabilities
- Top-ranked programming Web tutorials introduce vulnerabilities into software
The end result is that software quality and reliability has been going down like a lead balloon and we see a constant stream of news about increasingly severe outages and security breaches.
So how can we actually achieve simpler, more disaster-resistant systems?
A team culture of quality
First and foremost we should make sure all developers in our team understand and embrace the K.I.S.S. principle. That they value clean, consistent, well-documented APIs and that they think twice, or three times, before adding yet another external dependency to a project.
We should put in place processes and tools to help with the quality of your software. This includes coding guidelines, static analyzers, code reviews, continuous integrations, etc. Then we should evaluate their effectiveness on a regular basis and adapt them when necessary.
The shortening of the development cycle, in particular with Agile methodology, is putting so much time pressure on developers that cutting corners is now more the rule than the exception. So we should make sure that goals and deadlines are realistic, that quality is rewarded a lot more than speed.
Of course some of the reasons for that complexity are linked to the fact that what is demanded of software is of a totally different scale. After all a racing bike is inherently more complex to build than a skateboard, and a car is orders of magnitude more complex than a racing bike. While we can’t completely avoid intrinsic complexity, we can mitigate it by making sure we don’t add to it by applying the separation of concerns at every stage of the development cycle, in particular when creating the specifications.
Visual programming reduces complexity
At Olympe we are convinced that low-code/no-code platforms also have an important role to play in reducing that complexity. ‘Code as data’, as we like to call it, unlocks visual programming which is a higher level of abstraction and makes it simpler, especially for non-programmers, to understand the mechanics of a given application.
Naming convention and argument order don’t matter as much, plus any brick of code can be clicked to view its documentation.
But because the internal representation is in a graph database instead of a file of byte-code or native code, it is suddenly incredibly easy to add extra layers of information (fondly named meta-data) like documentation, permission, etc. It also makes it a lot easier to manage dependencies and analyze usage. It’s as simple as querying the database.
Finally because with Olympe all data can be part of the data-cloud (our distributed, automatically synchronized database), any changes to the code can be automatically applied everywhere, even in currently running applications, quasi-instantly. This can simplify deployment to a simple ‘push button’ action. Or, if you’d rather be a bit more cautious about deployment, it will, at the very least, drastically shorten and simplify the ‘implement-review-test’ cycles.
Today, a number of best practices and tools like Olympe exist out there to help ensure IT teams build robust and secure software. Key to success will be shifting the mindset of your team to K.I.S.S. software complexity goodbye.