Vulnerable API usage: Is your Java code vulnerable?

One of the downsides of using external dependencies, is that they might have known vulnerabilities at any time, as we have seen in the case of Log4Shell, Spring4Shell and other examples. 

This means that, as developers, we have to keep track of which dependencies have known vulnerabilities and upgrade them if an unaffected version is available. Sometimes we might need to prioritize which dependencies to update when. This is where it comes in handy to know what the severity of the vulnerabilities is. And whether we are even using the vulnerable API of a vulnerable dependency. In IntelliJ IDEA, Package analysis, provided by the Package Checker plugin, and the Vulnerable API Usage inspection can do just that!

See which dependencies have known vulnerabilities

If the dependencies in your project have known vulnerabilities, IntelliJ IDEA will highlight them in the build file (`pom.xml` or `build.gradle`). When we hover over the highlighted dependency, we’ll see a list of known vulnerabilities with a link to more information, a severity score and a brief description. 

Vulnerable dependency

We can click the link for a CVE number to open detailed information about that particular CVE in the Mend Vulnerability Database.

But we don’t need to leave our IDE to get more information about these vulnerabilities. In the popup, click the link Show details… to open the Vulnerable Dependencies tab in the Problems tool window.

Vulnerable Dependencies

The Vulnerable Dependencies tab contains a list of dependencies with known vulnerabilities in our project and the severity of these vulnerabilities. Some dependencies bring in transitive dependencies with known vulnerabilities; we can expand these dependencies in the list to see the transitive dependencies, their known vulnerabilities and their severity.

When we select a dependency in the list, we can see more details about its vulnerabilities in the right hand side of the tab. We see the dependency, CVE number, severity score, and a summary of the vulnerability. If we still need more information, we can click the link Read more, to open the information about this vulnerability in the Mend Vulnerability Database..

Vulnerable Dependencies – Details

Dealing with vulnerabilities

To deal with the vulnerabilities, we can use ⌥⏎ (on macOS) or Alt+Enter (on Windows/Linux) to have IntelliJ IDEA show us suggested fixes. For a vulnerable dependency, we have the option to update the dependency to an unaffected version (if one is available), ignore the vulnerability or show the vulnerability information for that dependency. The last option will show a list of all the known vulnerabilities for that dependency. 

Suggested fixes

In most cases, we’ll want to upgrade the dependency instead. When we upgrade, we’ll also want to make sure that our project still builds and our tests still pass. 

In some cases you may want to ignore a library that has known vulnerabilities. To do so, select the option “Ignore vulnerable <library name>” from the context action menu. In the Ignore Vulnerable Package popup that opens, select the reason you want to ignore this vulnerability. If you select Other, you’ll have the option to add a description.

Ignore Vulnerable Package

You may not want to ignore them forever though. To access the list with ignored vulnerabilities, open the IDE settings (⌘, on macOS or Ctrl+Alt+S on Windows/Linux) and go to Editor | Inspections. Expand the Security node and click Vulnerable declared dependency

Vulnerable declared dependency

To make this easier to find, click the Filter Inspection button and select Show Only Modified Inspections. The list is located in the Options section in inspection details. Remove a dependency from the list of ignored dependencies, by selecting that dependency and clicking the remove button or using the shortcut. Once removed from this list, vulnerabilities in that dependency will no longer be ignored.

Show only modified inspections

Prioritizing updates

If our application has multiple dependencies with known vulnerabilities, you might need to prioritize which to update first. You can look at the severity of the vulnerabilities, but you might want to know whether your code is actually using the vulnerable part of a dependency.

If we are looking at code that calls the vulnerable API of a dependency, this code will be highlighted in the editor. When we hover over the highlighted code, we see a list of vulnerabilities found in this API call. 

Vulnerabilities found in API call

We can use Show Intention Actions (⌥⏎ on macOS or Alt+Enter on Windows/Linux) and select Go to file with declared dependency from the menu. 

This will take us to the place in the build file where the dependency is declared, where we can use ⌥⏎ (on macOS) or Alt+Enter (on Windows/Linux) again to Update to unaffected version.

Go to file with declared dependency

Find out whether our code is using the Vulnerable API

But what if you’re not working on the exact file that uses the vulnerable API? How can you find out whether your code is using a vulnerable API anywhere in your project? 

We can run the Vulnerable API usage inspection manually to get a report about all vulnerable APIs usages in our project. To run an inspection by name, we can go to Code | Analyze Code | Run Inspection by Name in the main menu, use Search Everywhere (⇧⇧ on macOS or Shift+Shift on Windows/Linux) to look for “Run inspection by Name”, or use the shortcut ⌘⌥⇧I (on macOS) or Ctrl+Alt+Shift+I (on Windows/Linux). 

Run Inspection by Name

In the Enter inspection name popup that opens, type the name of the inspection you want to run: “Vulnerable API usage”. 

Enter inspection name

Next, select the scope you want to run this inspection on. You could run the inspection on a file or custom scope, or use the File mask(s) option to narrow down the number of files that will be inspected. In some cases you might only want to look at a part of your application. In other cases, you’ll want to run the inspection on the whole project.

Scope

The results of the inspection will open in a tab in the Problems tool window. 

Inspection results

The results will be shown on the left. Click one of the results to open a preview of that result on the right. This gives you the option to Go to file with declared dependency, which will navigate to the place in the build file where the relevant dependency is declared, and we can upgrade the dependency to the unaffected version from there. Alternatively, double-click the result to navigate to the affected code in the editor, to see exactly where and how the vulnerable API is used. 

Vulnerable API Usage

Supressing inspections

Notice that it is also possible to Suppress the inspection. We can suppress the inspection either for the statement or the class, or suppress all inspections for the class. 

Suppress

When you suppress an inspection, IntelliJ IDEA adds a new element before the selected symbol. When we select suppress for class, IntelliJ IDEA adds the `@SuppressWarnings` annotation. For statements, the `//noinspection` comment is added.

When an inspection is suppressed, the problem found by this inspection is no longer highlighted. To re-enable a suppressed inspection, delete the annotation or comment that the IDE has added before the selected symbol.

Suppressed vulnerability

Upgrade dependency

Since we’re actually using the vulnerable API for this dependency in this example, we’ll definitely want to upgrade it! We can go to the file with the declared dependency, and use Intention actions (⌥⏎ on macOS or Alt+Enter on Windows/Linux) to upgrade to the unaffected version. If needed, Load Maven Changes (⌘⇧I on macOS or Ctrl+Shift+O in Windows/Linux) to import the updated dependency.

Conclusion

When we have resolved the vulnerable API usage, when we run the Vulnerable API inspection again, we will get the result: “Code inspection did not find anything to report.”

Knowing whether our code uses a vulnerable API can help us developers better prioritize which dependencies to update.