Black Duck Security Scanning for Java Applications

Black Duck is a comprehensive security and license compliance solution that helps organizations identify and manage open source security vulnerabilities, license compliance issues, and operational risks in their software projects.


What is Black Duck?

Black Duck provides:

  • Open Source Detection: Automatically discovers open source components
  • Vulnerability Assessment: Identifies known security vulnerabilities
  • License Compliance: Analyzes license obligations and conflicts
  • Risk Management: Prioritizes and tracks remediation efforts
  • Policy Enforcement: Enforces organizational security policies

Black Duck Architecture

Source Code/Binaries → Black Duck Scanner → Black Duck Hub → Reports & Dashboards
↑                    ↑                    ↑                ↑
Application        Detection Engine     Central Database   Security Teams
Artifacts         Vulnerability DB     License DB         Development Teams

Getting Started with Black Duck

Installation and Setup

# Download Black Duck CLI (Detect)
curl -s https://detect.synopsys.com/detect.sh | bash
# Or use Docker image
docker pull blackducksoftware/blackduck-detect:latest
# Set environment variables
export BLACKDUCK_URL=https://your-blackduck-instance.com
export BLACKDUCK_API_TOKEN=your-api-token
export BLACKDUCK_TRUST_CERT=true

Black Duck Scanning Methods

Method 1: Basic Java Project Scan

# For Maven projects
java -jar synopsys-detect-8.0.0.jar \
--blackduck.url=$BLACKDUCK_URL \
--blackduck.api.token=$BLACKDUCK_API_TOKEN \
--detect.project.name="MyJavaApp" \
--detect.project.version="1.0.0" \
--detect.tools=DETECTOR \
--detect.maven.build.command="clean compile"
# For Gradle projects
java -jar synopsys-detect-8.0.0.jar \
--blackduck.url=$BLACKDUCK_URL \
--blackduck.api.token=$BLACKDUCK_API_TOKEN \
--detect.project.name="MyJavaApp" \
--detect.project.version="1.0.0" \
--detect.tools=DETECTOR \
--detect.gradle.build.command="build"

Method 2: Docker-based Scanning

# Scan using Docker container
docker run -it --rm \
-v $(pwd):/source \
-e BLACKDUCK_URL=$BLACKDUCK_URL \
-e BLACKDUCK_API_TOKEN=$BLACKDUCK_API_TOKEN \
blackducksoftware/blackduck-detect:latest \
--detect.project.name="MyJavaApp" \
--detect.project.version="1.0.0" \
--detect.source.path="/source"

Integration with Build Tools

Example 1: Maven Integration

<!-- pom.xml - Maven configuration -->
<project>
<build>
<plugins>
<!-- Black Duck Detect Maven Plugin -->
<plugin>
<groupId>com.synopsys.integration</groupId>
<artifactId>blackduck-maven-plugin</artifactId>
<version>2.0.0</version>
<configuration>
<blackduckUrl>https://your-blackduck-instance.com</blackduckUrl>
<blackduckApiToken>${blackduck.api.token}</blackduckApiToken>
<projectName>${project.name}</projectName>
<projectVersion>${project.version}</projectVersion>
<failOnPolicyViolation>true</failOnPolicyViolation>
<outputDirectory>${project.build.directory}/blackduck</outputDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>run</goal>
</goals>
<phase>verify</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

Example 2: Gradle Integration

// build.gradle - Gradle configuration
plugins {
id 'com.synopsys.integration.blackduck' version '2.0.0'
}
blackduck {
url = 'https://your-blackduck-instance.com'
apiToken = System.getenv('BLACKDUCK_API_TOKEN')
projectName = project.name
projectVersion = project.version
failOnPolicyViolation = true
outputDirectory = "${buildDir}/blackduck"
scan {
paths = ["${projectDir}"]
}
}

Advanced Scanning Configuration

Example 3: Comprehensive Detect Configuration

#!/bin/bash
# comprehensive-blackduck-scan.sh
java -jar synopsys-detect-8.0.0.jar \
--blackduck.url=$BLACKDUCK_URL \
--blackduck.api.token=$BLACKDUCK_API_TOKEN \
--blackduck.trust.cert=true \
# Project Information
--detect.project.name="my-java-application" \
--detect.project.version="1.0.0-$BUILD_NUMBER" \
--detect.project.tier="PRODUCTION" \
# Scanning Configuration
--detect.tools=DETECTOR,BINARY_SCAN \
--detect.detector.search.depth=10 \
--detect.excluded.directories="test,node_modules,.git" \
# Vulnerability Management
--detect.policy.check.fail.on.severities="BLOCKER,CRITICAL,HIGH" \
--detect.risk.check.fail.on.severities="HIGH" \
# Reporting
--detect.output.path="./blackduck-reports" \
--detect.report.format=JSON,HTML \
# Notifications
--detect.notification.email.addresses="[email protected]" \
--detect.notification.email.subject="Black Duck Scan Results" \
# Advanced Options
--detect.parallel.processors=4 \
--detect.timeout=600 \
--detect.cleanup=true

CI/CD Integration

Example 4: Jenkins Pipeline Integration

// Jenkinsfile
pipeline {
agent any
environment {
BLACKDUCK_URL = 'https://your-blackduck-instance.com'
BLACKDUCK_API_TOKEN = credentials('blackduck-api-token')
}
stages {
stage('Build') {
steps {
sh 'mvn clean compile -DskipTests'
}
}
stage('Black Duck Scan') {
steps {
script {
// Download Detect
sh 'curl -s https://detect.synopsys.com/detect.sh | bash'
// Run Black Duck Scan
sh """
java -jar synopsys-detect-*.jar \
--blackduck.url=${BLACKDUCK_URL} \
--blackduck.api.token=${BLACKDUCK_API_TOKEN} \
--detect.project.name="${env.JOB_NAME}" \
--detect.project.version="${env.BUILD_NUMBER}" \
--detect.policy.check.fail.on.severities="BLOCKER,CRITICAL" \
--detect.risk.check.fail.on.severities="HIGH" \
--detect.report.format=JSON,HTML
"""
}
}
post {
always {
// Archive reports
archiveArtifacts artifacts: 'blackduck-reports/*', allowEmptyArchive: true
// Publish HTML reports
publishHTML([
allowMissing: true,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'blackduck-reports',
reportFiles: 'report.html',
reportName: 'Black Duck Security Report'
])
}
}
}
stage('Security Gate') {
steps {
script {
// Check for policy violations
def scanResult = readJSON file: 'blackduck-reports/scan_result.json'
if (scanResult.policyViolations > 0) {
error "Black Duck policy violations detected: ${scanResult.policyViolations}"
}
}
}
}
}
}

Example 5: GitHub Actions Integration

# .github/workflows/blackduck-scan.yml
name: Black Duck Security Scan
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 0 * * 0'  # Weekly scan
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Build project
run: mvn clean compile -DskipTests
- name: Run Black Duck Scan
run: |
curl -s https://detect.synopsys.com/detect.sh | bash
java -jar synopsys-detect-*.jar \
--blackduck.url=${{ secrets.BLACKDUCK_URL }} \
--blackduck.api.token=${{ secrets.BLACKDUCK_API_TOKEN }} \
--detect.project.name="${{ github.event.repository.name }}" \
--detect.project.version="${{ github.sha }}" \
--detect.policy.check.fail.on.severities="BLOCKER,CRITICAL" \
--detect.report.format=JSON
- name: Upload Security Report
uses: actions/upload-artifact@v3
with:
name: blackduck-report
path: blackduck-reports/
- name: Check for Critical Vulnerabilities
run: |
if [ -f blackduck-reports/scan_result.json ]; then
VIOLATIONS=$(jq '.policyViolations' blackduck-reports/scan_result.json)
if [ "$VIOLATIONS" -gt 0 ]; then
echo "Critical vulnerabilities found: $VIOLATIONS"
exit 1
fi
fi

Custom Policy Configuration

Example 6: Black Duck Policy Rules

{
"name": "Java Security Policy",
"description": "Security policy for Java applications",
"overallConditions": {
"operator": "OR",
"expressions": [
{
"name": "Critical Vulnerabilities",
"conditionType": "VULNERABILITY",
"severityLevels": ["CRITICAL"],
"vulnerabilityCountThreshold": 0
},
{
"name": "High Risk Licenses",
"conditionType": "LICENSE",
"licenseRiskProfile": {
"highRiskCountThreshold": 0
}
}
]
},
"componentConditions": [
{
"name": "No Banned Components",
"conditionType": "COMPONENT",
"bannedComponents": [
"log4j:log4j:1.2.17",
"commons-collections:commons-collections:3.1"
]
},
{
"name": "Vulnerability Age",
"conditionType": "VULNERABILITY",
"vulnerabilityAgeThreshold": 90,
"severityLevels": ["HIGH", "CRITICAL"]
}
]
}

Remediation Workflow

Example 7: Automated Remediation Script

#!/bin/bash
# blackduck-remediation.sh
PROJECT_NAME="my-java-app"
PROJECT_VERSION="1.0.0"
BLACKDUCK_URL="https://your-blackduck-instance.com"
API_TOKEN=$BLACKDUCK_API_TOKEN
# Get vulnerability report
curl -X GET \
-H "Authorization: Bearer $API_TOKEN" \
"$BLACKDUCK_URL/api/projects?q=name:$PROJECT_NAME" > project_list.json
PROJECT_ID=$(jq -r '.items[0]._meta.href' project_list.json | sed 's|.*/||')
# Get components with vulnerabilities
curl -X GET \
-H "Authorization: Bearer $API_TOKEN" \
"$BLACKDUCK_URL/api/projects/$PROJECT_ID/versions/$PROJECT_VERSION/components" > components.json
# Process vulnerable components
jq -r '.items[] | select(.securityRiskProfile != null) | "\(.componentName):\(.componentVersionName) - \(.securityRiskProfile)"' components.json | while read component; do
echo "Processing: $component"
# Extract component details
COMPONENT_NAME=$(echo $component | cut -d':' -f1)
COMPONENT_VERSION=$(echo $component | cut -d':' -f2 | cut -d' ' -f1)
# Check for available upgrades
curl -X GET \
-H "Authorization: Bearer $API_TOKEN" \
"$BLACKDUCK_URL/api/components?q=name:$COMPONENT_NAME" > component_versions.json
LATEST_VERSION=$(jq -r '.items[0].versionName' component_versions.json)
if [ "$COMPONENT_VERSION" != "$LATEST_VERSION" ]; then
echo "Upgrade available: $COMPONENT_NAME from $COMPONENT_VERSION to $LATEST_VERSION"
# Auto-update in pom.xml (for Maven)
sed -i "s/<$COMPONENT_NAME.version>$COMPONENT_VERSION<\/$COMPONENT_NAME.version>/<$COMPONENT_NAME.version>$LATEST_VERSION<\/$COMPONENT_NAME.version>/" pom.xml
fi
done
# Generate remediation report
echo "Remediation actions completed. Please review and commit changes."

Reporting and Dashboards

Example 8: Custom Reporting Script

#!/usr/bin/env python3
# blackduck-report-generator.py
import requests
import json
import csv
from datetime import datetime
class BlackDuckReporter:
def __init__(self, base_url, token):
self.base_url = base_url
self.headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
def get_project_vulnerabilities(self, project_name, version_name):
# Get project ID
projects_url = f"{self.base_url}/api/projects"
response = requests.get(projects_url, headers=self.headers)
projects = response.json()
project_id = None
for project in projects['items']:
if project['name'] == project_name:
project_id = project['_meta']['href'].split('/')[-1]
break
if not project_id:
raise Exception(f"Project {project_name} not found")
# Get version ID
versions_url = f"{self.base_url}/api/projects/{project_id}/versions"
response = requests.get(versions_url, headers=self.headers)
versions = response.json()
version_id = None
for version in versions['items']:
if version['versionName'] == version_name:
version_id = version['_meta']['href'].split('/')[-1]
break
if not version_id:
raise Exception(f"Version {version_name} not found")
# Get vulnerability report
vuln_url = f"{self.base_url}/api/projects/{project_id}/versions/{version_id}/vulnerabilities"
response = requests.get(vuln_url, headers=self.headers)
return response.json()
def generate_csv_report(self, vulnerabilities, output_file):
with open(output_file, 'w', newline='') as csvfile:
fieldnames = ['Component', 'Version', 'Vulnerability', 'Severity', 'CVSS', 'Published', 'Description']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for vuln in vulnerabilities.get('items', []):
for affected_component in vuln.get('affectedComponents', []):
writer.writerow({
'Component': affected_component.get('componentName', ''),
'Version': affected_component.get('componentVersionName', ''),
'Vulnerability': vuln.get('vulnerabilityName', ''),
'Severity': vuln.get('severity', ''),
'CVSS': vuln.get('cvssScore', ''),
'Published': vuln.get('publishedDate', ''),
'Description': vuln.get('description', '')
})
# Usage
if __name__ == "__main__":
reporter = BlackDuckReporter(
base_url="https://your-blackduck-instance.com",
token="your-api-token"
)
vulnerabilities = reporter.get_project_vulnerabilities(
project_name="my-java-application",
version_name="1.0.0"
)
reporter.generate_csv_report(vulnerabilities, "security-report.csv")
print("Security report generated: security-report.csv")

Best Practices for Black Duck Scanning

1. Comprehensive Scanning Strategy

#!/bin/bash
# comprehensive-scan-strategy.sh
# 1. Pre-scan: Dependency check
echo "Running pre-scan dependency analysis..."
mvn dependency:tree > dependency-tree.txt
# 2. Main Black Duck scan
echo "Running Black Duck security scan..."
java -jar synopsys-detect-*.jar \
--blackduck.url=$BLACKDUCK_URL \
--blackduck.api.token=$BLACKDUCK_API_TOKEN \
--detect.project.name="$PROJECT_NAME" \
--detect.project.version="$VERSION" \
--detect.tools=DETECTOR,BINARY_SCAN,IMPACT_ANALYSIS \
--detect.policy.check.fail.on.severities="BLOCKER,CRITICAL" \
--detect.risk.check.fail.on.severities="HIGH" \
--detect.report.format=JSON,HTML,CSV
# 3. Post-scan: Generate remediation plan
echo "Generating remediation plan..."
python3 generate-remediation-plan.py blackduck-reports/scan_result.json

2. Security Gates in CI/CD

# Security gate configuration
security_gates:
vulnerability_severity:
blocker: 0
critical: 0
high: 5
medium: 20
low: 100
license_risk:
high: 0
medium: 3
low: 10
operational_risk:
high: 0
medium: 5
low: 15

Common Java Vulnerabilities Detected

Black Duck effectively identifies:

  1. Log4j Vulnerabilities (CVE-2021-44228, etc.)
  2. Apache Commons Vulnerabilities
  3. Spring Framework Security Issues
  4. Jackson Deserialization Vulnerabilities
  5. Tomcat Security Flaws
  6. Hibernate Security Issues
  7. JUnit Vulnerabilities
  8. SLF4J Security Problems

Conclusion

Black Duck provides comprehensive security scanning for Java applications:

Key Benefits:

  • Comprehensive Detection: Identifies all open source components
  • Vulnerability Intelligence: Leverages extensive vulnerability database
  • License Compliance: Manages open source license obligations
  • Risk Prioritization: Helps focus on critical issues
  • Integration Friendly: Works with existing development workflows

Implementation Strategy:

  1. Initial Setup: Configure Black Duck instance and API access
  2. CI/CD Integration: Embed scanning in build pipelines
  3. Policy Definition: Establish security and license policies
  4. Remediation Workflow: Create processes for addressing findings
  5. Continuous Monitoring: Regular scanning and reporting

Best Practices:

  • Scan early and often in development lifecycle
  • Fail builds on critical security violations
  • Maintain updated vulnerability databases
  • Train development teams on interpreting results
  • Establish clear remediation workflows

By implementing Black Duck security scanning, organizations can significantly improve their software security posture, ensure license compliance, and reduce the risk of deploying vulnerable applications to production.


Next Steps: Start with a pilot project, establish baseline security policies, integrate into your CI/CD pipeline, and gradually expand coverage across all Java applications in your organization.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper