Don’t Let Legacy Tech Debt Sink Your Security Posture
Like waistlines after a large holiday meal, legacy programming code can become bloated with useless lines of code resulting in features that are unnecessarily long or slow, due to a large amount of memory and RAM. Useless code might be libraries that contain new code and repetitive code from older versions of software, or service binaries. Bloating is often caused by inadequacies in the way in which the code is written, the compiler used to compile the code, dead code, or even a programmer writing it.
Sometimes a programmer will write more lines of code than required for the application to work. Then you inherit it and are tasked with figuring it out and fixing it. This is known as technical debt, and it broadly encompasses decisions and shortcuts taken during the Software Development Lifecycle (SDLC). As the name implies, some of the consequences of technical debt are ones you hope to avoid: badly designed code, unplanned costs, delivery delays and product quality degradation, and in some cases vulnerabilities resulting in exploitability.
Why Technical Debt is Bad
In short, technical debt becomes a pain to deal with and a security risk. It should serve as a warning that the software development process was not ideal. Therefore, besides slowing down your apps and eating up computer memory, this inherited code introduces the potential for cyberattacks.
That’s because the additional code from legacy software bloat provides hackers with more entry points into a software program. It was one of the reasons the WannaCry ransomware outbreak in 2017 crippled a number of companies.
And be aware that even when it’s not used, bloated code can also create false alarms because security scanners cannot distinguish between code that exists and code that is in use.
This should motivate developers, DevOps and security teams to reduce technical debt. Think of removing bloated code like spring cleaning. Once it’s done, you feel lighter. Teams only have to test the code required to run an application and you’re not wasting testing cycles on unused code.
You’ll also free up memory, thus, improving the uploading process, performance time . This in turn, reduces the monitoring process, speeds testing cycles and improves product release velocity. Additionally, you will improve your security posture.
How to Reduce Technical Bloat
Start by reviewing the initial development strategy, identifying the weak points that required a development team to take on technical debt, and fill in the gaps. Often times you will find that the culprit is pressure to release products quickly (time to market).
Fixing the problem might require holding more frequent meetings with stakeholders and developers, establishing new code standards, commitment to product security, or creating an efficient technical debt tracking system.
Legacy code should be tested. This will help developers understand what it actually does as well as reveal any potential problem areas. They should also review the documentation of the original requirements. Don’t be tempted to rewrite the code—that can introduce new bugs or remove hidden functionality.
Adopting an agile approach may be the way to reframe the existing strategy. The first way to minimize technical debt is to use a sprint-by-sprint approach, which will allow a team to reduce technical debt gradually with every subsequent sprint.
Tools and Techniques to Reduce Tech Debt
To address a large amount of technical debt instantly, you may want to consider using a dedicated sprint instead of doing it step-by-step. Deciding which approach to take will depend on the type of technical debt, complexity, allocated budget, and time. Both a scrum master and product owner should be involved in figuring out the best strategy to implement.
In terms of tools, it is not easy to automatically detect bloated code in the infrastructure. A native scanner will need to analyze the parts of the code that are never loaded to memory and can be removed from the build entirely. That’s an impossible task with computation limits. But, smart methods exist, such as unreachable code detection (available in most modern compilers), unused import of external libraries, and tools that feature real-time detection on pieces of the code that are actually loaded.
This has the added value of informing which security concerns should be taken care of as soon as possible, and which can be postponed until you ultimately refactor the project.
Refactoring transforms poorly written legacy code and improves the internal quality of a product’s source code without altering its external behavior. Yet even though this is a helpful practice, it is frequently ignored during development because it doesn’t add new functionality or fixes bugs.
By refactoring (and then testing) in regularly-scheduled intervals, you will not only reduce existing technical debt but also make your code more maintainable, readable, better-functioning, and secure.
This will also minimize the potential attack surface and threat vectors. And remember, while you can’t control the quality of inherited legacy code, you can keep the new code clean by adhering to best practices.