Applications may make up only one layer of the software stack, but they are arguably the most critical – and, in some respects, most difficult – layer to secure. Other layers, like the infrastructure that hosts applications, tend to have a smaller attack surface and to be more consistent in terms of what they include and how they are configured.
In contrast, most applications are exposed to the Internet, which means they face a continuous risk of attack. In addition, because applications can use a multitude of different architectures and may be written in a variety of programming languages, it’s more difficult to devise security protections tailored to each application than it is to secure other layers of the stack.
What’s more, application security challenges become even more complex when apps move to the cloud and integrate with various cloud services to manage traffic, store data, enforce access control settings and so on. The complexity of the cloud means that there are even more variables for security teams to think about, and more risks to address, when they plan a cloud application security strategy.
This article reviews all of the key challenges related to securing on-premises applications and cloud-based applications. It explains the main security risks that applications face, as well as the best practices that security, DevOps and IT teams should follow to minimize the risk that the application layer will allow attackers to exfiltrate data, execute malicious code or disrupt critical services.
What is application security?
Application security in DevOps is the process of protecting applications against attack and abuse. As noted above, applications constitute a unique part of the hosting stack. As a result, applications face particular security risks, and they require application-centric security tools.
To understand how application security differs from other types of security, consider how a security team would enforce access controls for a server that hosts an application, as opposed to the application itself. To secure the host server, the team could rely on access control tooling built into the server’s operating system. On a Linux server, for example, it could use the chmod command to define which users can perform which actions on the server.
Restricting access to an application, however, is not as straightforward because there is much more variation surrounding how users access the application. The application might use internal logic to authenticate users and define which access privileges each one should have. Or, it could use a distributed authentication framework, such as OAuth, to manage access rights externally.
On top of this, access control rules within the CI/CD toolchain that is used to build the application must be defined properly in order to secure the app. Excessive privileges for the app’s GitHub repositories or CI tools, for example, could allow malicious users to modify the way the application works by injecting malicious code into the delivery chain.
This example, by the way, involves application access controls, which are only one of numerous considerations that security teams must address to protect applications. They would also need to ensure that the app manages data securely, resists buffer overflow attacks, is free from vulnerabilities and so on. (We’ll discuss the main types of application security risks in detail below.)
The bottom line is that, when it comes to securing applications, there are a large number of variables at play and a wide array of challenges that security teams need to conquer. Application security tools and practices are designed to address these specific needs, as opposed to security considerations that affect other layers of the hosting stack.
Conventional application security vs. cloud application security
Application security challenges grow even wider in scope and complexity for applications that are hosted in the cloud, as opposed to “conventional” applications that run in an on-prem environment.
Key differences between conventional apps and cloud apps that impact security include:
- Less control: In the cloud, IT and security teams typically have less control over the environment that hosts applications. They can’t access the operating system logs of the underlying physical servers, for instance, and they may have limited ability to define network-level access controls. This means that cloud applications can face even more security risks, and that protections implemented within the infrastructure layer of the stack are not as effective.
- Vendor-specific security tooling: Public cloud providers offer tools and frameworks like Identity and Access Management (IAM) services to help protect applications. However, each cloud’s tools work a little differently, which makes it harder to define consistent and effective policies that work across clouds. In addition, the extent to which applications can benefit from cloud-level security tooling depends on how the applications are designed and how tightly they integrate with the cloud environment.
- Distributed environments: Although not all cloud-based apps have to use a distributed hosting architecture – meaning one in which multiple application instances are spread across a cluster of host servers – many do in order to take full advantage of the scalability and flexibility of the cloud. As a result, there are more application instances to secure and monitor and a higher risk of potential breaches.
- Network exposure: Cloud applications are almost always exposed to the Internet, which means they are constantly at risk of network-borne threats. Conventional applications are easier to secure using firewalls, private networks or even “air-gapping” (which is the process of separating applications from the network entirely).
Key types of application security risks
No matter which type of application you deploy and whether it runs on-prem or in the cloud, there are several major types of security risks that it may face.
Code injection attacks
If attackers breach your application’s CI/CD pipeline, they can potentially inject malicious source code into the app’s codebase (which is what happened, for example, in the Codecov breach of 2021). If you don’t catch the malicious code before you build and deploy the next version of your app, it will end up operating in your runtime environment.
A cross-site scripting attack occurs when attackers find a way to inject malicious scripts into applications at runtime. Web apps are the most common type of application targeted by cross-site scripting, although any type of application could potentially be breached in this way. This type of attack is most often enabled due to lack of proper input validation, which attackers exploit in order to “trick” the application into running scripts that they inject into it.
Applications typically rely on a variety of configurations to define how they behave. Developers can set some configuration rules within source code, while others are defined as runtime variables. Configuration options in the application host environment – such as which access-control settings are defined within the app’s host server or cloud – could also impact how the application runs.
Misconfigurations at any level within the application or its host environment could lead to security breaches. For example, developers might create a runtime variable that gives all application users admin-level privileges so that they can test the application more easily pre-deployment. If they mistakenly leave the runtime variable set in the excessively privileged mode when the application is deployed into production, attackers could abuse it to escalate their privileges.
Source code vulnerabilities
A variety of coding mistakes and oversights can enter application source code. Developers might fail to write code that validates inputs properly, for example, which would give attackers an opportunity to exfiltrate sensitive data by injecting malicious commands into the application. Or, poor memory management by the application may allow a buffer overflow attack, in which attackers essentially use a compromised application to overwrite system memory and execute malicious code.
It’s common for developers to define dependencies for applications. Dependencies are external modules, libraries or other resources that an application needs to run. If the dependencies contain vulnerabilities, they could be exploited by attackers to take control of the application or to access sensitive data that the application controls.
Best practices for application and cloud application security
Because application and cloud application security risks come in so many forms, businesses must deploy an array of defenses to protect against them.
Secure the software delivery pipeline
As noted above, insecure configurations or tools within the software delivery pipeline can create backdoors that attackers exploit. That’s why it’s critical to secure all of the tools and resources that teams rely on to write, test and deploy applications, in addition to the applications themselves.
Deploy multiple application security tools
There are several types of application security testing and validation tools:
- Source Composition Analysis (SCA): SCA tools scan source code to detect vulnerable components and dependencies.
- Static Application Security Testing (SAST): SAST tools evaluate source code to find security oversights, such as lack of proper input validation.
- Dynamic Application Security Testing (DAST): DAST allows teams to run tests against live applications to discover weak points that attackers could exploit.
- Cloud Security Posture Management (CSPM): CSPM tools aren’t application security solutions per se because they validate the configurations of cloud services that host applications, rather than the applications themselves. Still, CSPM can detect configuration oversights, such as weak IAM settings, that could lead to application breaches.
By leveraging all of these tools, teams maximize their chances of detecting every type of application security risk that may exist within application source code, binaries and runtime environments.
Avoid unnecessary application components
The simpler your application, the lower the risk of attack. For that reason, it’s a best practice to avoid unnecessary dependencies, extensions or other components that unnecessarily increase the breadth of the application attack surface.
Since insecure dependencies are a prime vector for application security breaches, it’s critical to use an application security scanning tool to know which dependencies your application has, as well as what the version of each dependency is. Versioning information is critical because in many cases, only specific versions of a dependency are subject to known security risks.
Harden the operating system
Some operating systems offer “hardening” tools – such as SELinux and AppArmor– designed to reduce the risk of application security breaches. These frameworks don’t remediate underlying security risks within applications, but they can make the risks harder to exploit by, for example, preventing compromised applications from overwriting system memory as part of a buffer overflow attack.
Deploying hardening tools wherever possible is a best practice for securing applications. Note, however, that in the case of cloud applications, you may not always have the level of control over the hosting environment that is necessary to install a framework like SELinux or AppArmor.