Skip to main content

Non-upgradable dependencies

Need

Explicitly declare and manage dependencies in the source code to ensure upgradability and avoid potential security vulnerabilities.

Context

  • Usage of Java for building robust and scalable applications
  • Usage of javax.servlet for building Java web applications
  • Usage of javax.servlet.http for handling HTTP requests and responses in Java web applications

Description

Non compliant code

import javax.servlet.*;
import javax.servlet.http.*;

public class MyServlet extends HttpServlet {
// This servlet uses the javax.servlet package without specifying a version
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Servlet code here...
}
}

In the above code, we are importing the javax.servlet package without specifying a version. This is a problem because different versions of a library can have different behaviors, and they can also have different vulnerabilities.

We are also not managing our dependencies in a centralized way, such as with a build tool like Maven or Gradle. Instead, we are just copying the javax.servlet library directly into our project repository. This makes it difficult to track which version of javax.servlet we're using, and it also makes it difficult to upgrade to a new version if a vulnerability is discovered.

This is a serious vulnerability because it means that we could be unknowingly using a version of javax.servlet that has known security vulnerabilities. It also means that if a vulnerability is discovered in the future, we may not be aware of it, and we may not be able to easily upgrade to a secure version.

To fix this vulnerability, we should manage our dependencies with a build tool like Maven or Gradle, and we should explicitly declare the version of javax.servlet that we're using. This will allow us to easily upgrade to a new version if a vulnerability is discovered, and it will also make it easier to track which version we're using.

Steps

  • Identify all the dependencies used in the code
  • Explicitly declare the dependencies in the project's build file (e.g., pom.xml for Maven or build.gradle for Gradle)
  • Specify the exact version of each dependency to be used
  • Regularly update the dependencies to the latest versions to ensure security patches and bug fixes are applied
  • Consider using a dependency management tool to automate the process of managing and updating dependencies

Compliant code

// MyServlet.java
import javax.servlet.*;
import javax.servlet.http.*;

public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Servlet code here...
}
}

The vulnerability in the original code was due to the use of dependencies without explicitly declaring their versions. This can lead to potential security risks as different versions of the same dependency may have different vulnerabilities.

To fix this, we have explicitly declared the version of the javax.servlet dependency in the pom.xml file. This is the build file used by Maven, which is a popular project management tool for Java.

The javax.servlet dependency is declared within the <dependencies> tag. The <groupId> and <artifactId> tags specify the dependency, and the <version> tag specifies the version to use. In this case, we are using version 4.0.1.

The <scope> tag is set to provided, which means that the dependency is provided by the runtime environment and does not need to be included in the project's build output.

By explicitly declaring the version of each dependency, we can ensure that we are using a known, secure version. It also makes it easier to update the dependencies to newer versions as they become available.

It's important to regularly update the dependencies to the latest versions to ensure that any security patches and bug fixes are applied. This can be done manually, or by using a dependency management tool to automate the process.

References