Article: Comprehensive Software Composition Analysis with Veracode SourceClear
Veracode SourceClear provides software composition analysis (SCA) to identify vulnerabilities in open-source dependencies. This article covers comprehensive integration strategies for Java applications with advanced features like policy enforcement, CI/CD integration, and remediation guidance.
Core SourceClear Integration
package com.titliel.veracode;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.concurrent.*;
import java.net.http.*;
import java.net.URI;
import javax.net.ssl.SSLContext;
/**
* Titliel Veracode SourceClear Scanner
* Advanced SCA integration with policy enforcement and remediation tracking
*/
public class TitlielSourceClearScanner {
private final SourceClearConfig config;
private final HttpClient httpClient;
private final VulnerabilityProcessor vulnProcessor;
private final PolicyEngine policyEngine;
private final ReportGenerator reportGenerator;
private final ExecutorService scanExecutor;
public TitlielSourceClearScanner() {
this.config = SourceClearConfig.getInstance();
this.httpClient = createHttpClient();
this.vulnProcessor = new VulnerabilityProcessor();
this.policyEngine = new PolicyEngine();
this.reportGenerator = new ReportGenerator();
this.scanExecutor = Executors.newFixedThreadPool(config.getThreadCount());
}
/**
* Perform comprehensive SCA scan
*/
public ScanResult scanProject(ProjectContext context) {
long startTime = System.currentTimeMillis();
ScanResult result = new ScanResult(context);
try {
// Pre-scan validation
validateProjectStructure(context);
// Execute scan phases in parallel
List<Future<ScanResult>> futures = new ArrayList<>();
futures.add(scanExecutor.submit(() -> performDependencyScan(context)));
futures.add(scanExecutor.submit(() -> performLicenseScan(context)));
futures.add(scanExecutor.submit(() -> performVulnerabilityScan(context)));
futures.add(scanExecutor.submit(() -> performPolicyCheck(context)));
// Wait for all scans to complete
for (Future<ScanResult> future : futures) {
try {
ScanResult partialResult = future.get();
result.merge(partialResult);
} catch (Exception e) {
result.addError(new ScanError("Scan phase failed", e));
}
}
// Post-process results
processScanResults(result);
// Generate reports
generateReports(result);
// Upload results to Veracode platform
if (config.isUploadEnabled()) {
uploadResults(result);
}
} catch (Exception e) {
result.addError(new ScanError("Scan failed", e));
} finally {
result.setScanDuration(System.currentTimeMillis() - startTime);
}
return result;
}
/**
* Perform dependency inventory scan
*/
private ScanResult performDependencyScan(ProjectContext context) {
ScanResult result = new ScanResult(context, ScanType.DEPENDENCY_INVENTORY);
try {
DependencyResolver resolver = new DependencyResolver();
List<Dependency> dependencies = resolver.resolveDependencies(context);
result.setDependencies(dependencies);
result.addMetric("dependencies_count", dependencies.size());
// Analyze dependency health
analyzeDependencyHealth(dependencies, result);
} catch (Exception e) {
result.addError(new ScanError("Dependency scan failed", e));
}
return result;
}
/**
* Perform license compliance scan
*/
private ScanResult performLicenseScan(ProjectContext context) {
ScanResult result = new ScanResult(context, ScanType.LICENSE_COMPLIANCE);
try {
LicenseAnalyzer analyzer = new LicenseAnalyzer();
List<LicenseViolation> violations = analyzer.analyzeLicenses(context);
for (LicenseViolation violation : violations) {
result.addLicenseViolation(violation);
}
result.addMetric("license_violations", violations.size());
} catch (Exception e) {
result.addError(new ScanError("License scan failed", e));
}
return result;
}
/**
* Perform vulnerability analysis
*/
private ScanResult performVulnerabilityScan(ProjectContext context) {
ScanResult result = new ScanResult(context, ScanType.VULNERABILITY_ANALYSIS);
try {
// Get dependencies from context or resolve fresh
List<Dependency> dependencies = result.getDependencies();
if (dependencies.isEmpty()) {
DependencyResolver resolver = new DependencyResolver();
dependencies = resolver.resolveDependencies(context);
}
// Check vulnerabilities for each dependency
for (Dependency dependency : dependencies) {
List<Vulnerability> vulns = checkDependencyVulnerabilities(dependency);
result.addVulnerabilities(vulns);
}
result.addMetric("vulnerabilities_count", result.getVulnerabilities().size());
} catch (Exception e) {
result.addError(new ScanError("Vulnerability scan failed", e));
}
return result;
}
/**
* Perform policy compliance check
*/
private ScanResult performPolicyCheck(ProjectContext context) {
ScanResult result = new ScanResult(context, ScanType.POLICY_COMPLIANCE);
try {
PolicyCheckResult policyResult = policyEngine.evaluatePolicy(result);
result.setPolicyResult(policyResult);
result.addMetric("policy_violations", policyResult.getViolations().size());
result.addMetric("policy_compliant", policyResult.isCompliant());
} catch (Exception e) {
result.addError(new ScanError("Policy check failed", e));
}
return result;
}
/**
* Check vulnerabilities for a specific dependency using SourceClear API
*/
private List<Vulnerability> checkDependencyVulnerabilities(Dependency dependency) {
List<Vulnerability> vulnerabilities = new ArrayList<>();
try {
// Build API request
String apiUrl = config.getApiBaseUrl() + "/v1/dependencies/vulnerabilities";
String requestBody = buildVulnerabilityRequest(dependency);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(apiUrl))
.header("Authorization", "Bearer " + config.getApiKey())
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
// Execute API call
HttpResponse<String> response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
vulnerabilities = parseVulnerabilityResponse(response.body(), dependency);
} else {
throw new IOException("API request failed: " + response.statusCode());
}
} catch (Exception e) {
// Fallback to local vulnerability database
vulnerabilities = checkLocalVulnerabilityDatabase(dependency);
}
return vulnerabilities;
}
/**
* Build vulnerability check request
*/
private String buildVulnerabilityRequest(Dependency dependency) {
Map<String, Object> request = new HashMap<>();
request.put("coordinates", dependency.getCoordinates());
request.put("version", dependency.getVersion());
request.put("ecosystem", "maven"); // or "gradle"
// Convert to JSON
return new JSONObject(request).toString();
}
/**
* Parse vulnerability API response
*/
private List<Vulnerability> parseVulnerabilityResponse(String responseBody,
Dependency dependency) {
List<Vulnerability> vulnerabilities = new ArrayList<>();
try {
JSONObject json = new JSONObject(responseBody);
JSONArray vulnsArray = json.getJSONArray("vulnerabilities");
for (int i = 0; i < vulnsArray.length(); i++) {
JSONObject vulnJson = vulnsArray.getJSONObject(i);
Vulnerability vulnerability = parseVulnerability(vulnJson, dependency);
vulnerabilities.add(vulnerability);
}
} catch (Exception e) {
throw new RuntimeException("Failed to parse vulnerability response", e);
}
return vulnerabilities;
}
/**
* Parse individual vulnerability
*/
private Vulnerability parseVulnerability(JSONObject vulnJson, Dependency dependency) {
Vulnerability vuln = new Vulnerability();
vuln.setId(vulnJson.getString("cve"));
vuln.setTitle(vulnJson.getString("title"));
vuln.setDescription(vulnJson.optString("description", ""));
vuln.setSeverity(SeverityLevel.fromString(vulnJson.getString("severity")));
vuln.setCvssScore(vulnJson.optDouble("cvss_score", 0.0));
vuln.setCweId(vulnJson.optString("cwe", ""));
vuln.setPublishedDate(parseDate(vulnJson.optString("published_date")));
vuln.setAffectedDependency(dependency);
// Parse remediation information
if (vulnJson.has("remediation")) {
JSONObject remediation = vulnJson.getJSONObject("remediation");
vuln.setRemediation(remediation.optString("recommendation", ""));
vuln.setFixedVersion(remediation.optString("fixed_version", ""));
}
// Parse exploit information
if (vulnJson.has("exploit")) {
JSONObject exploit = vulnJson.getJSONObject("exploit");
vuln.setExploitAvailable(exploit.optBoolean("available", false));
vuln.setExploitMaturity(exploit.optString("maturity", ""));
}
return vuln;
}
/**
* Fallback to local vulnerability database
*/
private List<Vulnerability> checkLocalVulnerabilityDatabase(Dependency dependency) {
// Implement local vulnerability database check
return new ArrayList<>();
}
/**
* Analyze dependency health metrics
*/
private void analyzeDependencyHealth(List<Dependency> dependencies, ScanResult result) {
DependencyHealthMetrics metrics = new DependencyHealthMetrics();
for (Dependency dependency : dependencies) {
metrics.analyzeDependency(dependency);
}
result.setHealthMetrics(metrics);
// Add metrics to result
result.addMetric("outdated_dependencies", metrics.getOutdatedCount());
result.addMetric("unmaintained_dependencies", metrics.getUnmaintainedCount());
result.addMetric("average_dependency_age", metrics.getAverageAgeInMonths());
}
/**
* Process and enrich scan results
*/
private void processScanResults(ScanResult result) {
// Process vulnerabilities
vulnProcessor.processVulnerabilities(result);
// Calculate risk scores
calculateRiskScores(result);
// Generate remediation guidance
generateRemediationGuidance(result);
// Update dependency graph
buildDependencyGraph(result);
}
/**
* Calculate overall risk scores
*/
private void calculateRiskScores(ScanResult result) {
RiskCalculator calculator = new RiskCalculator();
RiskAssessment assessment = calculator.assessRisk(result);
result.setRiskAssessment(assessment);
}
/**
* Generate remediation guidance
*/
private void generateRemediationGuidance(ScanResult result) {
RemediationEngine engine = new RemediationEngine();
RemediationPlan plan = engine.generateRemediationPlan(result);
result.setRemediationPlan(plan);
}
/**
* Build dependency graph with vulnerability information
*/
private void buildDependencyGraph(ScanResult result) {
DependencyGraphBuilder builder = new DependencyGraphBuilder();
DependencyGraph graph = builder.buildGraph(result.getDependencies(),
result.getVulnerabilities());
result.setDependencyGraph(graph);
}
/**
* Generate comprehensive reports
*/
private void generateReports(ScanResult result) {
try {
// HTML Report
if (config.isHtmlReportEnabled()) {
Path htmlReport = reportGenerator.generateHtmlReport(result);
result.addReport(htmlReport, ReportType.HTML);
}
// JSON Report
if (config.isJsonReportEnabled()) {
Path jsonReport = reportGenerator.generateJsonReport(result);
result.addReport(jsonReport, ReportType.JSON);
}
// SARIF Report for GitHub
if (config.isSarifReportEnabled()) {
Path sarifReport = reportGenerator.generateSarifReport(result);
result.addReport(sarifReport, ReportType.SARIF);
}
// SPDX Report for license compliance
if (config.isSpdxReportEnabled()) {
Path spdxReport = reportGenerator.generateSpdxReport(result);
result.addReport(spdxReport, ReportType.SPDX);
}
// CSV Report for spreadsheet analysis
if (config.isCsvReportEnabled()) {
Path csvReport = reportGenerator.generateCsvReport(result);
result.addReport(csvReport, ReportType.CSV);
}
} catch (Exception e) {
result.addError(new ScanError("Report generation failed", e));
}
}
/**
* Upload results to Veracode platform
*/
private void uploadResults(ScanResult result) {
try {
VeracodeUploader uploader = new VeracodeUploader(config);
UploadResult uploadResult = uploader.uploadScanResults(result);
result.setUploadResult(uploadResult);
} catch (Exception e) {
result.addError(new ScanError("Results upload failed", e));
}
}
/**
* Validate project structure
*/
private void validateProjectStructure(ProjectContext context) {
List<String> errors = new ArrayList<>();
if (!Files.exists(context.getProjectDir())) {
errors.add("Project directory does not exist: " + context.getProjectDir());
}
// Check for build files
if (!hasBuildFile(context.getProjectDir())) {
errors.add("No build file (pom.xml, build.gradle) found");
}
// Validate API configuration
if (!config.isValid()) {
errors.add("SourceClear configuration is invalid");
}
if (!errors.isEmpty()) {
throw new ScanValidationException("Project validation failed: " +
String.join(", ", errors));
}
}
private boolean hasBuildFile(Path projectDir) {
return Files.exists(projectDir.resolve("pom.xml")) ||
Files.exists(projectDir.resolve("build.gradle")) ||
Files.exists(projectDir.resolve("build.gradle.kts"));
}
/**
* Create HTTP client with proper configuration
*/
private HttpClient createHttpClient() {
return HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(30))
.sslContext(createSSLContext())
.build();
}
private SSLContext createSSLContext() {
try {
return SSLContext.getDefault();
} catch (Exception e) {
throw new RuntimeException("Failed to create SSL context", e);
}
}
private Date parseDate(String dateString) {
try {
// Implement date parsing logic
return new Date(); // Placeholder
} catch (Exception e) {
return new Date();
}
}
public void shutdown() {
scanExecutor.shutdown();
try {
if (!scanExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
scanExecutor.shutdownNow();
}
} catch (InterruptedException e) {
scanExecutor.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
Data Models and Configuration
package com.titliel.veracode;
import java.nio.file.Path;
import java.util.*;
/**
* Project context for SourceClear scanning
*/
public class ProjectContext {
private final Path projectDir;
private final String projectName;
private final String version;
private final BuildTool buildTool;
private final Map<String, String> properties;
private final List<String> scanIncludes;
private final List<String> scanExcludes;
public ProjectContext(Path projectDir, String projectName) {
this.projectDir = projectDir;
this.projectName = projectName;
this.version = "1.0.0";
this.buildTool = detectBuildTool(projectDir);
this.properties = new HashMap<>();
this.scanIncludes = new ArrayList<>();
this.scanExcludes = new ArrayList<>();
// Default excludes
this.scanExcludes.add("**/test/**");
this.scanExcludes.add("**/target/**");
this.scanExcludes.add("**/build/**");
this.scanExcludes.add("**/node_modules/**");
}
// Builder pattern
public static class Builder {
private Path projectDir;
private String projectName;
private String version = "1.0.0";
private BuildTool buildTool;
private Map<String, String> properties = new HashMap<>();
private List<String> includes = new ArrayList<>();
private List<String> excludes = new ArrayList<>();
public Builder setProjectDir(Path projectDir) {
this.projectDir = projectDir;
return this;
}
public Builder setProjectName(String projectName) {
this.projectName = projectName;
return this;
}
public Builder setVersion(String version) {
this.version = version;
return this;
}
public Builder setBuildTool(BuildTool buildTool) {
this.buildTool = buildTool;
return this;
}
public Builder addProperty(String key, String value) {
this.properties.put(key, value);
return this;
}
public Builder addInclude(String pattern) {
this.includes.add(pattern);
return this;
}
public Builder addExclude(String pattern) {
this.excludes.add(pattern);
return this;
}
public ProjectContext build() {
ProjectContext context = new ProjectContext(projectDir, projectName);
context.version = version;
context.buildTool = buildTool != null ? buildTool : context.buildTool;
context.properties.putAll(properties);
context.scanIncludes.addAll(includes);
context.scanExcludes.addAll(excludes);
return context;
}
}
private static BuildTool detectBuildTool(Path projectDir) {
if (Files.exists(projectDir.resolve("pom.xml"))) {
return BuildTool.MAVEN;
} else if (Files.exists(projectDir.resolve("build.gradle")) ||
Files.exists(projectDir.resolve("build.gradle.kts"))) {
return BuildTool.GRADLE;
}
return BuildTool.UNKNOWN;
}
// Getters
public Path getProjectDir() { return projectDir; }
public String getProjectName() { return projectName; }
public String getVersion() { return version; }
public BuildTool getBuildTool() { return buildTool; }
public Map<String, String> getProperties() { return Collections.unmodifiableMap(properties); }
public List<String> getScanIncludes() { return Collections.unmodifiableList(scanIncludes); }
public List<String> getScanExcludes() { return Collections.unmodifiableList(scanExcludes); }
}
/**
* Comprehensive scan result container
*/
public class ScanResult {
private final ProjectContext context;
private final ScanType scanType;
private final List<Vulnerability> vulnerabilities;
private final List<LicenseViolation> licenseViolations;
private final List<Dependency> dependencies;
private final List<ScanError> errors;
private final Map<ReportType, Path> reports;
private final Map<String, Object> metrics;
private PolicyCheckResult policyResult;
private RiskAssessment riskAssessment;
private RemediationPlan remediationPlan;
private DependencyGraph dependencyGraph;
private DependencyHealthMetrics healthMetrics;
private UploadResult uploadResult;
private long scanDuration;
private Date scanTimestamp;
public ScanResult(ProjectContext context) {
this(context, ScanType.COMPREHENSIVE);
}
public ScanResult(ProjectContext context, ScanType scanType) {
this.context = context;
this.scanType = scanType;
this.vulnerabilities = new ArrayList<>();
this.licenseViolations = new ArrayList<>();
this.dependencies = new ArrayList<>();
this.errors = new ArrayList<>();
this.reports = new HashMap<>();
this.metrics = new HashMap<>();
this.scanTimestamp = new Date();
}
// Add methods
public void addVulnerability(Vulnerability vulnerability) {
this.vulnerabilities.add(vulnerability);
}
public void addVulnerabilities(List<Vulnerability> vulnerabilities) {
this.vulnerabilities.addAll(vulnerabilities);
}
public void addLicenseViolation(LicenseViolation violation) {
this.licenseViolations.add(violation);
}
public void addDependency(Dependency dependency) {
this.dependencies.add(dependency);
}
public void addError(ScanError error) {
this.errors.add(error);
}
public void addReport(Path reportPath, ReportType reportType) {
this.reports.put(reportType, reportPath);
}
public void addMetric(String key, Object value) {
this.metrics.put(key, value);
}
public void merge(ScanResult other) {
this.vulnerabilities.addAll(other.vulnerabilities);
this.licenseViolations.addAll(other.licenseViolations);
this.dependencies.addAll(other.dependencies);
this.errors.addAll(other.errors);
this.reports.putAll(other.reports);
this.metrics.putAll(other.metrics);
}
// Getters and setters
public ProjectContext getContext() { return context; }
public ScanType getScanType() { return scanType; }
public List<Vulnerability> getVulnerabilities() { return Collections.unmodifiableList(vulnerabilities); }
public List<LicenseViolation> getLicenseViolations() { return Collections.unmodifiableList(licenseViolations); }
public List<Dependency> getDependencies() { return Collections.unmodifiableList(dependencies); }
public void setDependencies(List<Dependency> dependencies) { this.dependencies.clear(); this.dependencies.addAll(dependencies); }
public List<ScanError> getErrors() { return Collections.unmodifiableList(errors); }
public Map<ReportType, Path> getReports() { return Collections.unmodifiableMap(reports); }
public Map<String, Object> getMetrics() { return Collections.unmodifiableMap(metrics); }
public PolicyCheckResult getPolicyResult() { return policyResult; }
public void setPolicyResult(PolicyCheckResult policyResult) { this.policyResult = policyResult; }
public RiskAssessment getRiskAssessment() { return riskAssessment; }
public void setRiskAssessment(RiskAssessment riskAssessment) { this.riskAssessment = riskAssessment; }
public RemediationPlan getRemediationPlan() { return remediationPlan; }
public void setRemediationPlan(RemediationPlan remediationPlan) { this.remediationPlan = remediationPlan; }
public DependencyGraph getDependencyGraph() { return dependencyGraph; }
public void setDependencyGraph(DependencyGraph dependencyGraph) { this.dependencyGraph = dependencyGraph; }
public DependencyHealthMetrics getHealthMetrics() { return healthMetrics; }
public void setHealthMetrics(DependencyHealthMetrics healthMetrics) { this.healthMetrics = healthMetrics; }
public UploadResult getUploadResult() { return uploadResult; }
public void setUploadResult(UploadResult uploadResult) { this.uploadResult = uploadResult; }
public long getScanDuration() { return scanDuration; }
public void setScanDuration(long scanDuration) { this.scanDuration = scanDuration; }
public Date getScanTimestamp() { return scanTimestamp; }
// Statistics methods
public int getTotalVulnerabilities() { return vulnerabilities.size(); }
public int getCriticalVulnerabilities() { return countVulnerabilitiesBySeverity(SeverityLevel.CRITICAL); }
public int getHighVulnerabilities() { return countVulnerabilitiesBySeverity(SeverityLevel.HIGH); }
public int getMediumVulnerabilities() { return countVulnerabilitiesBySeverity(SeverityLevel.MEDIUM); }
public int getLowVulnerabilities() { return countVulnerabilitiesBySeverity(SeverityLevel.LOW); }
public int getTotalLicenseViolations() { return licenseViolations.size(); }
public int getCriticalLicenseViolations() { return countLicenseViolationsBySeverity(SeverityLevel.CRITICAL); }
public boolean hasCriticalIssues() {
return getCriticalVulnerabilities() > 0 || getCriticalLicenseViolations() > 0;
}
public boolean isScanSuccessful() {
return errors.isEmpty();
}
public boolean isPolicyCompliant() {
return policyResult != null && policyResult.isCompliant();
}
private int countVulnerabilitiesBySeverity(SeverityLevel severity) {
return (int) vulnerabilities.stream()
.filter(v -> v.getSeverity() == severity)
.count();
}
private int countLicenseViolationsBySeverity(SeverityLevel severity) {
return (int) licenseViolations.stream()
.filter(v -> v.getSeverity() == severity)
.count();
}
}
/**
* Dependency representation
*/
public class Dependency {
private final String groupId;
private final String artifactId;
private final String version;
private final String scope;
private final List<License> licenses;
private final Date lastUpdated;
private final DependencyHealth health;
public Dependency(String groupId, String artifactId, String version, String scope) {
this.groupId = groupId;
this.artifactId = artifactId;
this.version = version;
this.scope = scope;
this.licenses = new ArrayList<>();
this.lastUpdated = new Date();
this.health = new DependencyHealth();
}
// Getters
public String getGroupId() { return groupId; }
public String getArtifactId() { return artifactId; }
public String getVersion() { return version; }
public String getScope() { return scope; }
public List<License> getLicenses() { return Collections.unmodifiableList(licenses); }
public Date getLastUpdated() { return lastUpdated; }
public DependencyHealth getHealth() { return health; }
public String getCoordinates() {
return groupId + ":" + artifactId + ":" + version;
}
public void addLicense(License license) {
this.licenses.add(license);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Dependency that = (Dependency) o;
return Objects.equals(groupId, that.groupId) &&
Objects.equals(artifactId, that.artifactId) &&
Objects.equals(version, that.version);
}
@Override
public int hashCode() {
return Objects.hash(groupId, artifactId, version);
}
}
/**
* Vulnerability representation
*/
public class Vulnerability {
private String id;
private String title;
private String description;
private SeverityLevel severity;
private double cvssScore;
private String cweId;
private Date publishedDate;
private Dependency affectedDependency;
private String remediation;
private String fixedVersion;
private boolean exploitAvailable;
private String exploitMaturity;
private Map<String, Object> metadata;
public Vulnerability() {
this.metadata = new HashMap<>();
}
// Getters and setters
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
public SeverityLevel getSeverity() { return severity; }
public void setSeverity(SeverityLevel severity) { this.severity = severity; }
public double getCvssScore() { return cvssScore; }
public void setCvssScore(double cvssScore) { this.cvssScore = cvssScore; }
public String getCweId() { return cweId; }
public void setCweId(String cweId) { this.cweId = cweId; }
public Date getPublishedDate() { return publishedDate; }
public void setPublishedDate(Date publishedDate) { this.publishedDate = publishedDate; }
public Dependency getAffectedDependency() { return affectedDependency; }
public void setAffectedDependency(Dependency affectedDependency) { this.affectedDependency = affectedDependency; }
public String getRemediation() { return remediation; }
public void setRemediation(String remediation) { this.remediation = remediation; }
public String getFixedVersion() { return fixedVersion; }
public void setFixedVersion(String fixedVersion) { this.fixedVersion = fixedVersion; }
public boolean isExploitAvailable() { return exploitAvailable; }
public void setExploitAvailable(boolean exploitAvailable) { this.exploitAvailable = exploitAvailable; }
public String getExploitMaturity() { return exploitMaturity; }
public void setExploitMaturity(String exploitMaturity) { this.exploitMaturity = exploitMaturity; }
public Map<String, Object> getMetadata() { return Collections.unmodifiableMap(metadata); }
public void addMetadata(String key, Object value) { this.metadata.put(key, value); }
}
/**
* License violation representation
*/
public class LicenseViolation {
private final License license;
private final Dependency dependency;
private final String violationType;
private final SeverityLevel severity;
private final String description;
public LicenseViolation(License license, Dependency dependency, String violationType,
SeverityLevel severity, String description) {
this.license = license;
this.dependency = dependency;
this.violationType = violationType;
this.severity = severity;
this.description = description;
}
// Getters
public License getLicense() { return license; }
public Dependency getDependency() { return dependency; }
public String getViolationType() { return violationType; }
public SeverityLevel getSeverity() { return severity; }
public String getDescription() { return description; }
}
/**
* Enums and supporting classes
*/
public enum ScanType {
DEPENDENCY_INVENTORY, LICENSE_COMPLIANCE, VULNERABILITY_ANALYSIS,
POLICY_COMPLIANCE, COMPREHENSIVE
}
public enum BuildTool {
MAVEN, GRADLE, UNKNOWN
}
public enum SeverityLevel {
CRITICAL, HIGH, MEDIUM, LOW, INFO;
public static SeverityLevel fromString(String severity) {
try {
return SeverityLevel.valueOf(severity.toUpperCase());
} catch (IllegalArgumentException e) {
return INFO;
}
}
}
public enum ReportType {
HTML, JSON, SARIF, SPDX, CSV, PDF
}
/**
* License information
*/
public class License {
private final String id;
private final String name;
private final String url;
private final boolean osiApproved;
private final RiskLevel riskLevel;
public License(String id, String name, String url, boolean osiApproved, RiskLevel riskLevel) {
this.id = id;
this.name = name;
this.url = url;
this.osiApproved = osiApproved;
this.riskLevel = riskLevel;
}
// Getters
public String getId() { return id; }
public String getName() { return name; }
public String getUrl() { return url; }
public boolean isOsiApproved() { return osiApproved; }
public RiskLevel getRiskLevel() { return riskLevel; }
}
public enum RiskLevel {
HIGH, MEDIUM, LOW, NONE
}
/**
* Dependency health metrics
*/
public class DependencyHealth {
private boolean outdated;
private boolean unmaintained;
private boolean deprecated;
private int monthsSinceUpdate;
private int vulnerabilityCount;
private double healthScore;
// Getters and setters
public boolean isOutdated() { return outdated; }
public void setOutdated(boolean outdated) { this.outdated = outdated; }
public boolean isUnmaintained() { return unmaintained; }
public void setUnmaintained(boolean unmaintained) { this.unmaintained = unmaintained; }
public boolean isDeprecated() { return deprecated; }
public void setDeprecated(boolean deprecated) { this.deprecated = deprecated; }
public int getMonthsSinceUpdate() { return monthsSinceUpdate; }
public void setMonthsSinceUpdate(int monthsSinceUpdate) { this.monthsSinceUpdate = monthsSinceUpdate; }
public int getVulnerabilityCount() { return vulnerabilityCount; }
public void setVulnerabilityCount(int vulnerabilityCount) { this.vulnerabilityCount = vulnerabilityCount; }
public double getHealthScore() { return healthScore; }
public void setHealthScore(double healthScore) { this.healthScore = healthScore; }
}
Dependency Resolution and Analysis
package com.titliel.veracode;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* Dependency resolver for different build tools
*/
public class DependencyResolver {
public List<Dependency> resolveDependencies(ProjectContext context) {
switch (context.getBuildTool()) {
case MAVEN:
return resolveMavenDependencies(context);
case GRADLE:
return resolveGradleDependencies(context);
default:
throw new UnsupportedOperationException(
"Unsupported build tool: " + context.getBuildTool());
}
}
/**
* Resolve Maven dependencies from pom.xml
*/
private List<Dependency> resolveMavenDependencies(ProjectContext context) {
List<Dependency> dependencies = new ArrayList<>();
try {
Path pomFile = context.getProjectDir().resolve("pom.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(pomFile.toFile());
// Parse dependencies
NodeList dependencyNodes = document.getElementsByTagName("dependency");
for (int i = 0; i < dependencyNodes.getLength(); i++) {
Element dependencyElement = (Element) dependencyNodes.item(i);
Dependency dependency = parseMavenDependency(dependencyElement);
if (dependency != null) {
dependencies.add(dependency);
}
}
// Parse dependency management
parseDependencyManagement(document, dependencies);
// Resolve transitive dependencies (simplified)
resolveTransitiveDependencies(dependencies, context);
} catch (Exception e) {
throw new RuntimeException("Failed to resolve Maven dependencies", e);
}
return dependencies;
}
/**
* Parse individual Maven dependency
*/
private Dependency parseMavenDependency(Element dependencyElement) {
String groupId = getElementText(dependencyElement, "groupId");
String artifactId = getElementText(dependencyElement, "artifactId");
String version = getElementText(dependencyElement, "version");
String scope = getElementText(dependencyElement, "scope", "compile");
if (groupId == null || artifactId == null || version == null) {
return null;
}
Dependency dependency = new Dependency(groupId, artifactId, version, scope);
// Parse licenses
NodeList licenseNodes = dependencyElement.getElementsByTagName("license");
for (int i = 0; i < licenseNodes.getLength(); i++) {
Element licenseElement = (Element) licenseNodes.item(i);
License license = parseMavenLicense(licenseElement);
if (license != null) {
dependency.addLicense(license);
}
}
return dependency;
}
/**
* Parse Maven license information
*/
private License parseMavenLicense(Element licenseElement) {
String name = getElementText(licenseElement, "name");
String url = getElementText(licenseElement, "url");
if (name == null) {
return null;
}
// Determine license ID and risk level
String licenseId = inferLicenseId(name);
RiskLevel riskLevel = assessLicenseRisk(licenseId);
return new License(licenseId, name, url, isOsiApproved(licenseId), riskLevel);
}
/**
* Parse dependency management section
*/
private void parseDependencyManagement(Document document, List<Dependency> dependencies) {
// Implement dependency management parsing
// This would handle version inheritance and BOM imports
}
/**
* Resolve transitive dependencies (simplified)
*/
private void resolveTransitiveDependencies(List<Dependency> directDependencies,
ProjectContext context) {
// In a real implementation, this would use Maven/Gradle APIs
// to resolve the complete dependency tree
Set<Dependency> allDependencies = new HashSet<>(directDependencies);
for (Dependency directDep : directDependencies) {
List<Dependency> transitive = resolveTransitiveForDependency(directDep, context);
allDependencies.addAll(transitive);
}
directDependencies.clear();
directDependencies.addAll(allDependencies);
}
private List<Dependency> resolveTransitiveForDependency(Dependency dependency,
ProjectContext context) {
// Simplified transitive dependency resolution
// Real implementation would require dependency graph resolution
return new ArrayList<>();
}
/**
* Resolve Gradle dependencies
*/
private List<Dependency> resolveGradleDependencies(ProjectContext context) {
List<Dependency> dependencies = new ArrayList<>();
try {
// Execute gradle dependencies command
ProcessBuilder processBuilder = new ProcessBuilder(
"gradle", "dependencies", "--configuration", "compileClasspath");
processBuilder.directory(context.getProjectDir().toFile());
Process process = processBuilder.start();
String output = readProcessOutput(process);
dependencies = parseGradleDependencies(output);
} catch (Exception e) {
// Fallback to parsing build.gradle directly
dependencies = parseGradleBuildFile(context.getProjectDir());
}
return dependencies;
}
/**
* Parse Gradle dependencies output
*/
private List<Dependency> parseGradleDependencies(String output) {
List<Dependency> dependencies = new ArrayList<>();
// Implement Gradle dependencies output parsing
// This is a simplified version
String[] lines = output.split("\n");
for (String line : lines) {
if (line.contains("---") && line.contains(":")) {
Dependency dependency = parseGradleDependencyLine(line);
if (dependency != null) {
dependencies.add(dependency);
}
}
}
return dependencies;
}
private Dependency parseGradleDependencyLine(String line) {
// Simplified Gradle dependency parsing
// Real implementation would be more complex
try {
String[] parts = line.trim().split(":");
if (parts.length >= 3) {
String groupId = parts[0];
String artifactId = parts[1];
String version = parts[2].split(" ")[0]; // Remove extra info
return new Dependency(groupId, artifactId, version, "compile");
}
} catch (Exception e) {
// Skip malformed lines
}
return null;
}
/**
* Parse Gradle build file directly
*/
private List<Dependency> parseGradleBuildFile(Path projectDir) {
// Implement Gradle build file parsing
return new ArrayList<>();
}
// Utility methods
private String getElementText(Element parent, String tagName) {
return getElementText(parent, tagName, null);
}
private String getElementText(Element parent, String tagName, String defaultValue) {
NodeList nodes = parent.getElementsByTagName(tagName);
if (nodes.getLength() > 0) {
return nodes.item(0).getTextContent().trim();
}
return defaultValue;
}
private String readProcessOutput(Process process) throws IOException {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
StringBuilder output = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
output.append(line).append("\n");
}
return output.toString();
}
}
private String inferLicenseId(String licenseName) {
// Map common license names to SPDX IDs
Map<String, String> licenseMap = new HashMap<>();
licenseMap.put("Apache License 2.0", "Apache-2.0");
licenseMap.put("MIT License", "MIT");
licenseMap.put("GPL 3.0", "GPL-3.0");
// Add more mappings
return licenseMap.getOrDefault(licenseName, "UNKNOWN");
}
private RiskLevel assessLicenseRisk(String licenseId) {
Map<String, RiskLevel> riskMap = new HashMap<>();
riskMap.put("GPL-3.0", RiskLevel.HIGH);
riskMap.put("AGPL-3.0", RiskLevel.HIGH);
riskMap.put("LGPL-3.0", RiskLevel.MEDIUM);
riskMap.put("Apache-2.0", RiskLevel.LOW);
riskMap.put("MIT", RiskLevel.LOW);
riskMap.put("BSD-2-Clause", RiskLevel.LOW);
riskMap.put("BSD-3-Clause", RiskLevel.LOW);
return riskMap.getOrDefault(licenseId, RiskLevel.MEDIUM);
}
private boolean isOsiApproved(String licenseId) {
Set<String> osiApproved = Set.of(
"Apache-2.0", "MIT", "BSD-2-Clause", "BSD-3-Clause",
"GPL-3.0", "LGPL-3.0"
);
return osiApproved.contains(licenseId);
}
}
/**
* License analyzer for compliance checking
*/
class LicenseAnalyzer {
public List<LicenseViolation> analyzeLicenses(ProjectContext context) {
List<LicenseViolation> violations = new ArrayList<>();
try {
DependencyResolver resolver = new DependencyResolver();
List<Dependency> dependencies = resolver.resolveDependencies(context);
for (Dependency dependency : dependencies) {
for (License license : dependency.getLicenses()) {
LicenseViolation violation = checkLicenseCompliance(license, dependency);
if (violation != null) {
violations.add(violation);
}
}
}
} catch (Exception e) {
throw new RuntimeException("License analysis failed", e);
}
return violations;
}
private LicenseViolation checkLicenseCompliance(License license, Dependency dependency) {
// Check against organizational policy
if (license.getRiskLevel() == RiskLevel.HIGH) {
return new LicenseViolation(
license, dependency, "HIGH_RISK_LICENSE",
SeverityLevel.CRITICAL,
"High-risk license detected: " + license.getName()
);
}
if (!license.isOsiApproved()) {
return new LicenseViolation(
license, dependency, "NON_OSI_APPROVED",
SeverityLevel.MEDIUM,
"Non-OSI approved license: " + license.getName()
);
}
// Add more license policy checks
return null;
}
}
Policy Engine and Risk Assessment
package com.titliel.veracode;
import java.util.*;
/**
* Policy engine for security and compliance checks
*/
public class PolicyEngine {
private final List<PolicyRule> rules;
private final PolicyConfig config;
public PolicyEngine() {
this.config = PolicyConfig.getInstance();
this.rules = loadPolicyRules();
}
public PolicyCheckResult evaluatePolicy(ScanResult scanResult) {
PolicyCheckResult result = new PolicyCheckResult();
for (PolicyRule rule : rules) {
if (rule.isEnabled()) {
PolicyViolation violation = rule.evaluate(scanResult);
if (violation != null) {
result.addViolation(violation);
}
}
}
result.setCompliant(result.getViolations().isEmpty());
return result;
}
private List<PolicyRule> loadPolicyRules() {
List<PolicyRule> rules = new ArrayList<>();
// Critical vulnerability policy
rules.add(new CriticalVulnerabilityPolicy());
// High vulnerability count policy
rules.add(new HighVulnerabilityCountPolicy());
// License compliance policy
rules.add(new LicenseCompliancePolicy());
// Outdated dependencies policy
rules.add(new OutdatedDependenciesPolicy());
// Custom organizational policies
rules.addAll(loadCustomPolicies());
return rules;
}
private List<PolicyRule> loadCustomPolicies() {
// Load custom policies from configuration
return new ArrayList<>();
}
}
/**
* Policy rule interface
*/
interface PolicyRule {
boolean isEnabled();
PolicyViolation evaluate(ScanResult scanResult);
}
/**
* Critical vulnerability policy
*/
class CriticalVulnerabilityPolicy implements PolicyRule {
@Override
public boolean isEnabled() {
return true; // Typically enabled by default
}
@Override
public PolicyViolation evaluate(ScanResult scanResult) {
if (scanResult.getCriticalVulnerabilities() > 0) {
return new PolicyViolation(
"CRITICAL_VULNERABILITIES",
SeverityLevel.CRITICAL,
"Critical vulnerabilities detected: " +
scanResult.getCriticalVulnerabilities(),
"Fix all critical vulnerabilities before deployment"
);
}
return null;
}
}
/**
* High vulnerability count policy
*/
class HighVulnerabilityCountPolicy implements PolicyRule {
private static final int MAX_HIGH_VULNERABILITIES = 10;
@Override
public boolean isEnabled() {
return true;
}
@Override
public PolicyViolation evaluate(ScanResult scanResult) {
if (scanResult.getHighVulnerabilities() > MAX_HIGH_VULNERABILITIES) {
return new PolicyViolation(
"EXCESSIVE_HIGH_VULNERABILITIES",
SeverityLevel.HIGH,
"Too many high severity vulnerabilities: " +
scanResult.getHighVulnerabilities() + " (max: " + MAX_HIGH_VULNERABILITIES + ")",
"Reduce high severity vulnerabilities below threshold"
);
}
return null;
}
}
/**
* License compliance policy
*/
class LicenseCompliancePolicy implements PolicyRule {
@Override
public boolean isEnabled() {
return true;
}
@Override
public PolicyViolation evaluate(ScanResult scanResult) {
if (scanResult.getCriticalLicenseViolations() > 0) {
return new PolicyViolation(
"CRITICAL_LICENSE_VIOLATIONS",
SeverityLevel.CRITICAL,
"Critical license violations detected: " +
scanResult.getCriticalLicenseViolations(),
"Remove or replace dependencies with critical license violations"
);
}
return null;
}
}
/**
* Outdated dependencies policy
*/
class OutdatedDependenciesPolicy implements PolicyRule {
private static final double MAX_OUTDATED_PERCENTAGE = 0.2; // 20%
@Override
public boolean isEnabled() {
return true;
}
@Override
public PolicyViolation evaluate(ScanResult scanResult) {
DependencyHealthMetrics metrics = scanResult.getHealthMetrics();
if (metrics != null) {
double outdatedPercentage = (double) metrics.getOutdatedCount() /
scanResult.getDependencies().size();
if (outdatedPercentage > MAX_OUTDATED_PERCENTAGE) {
return new PolicyViolation(
"EXCESSIVE_OUTDATED_DEPENDENCIES",
SeverityLevel.MEDIUM,
String.format("Too many outdated dependencies: %.1f%% (max: %.1f%%)",
outdatedPercentage * 100, MAX_OUTDATED_PERCENTAGE * 100),
"Update outdated dependencies to recent versions"
);
}
}
return null;
}
}
/**
* Policy check result
*/
public class PolicyCheckResult {
private final List<PolicyViolation> violations;
private boolean compliant;
public PolicyCheckResult() {
this.violations = new ArrayList<>();
this.compliant = true;
}
public void addViolation(PolicyViolation violation) {
this.violations.add(violation);
this.compliant = false;
}
// Getters
public List<PolicyViolation> getViolations() { return Collections.unmodifiableList(violations); }
public boolean isCompliant() { return compliant; }
public void setCompliant(boolean compliant) { this.compliant = compliant; }
}
/**
* Policy violation representation
*/
public class PolicyViolation {
private final String ruleId;
private final SeverityLevel severity;
private final String description;
private final String remediation;
public PolicyViolation(String ruleId, SeverityLevel severity,
String description, String remediation) {
this.ruleId = ruleId;
this.severity = severity;
this.description = description;
this.remediation = remediation;
}
// Getters
public String getRuleId() { return ruleId; }
public SeverityLevel getSeverity() { return severity; }
public String getDescription() { return description; }
public String getRemediation() { return remediation; }
}
/**
* Risk assessment calculator
*/
public class RiskCalculator {
public RiskAssessment assessRisk(ScanResult scanResult) {
RiskAssessment assessment = new RiskAssessment();
// Calculate vulnerability risk
double vulnerabilityRisk = calculateVulnerabilityRisk(scanResult);
assessment.setVulnerabilityRisk(vulnerabilityRisk);
// Calculate license risk
double licenseRisk = calculateLicenseRisk(scanResult);
assessment.setLicenseRisk(licenseRisk);
// Calculate dependency health risk
double healthRisk = calculateHealthRisk(scanResult);
assessment.setHealthRisk(healthRisk);
// Calculate overall risk
double overallRisk = calculateOverallRisk(vulnerabilityRisk, licenseRisk, healthRisk);
assessment.setOverallRisk(overallRisk);
assessment.setRiskLevel(determineRiskLevel(overallRisk));
return assessment;
}
private double calculateVulnerabilityRisk(ScanResult scanResult) {
double risk = 0.0;
risk += scanResult.getCriticalVulnerabilities() * 10.0;
risk += scanResult.getHighVulnerabilities() * 5.0;
risk += scanResult.getMediumVulnerabilities() * 2.0;
risk += scanResult.getLowVulnerabilities() * 0.5;
// Normalize based on total dependencies
int totalDeps = scanResult.getDependencies().size();
if (totalDeps > 0) {
risk = (risk / totalDeps) * 10.0; // Scale to 0-10
}
return Math.min(risk, 10.0);
}
private double calculateLicenseRisk(ScanResult scanResult) {
double risk = 0.0;
risk += scanResult.getCriticalLicenseViolations() * 8.0;
risk += (scanResult.getTotalLicenseViolations() -
scanResult.getCriticalLicenseViolations()) * 3.0;
return Math.min(risk, 10.0);
}
private double calculateHealthRisk(ScanResult scanResult) {
DependencyHealthMetrics metrics = scanResult.getHealthMetrics();
if (metrics == null) return 0.0;
double risk = 0.0;
risk += metrics.getOutdatedCount() * 0.5;
risk += metrics.getUnmaintainedCount() * 2.0;
// Average age factor
if (metrics.getAverageAgeInMonths() > 24) {
risk += 3.0;
} else if (metrics.getAverageAgeInMonths() > 12) {
risk += 1.5;
}
return Math.min(risk, 10.0);
}
private double calculateOverallRisk(double vulnRisk, double licenseRisk, double healthRisk) {
// Weighted average based on importance
return (vulnRisk * 0.6) + (licenseRisk * 0.3) + (healthRisk * 0.1);
}
private RiskLevel determineRiskLevel(double riskScore) {
if (riskScore >= 7.5) return RiskLevel.HIGH;
if (riskScore >= 5.0) return RiskLevel.MEDIUM;
if (riskScore >= 2.5) return RiskLevel.LOW;
return RiskLevel.NONE;
}
}
/**
* Risk assessment result
*/
public class RiskAssessment {
private double overallRisk;
private double vulnerabilityRisk;
private double licenseRisk;
private double healthRisk;
private RiskLevel riskLevel;
// Getters and setters
public double getOverallRisk() { return overallRisk; }
public void setOverallRisk(double overallRisk) { this.overallRisk = overallRisk; }
public double getVulnerabilityRisk() { return vulnerabilityRisk; }
public void setVulnerabilityRisk(double vulnerabilityRisk) { this.vulnerabilityRisk = vulnerabilityRisk; }
public double getLicenseRisk() { return licenseRisk; }
public void setLicenseRisk(double licenseRisk) { this.licenseRisk = licenseRisk; }
public double getHealthRisk() { return healthRisk; }
public void setHealthRisk(double healthRisk) { this.healthRisk = healthRisk; }
public RiskLevel getRiskLevel() { return riskLevel; }
public void setRiskLevel(RiskLevel riskLevel) { this.riskLevel = riskLevel; }
}
/**
* Dependency health metrics calculator
*/
public class DependencyHealthMetrics {
private int outdatedCount = 0;
private int unmaintainedCount = 0;
private int totalMonths = 0;
private int dependencyCount = 0;
public void analyzeDependency(Dependency dependency) {
dependencyCount++;
DependencyHealth health = dependency.getHealth();
if (health.isOutdated()) {
outdatedCount++;
}
if (health.isUnmaintained()) {
unmaintainedCount++;
}
if (health.getMonthsSinceUpdate() > 0) {
totalMonths += health.getMonthsSinceUpdate();
}
}
// Getters
public int getOutdatedCount() { return outdatedCount; }
public int getUnmaintainedCount() { return unmaintainedCount; }
public double getAverageAgeInMonths() {
return dependencyCount > 0 ? (double) totalMonths / dependencyCount : 0.0;
}
}
Configuration Management
package com.titliel.veracode;
import java.io.*;
import java.util.*;
/**
* SourceClear configuration manager
*/
public class SourceClearConfig {
private static SourceClearConfig instance;
private final Properties properties;
private SourceClearConfig() {
this.properties = loadProperties();
}
public static synchronized SourceClearConfig getInstance() {
if (instance == null) {
instance = new SourceClearConfig();
}
return instance;
}
private Properties loadProperties() {
Properties props = new Properties();
// Load from system properties first
props.putAll(System.getProperties());
// Load from configuration file
try (InputStream input = getClass().getClassLoader()
.getResourceAsStream("sourceclear.properties")) {
if (input != null) {
props.load(input);
}
} catch (Exception e) {
// Use defaults
}
// Load from environment variables
loadFromEnvironment(props);
// Set defaults for missing properties
setDefaults(props);
return props;
}
private void loadFromEnvironment(Properties props) {
// API Key
String apiKey = System.getenv("SOURCECLEAR_API_KEY");
if (apiKey != null) {
props.setProperty("sourceclear.api.key", apiKey);
}
// API URL
String apiUrl = System.getenv("SOURCECLEAR_API_URL");
if (apiUrl != null) {
props.setProperty("sourceclear.api.url", apiUrl);
}
// Organization ID
String orgId = System.getenv("SOURCECLEAR_ORG_ID");
if (orgId != null) {
props.setProperty("sourceclear.org.id", orgId);
}
}
private void setDefaults(Properties props) {
props.setProperty("sourceclear.api.url", "https://api.sourceclear.com");
props.setProperty("sourceclear.thread.count", "4");
props.setProperty("sourceclear.upload.enabled", "true");
props.setProperty("sourceclear.report.html.enabled", "true");
props.setProperty("sourceclear.report.json.enabled", "true");
props.setProperty("sourceclear.report.sarif.enabled", "true");
props.setProperty("sourceclear.report.spdx.enabled", "false");
props.setProperty("sourceclear.report.csv.enabled", "false");
props.setProperty("sourceclear.timeout.seconds", "30");
}
// Getters
public String getApiKey() {
return properties.getProperty("sourceclear.api.key");
}
public String getApiBaseUrl() {
return properties.getProperty("sourceclear.api.url", "https://api.sourceclear.com");
}
public String getOrgId() {
return properties.getProperty("sourceclear.org.id");
}
public int getThreadCount() {
return Integer.parseInt(properties.getProperty("sourceclear.thread.count", "4"));
}
public int getTimeoutSeconds() {
return Integer.parseInt(properties.getProperty("sourceclear.timeout.seconds", "30"));
}
public boolean isUploadEnabled() {
return Boolean.parseBoolean(properties.getProperty("sourceclear.upload.enabled", "true"));
}
public boolean isHtmlReportEnabled() {
return Boolean.parseBoolean(properties.getProperty("sourceclear.report.html.enabled", "true"));
}
public boolean isJsonReportEnabled() {
return Boolean.parseBoolean(properties.getProperty("sourceclear.report.json.enabled", "true"));
}
public boolean isSarifReportEnabled() {
return Boolean.parseBoolean(properties.getProperty("sourceclear.report.sarif.enabled", "true"));
}
public boolean isSpdxReportEnabled() {
return Boolean.parseBoolean(properties.getProperty("sourceclear.report.spdx.enabled", "false"));
}
public boolean isCsvReportEnabled() {
return Boolean.parseBoolean(properties.getProperty("sourceclear.report.csv.enabled", "false"));
}
public boolean isValid() {
return getApiKey() != null && !getApiKey().isEmpty();
}
public void setProperty(String key, String value) {
properties.setProperty(key, value);
}
}
/**
* Policy configuration
*/
class PolicyConfig {
private static PolicyConfig instance;
private final Properties properties;
private PolicyConfig() {
this.properties = loadProperties();
}
public static synchronized PolicyConfig getInstance() {
if (instance == null) {
instance = new PolicyConfig();
}
return instance;
}
private Properties loadProperties() {
Properties props = new Properties();
// Load policy configuration
return props;
}
}
Usage Examples
package com.titliel.examples;
import com.titliel.veracode.TitlielSourceClearScanner;
import com.titliel.veracode.ProjectContext;
import com.titliel.veracode.ScanResult;
import java.nio.file.Paths;
/**
* Example usage of Titliel SourceClear Scanner
*/
public class SourceClearScanExample {
public static void main(String[] args) {
// Create project context
ProjectContext context = new ProjectContext.Builder()
.setProjectDir(Paths.get("/path/to/your/project"))
.setProjectName("my-spring-boot-app")
.setVersion("1.0.0")
.addExclude("**/generated/**")
.addProperty("java.version", "11")
.build();
// Create scanner
TitlielSourceClearScanner scanner = new TitlielSourceClearScanner();
try {
// Perform comprehensive scan
ScanResult result = scanner.scanProject(context);
// Analyze and act on results
processScanResults(result);
} finally {
scanner.shutdown();
}
}
private static void processScanResults(ScanResult result) {
System.out.println("=== Veracode SourceClear Scan Results ===");
System.out.println("Scan Duration: " + result.getScanDuration() + "ms");
System.out.println("Total Dependencies: " + result.getDependencies().size());
System.out.println("Total Vulnerabilities: " + result.getTotalVulnerabilities());
System.out.println("Critical: " + result.getCriticalVulnerabilities());
System.out.println("High: " + result.getHighVulnerabilities());
System.out.println("License Violations: " + result.getTotalLicenseViolations());
// Risk assessment
if (result.getRiskAssessment() != null) {
System.out.println("Overall Risk: " + result.getRiskAssessment().getOverallRisk());
System.out.println("Risk Level: " + result.getRiskAssessment().getRiskLevel());
}
// Policy compliance
if (result.getPolicyResult() != null) {
System.out.println("Policy Compliant: " + result.isPolicyCompliant());
if (!result.isPolicyCompliant()) {
System.out.println("Policy Violations:");
result.getPolicyResult().getViolations().forEach(violation ->
System.out.println(" - " + violation.getDescription()));
}
}
// Critical issues check
if (result.hasCriticalIssues()) {
System.out.println("🚨 CRITICAL ISSUES DETECTED!");
// Fail build or trigger alerts
}
// Generate reports path
result.getReports().forEach((type, path) ->
System.out.println("Report generated: " + type + " -> " + path));
}
}
/**
* CI/CD Integration Example
*/
class CICDIntegration {
public boolean performSecurityGate(ProjectContext context) {
TitlielSourceClearScanner scanner = new TitlielSourceClearScanner();
try {
ScanResult result = scanner.scanProject(context);
// Check policy compliance
if (!result.isPolicyCompliant()) {
System.err.println("Build failed: Policy violations detected");
logPolicyViolations(result);
return false;
}
// Check for critical vulnerabilities
if (result.hasCriticalIssues()) {
System.err.println("Build failed: Critical security issues detected");
return false;
}
// Check risk level
if (result.getRiskAssessment() != null &&
result.getRiskAssessment().getRiskLevel() == RiskLevel.HIGH) {
System.err.println("Build failed: High risk level detected");
return false;
}
System.out.println("Security gate passed");
return true;
} finally {
scanner.shutdown();
}
}
private void logPolicyViolations(ScanResult result) {
result.getPolicyResult().getViolations().forEach(violation -> {
System.err.println("Policy Violation: " + violation.getDescription());
System.err.println(" Remediation: " + violation.getRemediation());
});
}
public void generateComplianceReport(ProjectContext context) {
TitlielSourceClearScanner scanner = new TitlielSourceClearScanner();
try {
ScanResult result = scanner.scanProject(context);
// Generate compliance reports
if (result.getReports().containsKey(ReportType.SPDX)) {
uploadSpdxReport(result.getReports().get(ReportType.SPDX));
}
// Send to security dashboard
sendToSecurityDashboard(result);
} finally {
scanner.shutdown();
}
}
private void uploadSpdxReport(Path spdxReport) {
// Upload SPDX report to compliance system
System.out.println("Uploading SPDX report: " + spdxReport);
}
private void sendToSecurityDashboard(ScanResult result) {
// Send results to security dashboard
System.out.println("Sending scan results to security dashboard");
}
}
/**
* Remediation Workflow Example
*/
class RemediationWorkflow {
public void handleVulnerabilityRemediation(ScanResult result) {
if (result.getRemediationPlan() != null) {
RemediationPlan plan = result.getRemediationPlan();
System.out.println("=== Remediation Plan ===");
System.out.println("Total actions: " + plan.getActions().size());
System.out.println("Estimated effort: " + plan.getEstimatedEffort());
// Process remediation actions
for (RemediationAction action : plan.getActions()) {
processRemediationAction(action);
}
}
}
private void processRemediationAction(RemediationAction action) {
switch (action.getType()) {
case UPDATE_DEPENDENCY:
System.out.println("Update " + action.getDependency().getCoordinates() +
" to version " + action.getTargetVersion());
break;
case REPLACE_DEPENDENCY:
System.out.println("Replace " + action.getDependency().getCoordinates() +
" with alternative");
break;
case MITIGATE_VULNERABILITY:
System.out.println("Mitigate vulnerability: " + action.getVulnerability().getId());
break;
}
}
}
Maven Dependencies
<dependencies> <!-- HTTP Client --> <dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> <version>5.2.1</version> </dependency> <!-- JSON Processing --> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20230227</version> </dependency> <!-- XML Processing --> <dependency> <groupId>javax.xml.parsers</groupId> <artifactId>jaxp-api</artifactId> <version>1.4.5</version> </dependency> <!-- File Utilities --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.11.0</version> </dependency> <!-- Logging --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.7</version> </dependency> </dependencies>
Best Practices
1. Integration Strategy
- Integrate early in SDLC
- Use in CI/CD for automated scanning
- Implement security gates
2. Policy Management
- Define clear security policies
- Implement organizational rules
- Regular policy reviews
3. Remediation Workflow
- Prioritize by severity and exploitability
- Track remediation progress
- Automate dependency updates
4. Compliance Reporting
- Generate multiple report formats
- Maintain audit trails
- Integrate with GRC systems
5. Performance Optimization
- Cache scan results
- Use incremental scanning
- Optimize API calls
This Titliel SourceClear integration provides comprehensive software composition analysis with advanced policy enforcement, risk assessment, and remediation guidance for enterprise Java applications.
Secure Java Supply Chain, Minimal Containers & Runtime Security (Alpine, Distroless, Signing, SBOM & Kubernetes Controls)
https://macronepal.com/blog/alpine-linux-security-in-java-complete-guide/
Explains how Alpine Linux is used as a lightweight base for Java containers to reduce image size and attack surface, while discussing tradeoffs like musl compatibility, CVE handling, and additional hardening requirements for production security.
https://macronepal.com/blog/the-minimalists-approach-building-ultra-secure-java-applications-with-scratch-base-images/
Explains using scratch base images for Java applications to create extremely minimal containers with almost zero attack surface, where only the compiled Java application and runtime dependencies exist.
https://macronepal.com/blog/distroless-containers-in-java-minimal-secure-containers-for-jvm-applications/
Explains distroless Java containers that remove shells, package managers, and unnecessary OS tools, significantly reducing vulnerabilities while improving security posture for JVM workloads.
https://macronepal.com/blog/revolutionizing-container-security-implementing-chainguard-images-for-java-applications/
Explains Chainguard images for Java, which are secure-by-default, CVE-minimized container images with SBOMs and cryptographic signing, designed for modern supply-chain security.
https://macronepal.com/blog/seccomp-filtering-in-java-comprehensive-security-sandboxing/
Explains seccomp syscall filtering in Linux to restrict what system calls Java applications can make, reducing the impact of exploits by limiting kernel-level access.
https://macronepal.com/blog/in-toto-attestations-in-java/
Explains in-toto framework integration in Java to create cryptographically verifiable attestations across the software supply chain, ensuring every build step is trusted and auditable.
https://macronepal.com/blog/fulcio-integration-in-java-code-signing-certificate-infrastructure/
Explains Fulcio integration for Java, which issues short-lived certificates for code signing in a zero-trust supply chain, enabling secure identity-based signing of artifacts.
https://macronepal.com/blog/tekton-supply-chain-in-java-comprehensive-ci-cd-pipeline-implementation/
Explains using Tekton CI/CD pipelines for Java applications to automate secure builds, testing, signing, and deployment with supply-chain security controls built in.
https://macronepal.com/blog/slsa-provenance-in-java-complete-guide-to-supply-chain-security-2/
Explains SLSA (Supply-chain Levels for Software Artifacts) provenance in Java builds, ensuring traceability of how software is built, from source code to final container image.
https://macronepal.com/blog/notary-project-in-java-complete-implementation-guide/
Explains the Notary Project for Java container security, enabling cryptographic signing and verification of container images and artifacts to prevent tampering in deployment pipelines.