Improving Java Code Security
In this article, discover how to improve code quality and security with the tools SpotBugs/FindSecBugs and OWSAP Dependency Scan.
Join the DZone community and get the full member experience.
Join For FreeDevelopers always strive to create stable, performant, and scalable code. There are plenty of tools to help with that like unit, integration, and load tests.
Along with this aspect improving code security is equally important. Today, in the world of cloud and distributed environments, it is becoming more and more critical.
Code security is crucial in cloud and distributed environments due to the increased attack surface, shared responsibility models, and potential for data breaches. Inadequate security can lead to regulatory non-compliance, data exposure, and damage to an organization's reputation. With dynamic scaling and resource sharing, continuous monitoring and updates are essential to maintain a secure posture and protect sensitive data from unauthorized access and manipulation.
To ensure that we have properly disposed of all the security and vulnerability issues, we need some tools to analyze and capture them.
Luckily, there are two popular tools that can scan the code and report any security and outdated dependency issues.
1. Security Scan
For security scanning, there is a tool that scans all the code and applies multiple rulesets meant for different types of scanning. The library is called SpotBugs. To enable security scanning, an additional plugin called Find Security Bugs is needed.
To enable this tool, you just need to add them to your build configuration.
Gradle Configuration
apply plugin: "com.github.spotbugs"
classpath "com.github.spotbugs.snom:spotbugs-gradle-plugin:4.7.8"
spotbugs 'com.github.spotbugs:spotbugs:4.4.0'
spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.12.0'
spotbugs {
ignoreFailures = true
showStackTraces = false
reportsDir = file("$buildDir/spotbugs")
}
spotbugsMain {
reports {
html {
required = true
outputLocation = file("$buildDir/reports/spotbugs/main/spotbugsTest.html")
stylesheet = 'fancy-hist.xsl'
}
}
}
After putting this configuration, run the Gradle build. After a successful build, it will produce the report in the $buildDir/reports/spotbugs/main/spotbugsTest.html
path.
Using Test Drive Development
SpotBugs Find Security Bug support can be invoked and customized programmatically using JUnit test cases. This allows it to run against specific pieces of code. It also does not require plugin reload and full build.
You need to write a custom bug detector test case to analyze and report the logic to want to make sure does not contain any security vulnerabilities.
public class XmlDecoderDetectorTest extends BaseDetectorTest {
@Test
public void detectXmlDecoder() throws Exception {
//Locate test code
String[] files = {
getClassFilePath("<main-logic-file-path>")
};
//Run the analysis
EasyBugReporter reporter = spy(new EasyBugReporter());
analyze(files, reporter);
//Assertions
verify(reporter).doReportBug(
bugDefinition().bugType("XML_DECODER")
.inClass("<class-name>").inMethod("<method-name").atLine("<line-no>")
.build()
);
}
}
Also, configure the bug detector and messages in appropriate configuration files.
- Findbugs.xml
<Detector class="com.h3xstream.findsecbugs.XmlDecoderDetector" reports="XML_DECODER"/>
<BugPattern type="XML_DECODER" abbrev="XMLDEC" category="SECURITY"/>
- Messages.xml
<!-- XML decoder -->
<Detector class="com.h3xstream.findsecbugs.XmlDecoderDetector">
<Details>Identify the use of XMLDecoder (a dangerous XML serializer).</Details>
</Detector>
<BugPattern type="XML_DECODER">
<ShortDescription>XMLDecoder usage</ShortDescription>
<LongDescription>It is not safe to use an XMLDecoder to parse user-supplied data</LongDescription>
<Details><![CDATA[<p>
XMLDecoder should not be used to parse untrusted data. Deserializing user input can lead to arbitrary code execution.
This is possible because XMLDecoder supports arbitrary method invocation. This capability is intended to call setter methods,
but in practice, any method can be called.</p>]]>
</Details>
</BugPattern>
<BugCode abbrev="XMLDEC">XMLDecoder usage</BugCode>
To run this detector, we need to follow the specific DSL.
There are many possibilities to implement a detector.
OpcodeStackDetector
: Look for a specific method callConfiguredBasicInjectionDetector
: To implement an injection-like detectorDetector
: To analyze the complete class context
Example
A developer runs Find Security Bugs on their Java application and discovers a SQL injection vulnerability in a database query.
Action
The developer reviews the vulnerable code, applies proper input validation and parameterized queries to prevent SQL injection attacks, and retests the application to ensure the vulnerability is mitigated.
2. Dependency Scan
Most applications depend upon one library or another to perform certain tasks, like parsing, HTTP communication, database operations, etc. Separate maintainers maintain all of those libraries and have their different release cycles.
There is no easy way one could track security issues for all those libraries. To solve this, some central organizations maintain a database of security issues discovered with a particular version of a library. Those organizations then periodically publish bulletins and sometimes APIs so the world knows about those issues.
However, no one can check each library and its used version across all application components. To help with this, OWSAP provides an excellent tool that scans all your dependencies and matches them against centrally maintained vulnerability databases. Upon finding any such issue it reports the issue with details of its Maven coordinates such as group, artifact, and version details.
The tool is called OWASP Dependency Check and it validates the vulnerabilities against NVD data feeds.
To enable this, add the configuration below to your build configuration and run the dependencyCheckAnalyze
command.
apply plugin: 'org.owasp.dependencycheck'
classpath 'org.owasp:dependency-check-gradle:8.2.1'
On the successful run, it would produce the report on the path build/reports/dependency-check-report.html
.
Example
During a CI/CD pipeline, OWASP Dependency Scan identifies that the application is using an outdated and vulnerable version of a third-party library with known security issues.
Action
The development team updates the vulnerable library to the latest secure version or replaces it with a safer alternative. They then rerun the dependency scan to verify that the vulnerability has been addressed.
Conclusion
The utilization of security tools plays a critical role in enhancing code security within applications.
Find Security Bugs improves the development process, and developers can identify and address security issues early in the development lifecycle, reducing the likelihood of these vulnerabilities making their way into production.
OWASP Dependency Scan focuses on identifying vulnerabilities associated with third-party libraries and dependencies used in the application. By regularly scanning and updating dependencies, developers can mitigate the risks associated with using vulnerable or outdated libraries, thereby reducing the attack surface, and enhancing the overall security of the application.
Opinions expressed by DZone contributors are their own.
Comments