Some Advice For Software Developers Who Really Care About Secure Code
With the development of the Internet, especially the advances in the mobile Internet, digital services are more and more closely connected with our personal lives in areas such as banking, utility payments, entertainment and games, etc. where most have moved from offline to online. The new era of the ‘Internet of Things’ has truly arrived.
Because of ubiquitous computing, network security incidents are frequent, and occurrences of these incidents has grown exponentially. Software engineers need to pay more and more attention to security issues. Here, I’d like to share some of my learnings for developers who are new to cybersecurity.
First, what is security?
The most common question I’ve come across for software developers who have not been exposed to security is ‘how to write secure code or make a secure system’? In my mind, security is a very broad concept, and you can start with a general description: protected targets or objects are not destroyed, tampered with, leaked or exploited, and the whole system functions properly and keeps integrity intact. For us developers, the key questions of ” security ” are what is the object that needs to be protected and hence what is the protection requirement? Note that you can’t talk about security without a clear security requirement. For example, common security issues include whether the communication protocol is secure, whether the data stored is secure, whether the software operating environment is secure or is the code itself secure. So, before you want to write secure code or implement a secure system, you must ask yourself what is it that you want to protect? The different security requirements and the security protection methods that need to be deployed are also necessarily different. If you don’t know what you want, then you will not achieve your goal!
To further understand this definition of security, I believe, the next question must be how do I know if the security measures implemented are sufficiently secure? Security defenses and malicious attacks are an evolving game. Like antibiotics and viruses, defense and attack technologies are constantly evolving. As engineers, we know that there is no such thing as absolute security and the best we can do is to reduce the risk to very low levels according to security best practices within the industry.
Second, how do I get security training?
The sixth century Chinese general and philosopher, Sun Tzu says “know your enemies and know yourself and you will not be imperiled in a hundred battles”, so keeping yourself up to date by reading books and articles about how hackers attack and how to defend is essential for developers. The content you read may include some basic knowledge in fundamental computer system software and not just code in application layer. This knowledge is essential and necessary, for otherwise, you will only know “what” but not “why”! Understanding hacker attacks and defense techniques will invariably lead to a ‘foundation knowledge’ of computer systems, networks, computer architectures, compilation principles, virtual machines, and so on that gives you a holistic perspective on what the attacker is doing.
These foundation concepts in turn lets you understand the popular security methods used in the real world. Common Weakness Enumeration (CWE) lists a lot of common security flaws. You can start with the 25 most popular problems, which can help you avoid many security problems when coding. For a web application or system, I usually turn to the Open Web Application Security Project (OWASP) which has a database that should not be missed. OWASP contains common web problems and best practices. The OWASP Top 10 list published almost every year consists of the 10 most seen application vulnerabilities. For example, SQL injection, a common high-risk problem with decades of history, is mentioned in both OWASP and CWE. Next, you can look at the better security practices in the industry. SEI CERT coding standards is a security coding standard that categories the common security problems in C, Java and other languages, to explains the security problems. Unsafe code samples and safe code samples can be found on their website. This specification is a good starting point to help you quickly understand security issues and practice security coding.
Third, what are the major categories of “safety” issues?
The many kinds of security problems are quite mind blowing. Do these security problems have common characteristics and traits? The answer is yes. I like to divide security issues into the following categories.
a) Untrusted input and output
If a system does not interact with an untrustworthy environment, the security threat of the system is relatively minor. Most systems, especially web systems, need to interact with untrustworthy environments. During interaction with the web interface, you need to pay attention to two issues: whether the input is legitimate and whether the output data contains sensitive information. Input data includes, but is not limited to, parameters entered by the user, incoming files, environment variables use, dependent runtime libraries or packages, etc. If the data input by the user is beyond the scope of program processing, it may cause unexpected results. For this ‘untrusted’ data, we can usually limit the range of inputs and accept only the inputs the system can properly process. One possible solution for website registration is to limit the set characters used. We can also sanitize the input strings of unsupported characters.
For output data, you need to care about whether the output contains sensitive information. Examples of sensitive information are program path, username, password, IP address, and so on. If the username and password of the server are leaked, all information on the server is at risk of leakage. This requires that we carefully check the program source code that deals with output before the program is released.
b) Program error
If the program itself is in error, it gives the attacker the opportunity to take advantage of it. Once the program triggers into executing the portion with error logic, the program may deviate from the normal running process, such as running the program provided by the attacker. For C/C++ language, common program errors include null pointer references, uninitialized variable, heap memory allocated by not freed, heap memory freed multiple times, array out of bound, out of scope use of stack memory, integer overflow, etc. This requires you to improve the quality of code writing and focus on minimizing program errors.
For the Java language, memory problems do not apply, but other issues occur like integer overflow, array out of bound, reference empty objects. There are also wrong uses of runtime library functions, type definition error in Java. Serialization and deserialization errors are problems specific to Java language.
c) Other error problems
You can classify other security problems into separate categories. These security issues include, but are not limited to, the following:
• Business logic error: read user information without authentication
• Communication protocols not secure: such as the use of weak encryption methods and hashing algorithms
• The library or package used is not secure: for example, the web server has security vulnerability
Fourth, recommendations on security safety practices
The issue of security and the practice of secure coding is not a classroom exercise. Only through diligent scrutiny and practices can safety be improved. Here are some of my suggestions that may help.
a) The first step to solving the problem is to admit the problem. Take on solving security issues at the design stage of software development adopting a ‘shift-left’ approach. Implement security measures and safeguards during development and testing cycles.
b) Find and leverage tools to help solve security problems. There are many tools available in the industry that can help us detect security issues at all stages software development and during program execution.
• Syntax error detection tools to avoid simple and embarrassing mistakes
• Static Application Security Testing (SAST) tools: during the SDLC, these tools can detect the security problems and can analyze whether there is a vulnerability in the library file which is a very effective way to detect potential security problems early on. The well known static detection tools are OCLint, Fortify, Coverity, Checkmarx, etc. Some rookies are also rising, including Xcalibyte.
• Dynamic Application Security Test (DAST) tool: these tools will try to detect security vulnerabilities during program execution. For example, you can use Wapiti, Panda and other tools.
• Penetration Testing tool: these tools simulate cyber-attacks against your computer system to expose and identify security issues. For example, there are Zed Attack Proxy, W3AF, Valgrind and other tools.
Security is not an isolated problem. It is a system problem and there are no silver bullets. There is no cure for all tools. The best you can do is to fully understand, simulate and forewarn the safety problems before they occur, and make effective precautions and safeguards. The more protection you provide, the narrower the attacker’s attack surface, the higher the cost of attack and the lower the probability that our system will be compromised. I like the Chinese proverb ‘a thousand miles journey begins with one single step’. It is time to start understanding and to take the security problems to heart. Take that first step now!