Committed to connecting the world

Some suggestions on how to write more safe and secure programs - Design

Design with security and safety in mind

Don't assume that you will be able to add security or safety to your software as an add-on after it is finished or - worse - released. These are not features of a program, but properties that emerge from the way the software product is designed and built. They are also influenced by the environment where the program runs, such as the operating system and the type of network. For many programs, porting them from one operating system to a different operating system requires a careful examination of security-related aspects. Moreover, your decisions on the cryptographic algorithms to use, their parameters, the length of the cryptographic keys, etc., should depend on the nature and value of the information that you want to protect and on the way this information is used.

Design for quality

It is a good idea to develop your application following a rigorous methodology for high-quality software. As an example, the Radio Technical Commission for Aeronautics (RTCA) DO-178B standard provides guidelines for the production of software to be used in airborne systems and describes many techniques and methods appropriate to ensure the integrity, reliability, and safety of such software. This standard is general enough to be useful in assessing the quality of many other kinds of applications.

Use formal methods and languages

Formal methods can be used at all stages of a software development project. Different methods and languages cover different aspects of a software system, from requirements definition to system specification, down to low-level design and implementation. The main benefit to using formal methods and languages is the ability to exploit tools to verify the correctness of the system description at each abstraction level. Moreover, each of the resulting descriptions can be manually reviewed and checked against earlier, higher-level descriptions to ensure consistency as details are progressively added. All this helps to eliminate ambiguities and limit the introduction of defects at each stage, and makes it easier to identify and remove any existing defects as early as possible.

Limit software complexity

Complexity is an enemy of security and safety, so it should be limited as much as possible. Given a set of requirements for an application, good design methodologies can help reduce the complexity of the software product.

Ensure that all the operations (both normal and exceptional) in your application are safe and secure

Your application should always behave in a secure and safe way, both when it is operating normally and when it is handling exceptional conditions. Unfortunately, certain systems become less safe or less secure when they are reacting to a failure. This should be avoided. Actually, a system that becomes insecure when handling exceptional conditions cannot be considered secure at all. An example of a well-known methodology for assessing the safety of systems is "Fault tree analysis". Fault tree analysis is a top-down approach to the identification of process hazards, aimed at systematically identifying and graphically displaying the many ways something can go wrong.

Use only well-known cryptographic algorithms

Whenever there is a need to implement confidentiality and integrity in your application, it is always better to use an established cryptographic algorithm than invent your own algorithm. No cryptographic algorithm can be mathematically proven to be resistant to all possible attacks (current and future), so the only way that an algorithm can be considered secure enough is by relying on the existing community of cryptography experts, who scrutinize algorithms and are often highly motivated to discover weaknesses in them.

Don't assume that you can increase security by keeping the source code of your algorithms hidden

Not providing source code can help protect your interests as a software vendor, but it is hardly effective in protecting any secrets that may be embedded in your program. Attackers are often very able at reverse-engineering machine code and reconstructing "hidden" algorithms. Sometimes this reverse-engineering is not even necessary. Certain cryptographic algorithms, used by well-known applications, have proved so naive that crypto-analysts were able to reproduce them just by observing the program's behavior. Hiding the source code of a poor cryptographic algorithm doesn't make it any more secure. Again, it is much better to rely on a well-known algorithm.

Don't rely on the users of your application to select the appropriate (more secure) security settings

Few people bother to read manuals or to play with the configuration. Common users are non-proactive and system administrators are often too busy to do these things. If the secure modes of your application (for example, encryption) are not set by default, most users will never be aware of their existence and will never enable them. The result is that your application will needlessly run in an insecure mode on most systems. So in general it is better to enable security by default and require positive action to disable it.

Verify exchanged digital certificates and involve the user as much as possible in this process

When using public key cryptography and receiving a certificate from a third party, make sure your program checks the certificate against your trusted certificate files and certificate revocation lists, and provide the user with the ability to view the third party's certificate. The program should be able to ascertain the identity of the third party automatically in most cases, otherwise it should display the third party's certificate to the user (with clear warnings and instructions) whenever appropriate.. You shouldn't simply rely on the user requesting the display of the certificates , as most users won't remember to do such a thing even if they are aware of the potential risks (for example, the web server they are talking to may not be what it says it is or what it looks like).

Limit the internal data redundancy and manage the existing redundancy

Document all the existing dependencies among the data managed by the application and include in your design specific operations that verify the consistency of these data.

[ Table of Contents ]