com.h3xstream.maven.victims.VictimsDbLoader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of security-versions Show documentation
Show all versions of security-versions Show documentation
Maven plugin that identify vulnerable libraries in Maven dependencies
The newest version!
package com.h3xstream.maven.victims;
import com.h3xstream.maven.VersionUtil;
import com.h3xstream.maven.http.HttpRepository;
import com.h3xstream.maven.http.WagonHttpRepository;
import org.apache.maven.artifact.manager.WagonConfigurationException;
import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.wagon.ConnectionException;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.apache.maven.wagon.UnsupportedProtocolException;
import org.apache.maven.wagon.Wagon;
import org.apache.maven.wagon.authentication.AuthenticationException;
import org.apache.maven.wagon.authorization.AuthorizationException;
import org.apache.maven.wagon.repository.Repository;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import org.yaml.snakeyaml.Yaml;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class VictimsDbLoader {
private static final String URL_ARCHIVE_FILE = "archive/master.zip";
private static final String URL_COMMITS_FILE = "commits.atom";
private Log log; //= new SystemStreamLog()
private WagonManager wagonManager;
private Map> cves;
protected HttpRepository repo;
/**
* Matching file like : victims-cve-db-master/database/java/2014/7839.yaml
*/
private static final Pattern YAML_JAVA_FILE = Pattern.compile("database/java/[\\d]+/[\\d]+.yaml");
public VictimsDbLoader(final Log log,final WagonManager wagonManager) throws WagonConfigurationException, UnsupportedProtocolException, ConnectionException, AuthenticationException {
this.log = log;
this.wagonManager = wagonManager;
if(wagonManager != null) {
this.repo = new WagonHttpRepository(log,wagonManager);
}
}
public Map> getRepository() {
return cves;
}
public void loadRepository() {
this.cves = new HashMap>();
String homeDir = System.getProperty("user.home");
File cacheDir = new File(homeDir, ".victims");
File victimsRepoFile = new File(cacheDir, "master.zip");
File versionFile = new File(cacheDir, "version.txt");
try {
//Create cache directory if nonexistent
if(!cacheDir.exists()) {
log.info("Creating victim cache directory "+cacheDir.getCanonicalPath());
cacheDir.mkdir();
}
////Loading the version (date)
log.info("Syncing with the victims repository (based on the atom feed)");
File tempAtomFeed = File.createTempFile("commits-atom", ".xml");
log.debug("Temp file: " + tempAtomFeed.getCanonicalPath());
repo.getFile(URL_COMMITS_FILE, tempAtomFeed);
////Comparing the version with the local one
String latestVersion = getLatestVersion(tempAtomFeed);
String localeVersion = getFileContent(versionFile);
log.debug(String.format("Latest version %s, Locale version %s",latestVersion,localeVersion));
if(latestVersion.equals(localeVersion)) {
log.info("Already to the latest version.");
}
else {
if(victimsRepoFile.exists()) {
log.info("Removing existing database.");
victimsRepoFile.delete();
}
if(versionFile.exists()) {
versionFile.delete();
}
log.debug("Downloading the latest repository");
repo.getFile(URL_ARCHIVE_FILE, victimsRepoFile);
//Keep the version of the downloaded file
writeVersionFile(versionFile, latestVersion);
}
//Extracting the yaml file
ZipInputStream stream = new ZipInputStream(new FileInputStream(victimsRepoFile));
for(ZipEntry entry ; (entry = stream.getNextEntry()) !=null; ) {
if(YAML_JAVA_FILE.matcher(entry.getName()).find()) {
//log.info(""+entry.getName());
List artifactIds = new ArrayList();
CveVulnerability newCve = parseCveYamlFile(stream,artifactIds);
for(String artifactId : artifactIds) {
//Get the list of CVE for the artifact or create an empty list..
List vulns = cves.get(artifactId);
if(vulns == null) {
vulns = new ArrayList();
cves.put(artifactId,vulns);
}
vulns.add(newCve);
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private CveVulnerability parseCveYamlFile(InputStream in,List outArtifact) {
Yaml yaml = new Yaml();
Map obj = (Map) yaml.load(in);
String cveId = (String) obj.get("cve");
String title = (String) obj.get("title");
String description = (String) obj.get("description");
String cvssScore = obj.get("cvss_v2") != null ? String.valueOf((Double) obj.get("cvss_v2")) : null;
List references = (List) obj.get("references");
List parsedVersions = new ArrayList(5);
List