Better Safe Than Sorry
As we engineer software products, we must be aware that it is used in unforeseen ways. Some ways sprout from the creativity of the user, some relate to the user’s ignorance and inexperience. A third unforeseen way is related to mischief and malice. This third group of ways of how our product will be used might be unforeseen but must be anticipated. Security must be part of the requirements, design, and implementation to effectively be implemented. a key aspect that is instrumental to deliver a secure product is found in the way it is constructed, the build system. This article is the first of the second season and it will ensure that the application being developed in the series is as secure as practically possible at this phase of our product’s development.
From ThreeAxis to Arc-E-Tect
Before everything else a short house-keeping message: The repository containing all source code has been renamed from the ThreeAxis username to the Arc-E-Tect username. The source code for this and previous episodes can be retrieved from:
Public Repository in support of the Medium article series by Arc-E-Tect on the development of software. Public…
The story thus far…
The previous episode covered the topic of configuring our build environment to support the development of a serious application.
Until episode 5, which you can find using the link above, we covered simple, yet powerful, principles in software engineering. The emphasis has been on spending your time wisely and being an effective software engineer. By applying Test Driven Development (TDD) and Behavior Driven Development (BDD) practices, we limit the amount of effort exerted to what we know is required and not to what we think might be required.
The series also showed that by doing TDD and BDD quality is prone to be excellent. Code coverage is reaching 80% with ease, getting closer to the 100% mark than the minimal 80% mark. I also explained why code coverage is important and at the same time can be deceiving you and your perception of quality.
Think big, start small
The previous episode marked a new part of the story and with this episode we have reached the second season of the Software Engineering Done Right.
The reason for transitioning to the second season and not turning this into the 6th episode of season 1 is that the application is going to be taken to the web, or rather the internet. With this episode we will make sure that the Arc-E-Tect Phonebook application will be moving from a standalone and rather useless application to an application that is running somewhere on the internet. We will do this by developing an inherently secure API-only application.
We start, as usual, with ensuring that all important bits of developing the software will be automated so we do not forget about them. Or maybe I should say that we can forget about them because our tooling will handle these bits for us.
We will also adopt an API-only approach to our application. This is a variation to the API-first paradigm and in my opinion the correct approach when starting a new software product.
API-only refers to the fact that the information and functionality, that is, the features of our product, will only be accessible through an API. There will not be any other integrated interface. Because of our API-only approach, the user experience will not be shiny and glamorous.
As before, we will start with a small implementation of our application that is of high quality and will only provide the functionality that is defined as well as behaving the way we have in mind. The first iteration is intended to make sure that our development environment is ready for developing applications that have public endpoints. This means that our API can be accessed and consumed from the internet.
Security by design
Probably the most important aspect to keep in mind when developing an API-only application is security. A good practice when developing an API is to assume that the API is accessible from the public internet. Even when your intentions are to only expose the API from within your private network, this is a correct assumption. APIs are exposed on your network, typically through http and preferably https. This means that every actor, including a bad actor, that has access to your network also has access to your API. A compromised infrastructure therefore will expose your API to the public internet.
As we develop the Arc-E-Tect Phonebook application, we will make sure that security is our first concern, and we will not compromise it.
This bold statement does not mean that we will have to encrypt, hash, lockdown, firewall our application. What it means is that with every step we take we consider the risks and take measures to mitigate them. You will find me explaining the decisions I make to close gaps in our system or to ignore them.
This risk-based approach is going to pay off when we apply it from the start. It allows us to include security in our requirements and our design. That way it is sure to find its way into our code because we treat security as a behavioral aspect of our application.
A pre-emptive apology because the code in this episode will limit itself to, once again, our build environment. But I can already reveal that the second episode of this second season will have us coding the application.
When developing a product for a networked environment, such as our future Phonebook application, there is always the risk of bad actors. Malicious users, bots, and just blissful yet ignorant people will form the threats we need to defend the application against. Since the Arc-E-Tect Phonebook application is going to expose all information through an API, a RESTful API over http, and the information is going to be Person Identifiable Information (PII), we must ensure that it is secured.
OWASP.org is a standard location to turn to when it comes to securing web-based applications. OWASP stands for Open Web Application Security Project. It publishes periodically the ten most common threats faced by internet-based applications. The current OWAS Top 10 is published on the OWASP website which you can access through the link below. I can recommend going over the top 10 and be amazed, surprised, and aware.
OWASP Top Ten
The OWASP Top 10 is a standard awareness document for developers and web application security. It represents a broad…
The OWASP Top 10 and OWASP in general are well known and every internet exposed endpoint should be tested against any vulnerability that is listed in the Top 10. Because an API should be treated as if it is exposed to the public internet, we must ensure that it does not expose any of these vulnerabilities.
Fortunately, OWASP provides some links to tools and libraries that we can use to reduce the risk we expose ourselves to when developing an API.
Because we continuously weigh the risk against the effort required to mitigate and the reduction of the risk when mitigated, at this time it is sufficient to ensure that our application is not inherently vulnerable. In other words, make sure that the libraries and frameworks our application depends on do not expose any vulnerabilities.
We use the Gradle plugin ‘dependency-check’ which is maintained by Jeremy Long and referenced on the OWASP website.
The dependency-check gradle plugin allows projects to monitor dependent libraries for known, published vulnerabilities…
As with most of my standard plugins, I create a separate Gradle file for this plugin and apply that Gradle file in my build.gradle.
In my build.gradle I register a dependency on the plugin and activate it. And I apply the security.gradle file which configures all my security related plugins.
Note that the task is set to run after `build` and not depend on it. As the scan can take a significant amount of time, it disrupts the flow of development. I chose to run it on demand only.
A quick analysis of this file shows that I have the build fail when the plugin registers an error. Because the plugin is using a standard database with vulnerabilities, I keep most of the plugin’s default values. It is designed such that it is as secure as possible while still practical in use. It also means that it retrieves new vulnerability information periodically. The plugin also provides a task in Gradle that will refresh the database with known vulnerabilities on-demand.
In case you ask yourself why I disabled the yarn-analyzer: it is because I do not use yarn as a package manager. Enabling this analyzer would also scan for vulnerabilities introduced by using yarn. But I found that it made my build environment overly complex. The current version of the plugin requires an operational version of yarn installed when this analyzer is enabled. Making things more complex than necessary is never a good idea. That is why I opted for disabling the analyzer.
Whereas the OWASP dependency scanner ensures that you know which vulnerabilities are introduced by making the application dependent on third-party software, the Versions plugin developed by Ben Manes will scan your dependencies and reports whether there are newer versions available.
In the spirit of the Maven Versions Plugin, this plugin provides a task to determine which dependencies have updates…
While working with teams in various organizations, I found that maintaining dependencies is typically lacking. Once a team has a working set of libraries they use, they tend to not update the libraries unless there is a bug they suffer from, which is fixed in a more recent release. Generally, dependency management is very reactive.
There is an immediate risk that is introduced by not actively maintaining dependencies: a library may expose a vulnerability that you are not aware of, making your application vulnerable. This introduces the risk that your organization is exposed to some serious threats from the bad people on the internet.
A reactive stance when it comes to updating dependencies ensures that as time goes by, your product and your organization will be more and more at risk. On the one hand, because your dependencies may have vulnerabilities that are addressed in later releases than the one you use. And on the other hand, you may face a major undertaking when you need to upgrade because gap between the most recent available release and the currently installed release is just too wide. Sometimes replacing with a different product is a more viable and just as scary option.
The versions plugin is an excellent addition to your build script to address this problem. It will scan your dependencies and verifies that you are using the most recent version of each dependency. If not, it will tell you directly what version you are on and what the most recent version is. In the code snippet you see that I configured the plugin to only look for released versions and ignore milestone releases.
I tend to update to the latest versions all the time. When the plugin reports the existence of a newer version of a dependency, I update the dependency_version.properties file accordingly, do a full build and unless that build fails, adopt the newer version of the dependency.
I am comfortable doing so, because I know that my tests (TDD and BDD) will ensure that the application still behaves as desired. There is no difference between changing my own code and changing a dependency.
The plugin will also tell you whether there is a new release of Gradle. Since I am only interested in release versions of Gradle and not intermediate versions, I configure the plugin to only report on releases and ignore milestone versions.
Source code quality
In the previous episode, the season finale so to speak, I introduced the Sonarlint plugin for Gradle. The plugin will scan your source code for vulnerabilities. I like the plugin approach because it means I can run the same checks locally attended as well as remotely on the CI (Continuous Integration) server, unattended. Unattended implies that the scan can run without human supervision or interaction.
With the OWASP scanner and the dependency updates, I know that my third-party dependencies now are covered. Which leaves my own code and coding style as the final parts of the static analysis to ensure that I do not introduce any holes in my defenses against bad actors.
I think that Sonarlint finds a lot of coding style issues. Uninitialized variables, initialized variables, inefficient code constructs etc. To a degree this is subjective, but the explanations given as to why the tool complains, are good enough to change my code.
At the same time, static source code analysis will also scan for possible information leaks in your application. Leaks that disclose how your application has been developed and therefore provide clues as to what vulnerabilities might exist in the code. I also find myself getting better at developing defensively. Since I started using Lombok, I observed that the number of findings by Sonarlint has gone down significantly. This of course has to do with the fact that once the boilerplate code generated by Lombok is passing the linting steps, Lombok will consistently generate solid code.
Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java. Never…
This is where this post ends. I can imagine that it has been a bit disappointing because there was not a lot of engineering in it. The code presented is not much more than some build script snippets. Compared to the last episode of season one, it is only different in that it introduced some new plugins that I use.
Although the amount of software engineering in this post is low, it is the right way to do software engineering. In my experience, security is one of the more complex aspects of software development. At the same time, it is one of the more important aspects of products that are to be exposed online. If not anything else, it is therefore a good practice to ensure that from day one your software engineering efforts include security, effortlessly. This means that we make it part of our automated process so it can be applied continuously and consistently, without effort.
With that thought, I promise that in the next episode I will introduce the first APIs based around REST principles and deliver an application that is secure enough to be accessible from the network.
Full sources to this first episode of season two can be found here:
Public Repository in support of the Medium article series by Arc-E-Tect on the development of software. This branch is…
A friendly link to the very first episode in this series can be found here:
The text very explicitly communicates my own personal views, experiences and practices. Any similarities with the views, experiences and practices of any of my previous or current clients, customers or employers are strictly coincidental. This post is therefore my own, and I am the sole author of it and am the sole copyright holder of it.
Special thanks to my lovely wife Olcay, as well as my friend Sytse who took the time and made the effort to review my article. I am confident that the article’s quality was significantly improved by their feedback.