Java: Use of HTTP/FTP to download/upload Maven artifacts

This adds a security alert for the use of HTTP or FTP to download or upload
artifacts using Maven.
This commit is contained in:
Jonathan Leitschuh
2019-11-21 13:31:06 -05:00
parent 8cca9b05ea
commit 21193bd780
4 changed files with 203 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Using an insecure protocol like HTTP or FTP to download your dependencies leaves your Maven build vulnerable to a
<a href="https://en.wikipedia.org/wiki/Man-in-the-middle_attack">Man in the Middle (MITM)</a>.
This can allow attackers to inject malicious code into the artifacts that you are resolving and infect build artifacts
that are being produced. This can be used by attackers to perform a
<a href="https://en.wikipedia.org/wiki/Supply_chain_attack">Supply chain attack</a>
against your project's users.
</p>
<p>This vulnerability has a
<a href="https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator?vector=AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H&version=3.1">
CVSS v3.1 base score of 8.1/10
</a>.</p>
</overview>
<recommendation>
<p>Always use HTTPS or SFTP to download artifacts from artifact servers.</p>
</recommendation>
<example>
<p>These examples show examples of locations in Maven POM files where artifact repository upload/download is configured.
The first shows the use of HTTP, the second shows the use of HTTPS.
</p>
<sample src="insecure-pom.xml" />
<sample src="secure-pom.xml" />
</example>
<references>
<li>
Research:
<a href="https://medium.com/bugbountywriteup/want-to-take-over-the-java-ecosystem-all-you-need-is-a-mitm-1fc329d898fb?source=friends_link&sk=3c99970c55a899ad9ef41f126efcde0e">
Want to take over the Java ecosystem? All you need is a MITM!
</a>
</li>
<li>
Research:
<a href="https://max.computer/blog/how-to-take-over-the-computer-of-any-java-or-clojure-or-scala-developer/">
How to take over the computer of any Java (or Closure or Scala) Developer.
</a>
</li>
<li>
Proof of Concept:
<a href="https://github.com/mveytsman/dilettante">
mveytsman/dilettante
</a>
</li>
<li>
Additional Gradle & Maven plugin:
<a href="https://spring.io/blog/2019/06/10/announcing-nohttp">
Announcing nohttp
</a>
</li>
<li>
Java Ecosystem Announcement:
<a href="https://gist.github.com/JLLeitschuh/789e49e3d34092a005031a0a1880af99">
HTTP Decommission Artifact Server Announcements
</a>
</li>
<!-- LocalWords: CWE maven dependencies artifact
-->
</references>
</qhelp>

View File

@@ -0,0 +1,38 @@
/**
* @name Failure to use HTTPS or SFTP URL in Maven artifact upload/download
* @description Non-HTTPS connections can be intercepted by third parties.
* @kind path-problem
* @problem.severity error
* @precision very high
* @id java/maven/non-https-url
* @tags security
* external/cwe/cwe-319
* external/cwe/cwe-494
* external/cwe/cwe-829
*/
import java
import semmle.code.xml.MavenPom
private class DeclaredRepository extends PomElement {
DeclaredRepository() {
this.getName() = "repository" or
this.getName() = "snapshotRepository" or
this.getName() = "pluginRepository"
}
string getUrl() {
result = getAChild("url").(PomElement).getValue()
}
predicate isInsecureRepositoryUsage() {
getUrl().matches("http://%") or
getUrl().matches("ftp://%")
}
}
from DeclaredRepository repository
where repository.isInsecureRepositoryUsage()
select
repository,
"Downloading or uploading artifacts over insecure protocol (eg. http or ftp) to repository " + repository.getUrl()

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.semmle</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<name>Security Testing</name>
<description>An example of insecure download and upload of dependencies</description>
<distributionManagement>
<repository>
<id>insecure-releases</id>
<name>Insecure Repository Releases</name>
<!-- BAD! Use HTTPS -->
<url>http://insecure-repository.example</url>
</repository>
<snapshotRepository>
<id>insecure-snapshots</id>
<name>Insecure Repository Snapshots</name>
<!-- BAD! Use HTTPS -->
<url>http://insecure-repository.example</url>
</snapshotRepository>
</distributionManagement>
<repositories>
<repository>
<id>insecure</id>
<name>Insecure Repository</name>
<!-- BAD! Use HTTPS -->
<url>http://insecure-repository.example</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>insecure-plugins</id>
<name>Insecure Repository Releases</name>
<!-- BAD! Use HTTPS -->
<url>http://insecure-repository.example</url>
</pluginRepository>
</pluginRepositories>
</project>

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.semmle</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<name>Security Testing</name>
<description>An example of secure download and upload of dependencies</description>
<distributionManagement>
<repository>
<id>insecure-releases</id>
<name>Secure Repository Releases</name>
<!-- GOOD! Use HTTPS -->
<url>https://insecure-repository.example</url>
</repository>
<snapshotRepository>
<id>insecure-snapshots</id>
<name>Secure Repository Snapshots</name>
<!-- GOOD! Use HTTPS -->
<url>https://insecure-repository.example</url>
</snapshotRepository>
</distributionManagement>
<repositories>
<repository>
<id>insecure</id>
<name>Secure Repository</name>
<!-- GOOD! Use HTTPS -->
<url>https://insecure-repository.example</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>insecure-plugins</id>
<name>Secure Repository Releases</name>
<!-- GOOD! Use HTTPS -->
<url>https://insecure-repository.example</url>
</pluginRepository>
</pluginRepositories>
</project>