Securing Software
We employ the Defense in Depth (DiD) approach. This means defenses are implemented, over different layers of the software and at all phases of the product development, to eliminate single points of failure.
Software Design Phase
Software design starts with threat-modeling. Early on, security flaw analyses are run to spot security risks in the software architecture to avoid expensive re-designs later. At the system level design phase we concentrate on high-level mitigations to generic threats, such as anti-tampering features. And at the component level, our focus is on input validation practices.
- Thread modeling relies on going through important checklists that can be used at all abstraction levels CIA (Confidentiality, Integrity, and Availability)
- STRIDE (Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, and Elevation of srivilege)
- DREAD (Damage, Reproducibility, Exploitability, Affected users and Discoverability)
We also rely on Taint analysis, which marks untrusted or sensitive data and tracks its propagation and respective derivatives within the system. The usefulness of Taint is two-fold: it ensures that untrusted data do not cause malicious actions. It also guards against sensitive data not getting leaked outside of the system and making sure such data is erased when not needed.
We make sure that the security foundations are solid and neither the system nor its components are open to vulnerabilities when going forward in the software development process.
Software Implementation Phase
In the implementation phase, a hierarchical structure is applied to create secure code. At the top level of the structure, input validation is applied through whitelisting. This means that access is granted only to specifically identified entities rather than going by the principle of least privilege, which is used in blacklisting.
At lower levels, where abstraction level decreases, more detailed guidance is defined from client-server architecture considerations (e.g. communication security, authentication, and access control) down to standard coding practices (e.g. Java and C language-specific). If the system under development includes 3rd party open source software, we use open source vulnerability databases, such as CVE, and hold rigorous reviews to check against any back-doors. Legacy source codebase security is kept up to date and use-automated tools for static code analysis to help identify invalid pointer references, uninitialized variables, buffer overruns as well as other security flaws.
Software Testing Phase
The software implementation phase includes many security self-assessment methods. Primarily attention is given to the scope of the software component. Also, manual integration testing is needed to take into account interactions between the different software components – to check the networking and access control of shared resources.
Coverage analysis tools ensure that the entire source codebase gets tested. Fuzz testing goes through modified versions of valid inputs to the tested interface and finds conditions as invalid input handling, memory leak, or overload scenarios. Coverage analysis is essential for enabling efficient fuzzing because it enables the selection of a comprehensive and non-overlapping set of valid inputs that will be modified during fuzz testing.
Software Releasing and Maintenance Phase
From the security viewpoint, the software is ready for release when all its security issues are tackled. From the release on, maintenance takes the stage and protecting the software from unwanted changes is essential until the end of the software lifecycle. Secure building, integrity protection, secure signing, and rollback prevention are the main measures to be taken. All of these protections are included also in the swift over-the-air (OTA) updates, which can be run to patch e.g. third-party software vulnerabilities.