The Secure Developer Quality
Archimedes, Galileo, Kepler and Newton. Just a few great minds of human advancements. There’s a keen and distinguished characteristics of these giant leapers which all of the developers should try to learn and apply what they do in order to produce rock solid secure applications.
What makes these scientists/philosophers and alike so successful to be noted as the best? While they were obviously smart people, what’s by far the most important quality is in fact their ability of asking the right questions. They were excellent questioners.
What great scientists do best is to see the anomalies of contemporary understanding of things and find another model to explain them better. This is how scientific revolutions happen [1].
Asking questions is the basis of critical thinking, which leads us reveal valid problems otherwise perhaps hidden. Moreover asking questions make the problem at hand clearer, understandable and easier to attack.
I’m sure you experienced a certain phenomenon in which the solution of a sticky problem bugging you for a long time suddenly appears crystal clear in your mind when you are in the middle of explaining the problem to others for a second opinion. This is because detailed description helps us to lay the problem better, which is the foundation of solving it. And asking reflexive questions is a great way of starting a dialog with yourself. It gets things rolling.
Secure Coding & Reflexive Questions
If you did any kind of a peer programming coding session in the past, I’m sure you realized that it’s one of the best ways of producing rock solid flows covering more edge cases than one might handle by him or herself.
One steering and the other actively watching, the effectiveness of pair programming is allowing a second eye to analyze the code/logic written. In the absence of a second programmer, the best way to mimic the situation is to ask questions ourselves, hence the reflexive questioning.
There are, as of now, 419 somewhat distinct software weaknesses published on Common Weakness Enumeration (CWE) project. That is a lot of weaknesses. It’s nearly impossible to know each and every one of them for a developer, or even for a software security expert. So, there must be other ways of ensuring the security of the code written. This is why we have automatic SAST/DAST tools and they play an important role in SDLCs.
A more early and involving technique is educating the developers on the key areas and arousing the falsification daemon inside them. :) What is a falsification daemon I hear you say.
Falsification Daemon
Most of the vulnerabilities exist in the code stem from the lack of critical thinking. The blame is of course on us, the developers. We should not be naïve while coding. Instead we have to be suspicious of what we accept and what we do when coding. It’s a little extreme, however, we should code as if hackers are watching from our shoulders. This is called Falsification Bias and I believe this has to be a 101 for software security.
Here’s an extremely simple code to illustrate the point.
Receipt receipt = ReceiptService.Get(id);
return receipt;
Assume this block resides inside an API endpoint method. The variable id comes from an end-user and the ReceiptService.Get method gets the details of the target receipt and returns it back the caller user using the id as the direct reference.
Without any falsification daemon running in the background of our brain, we may be introducing a critical security bug here. And the bug is a malicious/curious caller sending us random ids and receive other users receipts.
With a falsification daemon running, on the other hand, a developer will surely go through this dialog with him/herself while coding this block;
A short dialog between Jack the developer and his suspicious consciousness;Susp. Consciousness - Where does this parameter id come from?
Jack - From the user...Susp. Consciousness - Do we trust the user? Is he a privileged user?
Jack - No and no...Susp. Consciousness - Can he, then, access others receipts?
Jack - Yes, so let's prevent.
A flash of seconds and we will be our on way to fix the problem without committing anything to any repository. Security shifted the leftest. :)
Example Questions To Get You Started
As there are a lot of weaknesses, there are also a lot of questions to be asked. So, here’s a list of important ones to get you going while coding;
Who can call this endpoint I open to the world?
The above is a simple but unbelievably important question ensuring tight authorization and authentication around our software.
Can user access any assets he does not own using this parameter?
This is again seemingly stupid and basic question, however, it prevents a weakness called IDOR.
Have I applied whitelist validation, as opposed to blacklist validation, to this parameter?
Once the answer to this question is correct, and I mean correct, then you have a pretty secure application. It’s easy to ask this question, however, not that easy to implement right. Make sure you know the different types of validations one can employ before hand and read this blog post.
Am I mixing code and untrusted data without any validation in this piece of code?
This is a bit technical, however, be aware that any string concatenation operation of an input coming from an untrusted source, such as user, B2B API call responses, file contents or even database rows is dangerous. That untrusted data should go though a set of validation first, period.
Are my libraries up-to-date and have I read their security pages?
Just take a look at CVE numbers each year and total to understand the importance of this question.
Do this API method I am calling or arguments I am using have secure versions or any security side effects?
We are constantly using someone else’s code during development. 3rd party libraries, APIs, etc. The question above prevents us making insecure assumptions when calling them.
Do I really need to get this parameter from the user?
An excellent one. When there are other ways, and if it’s possible we should never get an input from an untrusted source. To put this differently, we should only accept an input when it’s absolutely necessary.
Does this security related check that I am writing run on the client or the server side?
Most of the time we know where the code we write will run. But still there are some technologies you may be unsure. The basic understanding is that secure checks done at the client side is always open to by-passes.
Again the list is not complete. However, these questions should be alive at the back of our brain all the time when coding. It is a hard process, but once we get the hang of it, they will stay there no matter what. Even when we do not want to give an answer or do nothing about it. ;)
The Need to Provoke the Daemon
It’s good to know that when we start to ask questions, then we can trigger a process to prevent security bugs from happening. However, we have to have a motivation for developers to start asking. Let me give you an example.
Assume you have a developer group where you show them the following code;
protected void doPost(HttpServletRequest ... ){ Part filePart = request.getPart("file"); String fileName = UploadedPath + getFilename(filePart); InputStream fileContent = filePart.getInputStream(); OutputStream out = new FileOutputStream(fileName);
int read = 0; byte[] bytes = new byte[1024]; while ((read = fileContent.read(bytes)) != -1) out.write(bytes, 0, read); …}
This is a simple file upload code in Java. As is, this method is open to a security bug called, Insecure File Upload. And there are multiple precautions that should be taken in order to prevent a hacker to abuse this method.
The funny thing is that, you don’t have to really list the precautions one by one for a developer to know them. All you have to do is to motivate them against the risk of being hacked by using this method. You don’t even have to point to or explain the Insecure File Upload security bug. Just tell them, “there are hackers somehow abusing this method. So, what would you do to prevent them?” and you will see that they will start to list most of the items used to avoid such a bug.
Of course, this doesn’t mean that they won’t find any bad/insecure solutions but that can be prevented easily with a short “how to do a secure validation” session.
[1] To that end, I would recommend two good books; one of them is “The structure of scientific revolutions” by Thomas S. Kuhn and the other is “The sleepwalkers” by Arthur Koestler.