Merge pull request #2413 from JLLeitschuh/feature/JLL/maven_insecure_artifact_resolution

Java: Use of HTTP/FTP to download/upload Maven artifacts
This commit is contained in:
Anders Schack-Mulligen
2020-01-02 14:47:30 +01:00
committed by GitHub
9 changed files with 305 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&amp;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&amp;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 &amp; 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,37 @@
/**
* @name Failure to use HTTPS or SFTP URL in Maven artifact upload/download
* @description Non-HTTPS connections can be intercepted by third parties.
* @kind problem
* @problem.severity error
* @precision very-high
* @id java/maven/non-https-url
* @tags security
* external/cwe/cwe-300
* 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/from 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>

View File

@@ -0,0 +1,2 @@
public class A {
}

View File

@@ -0,0 +1,4 @@
| insecure-pom.xml:19:9:24:22 | repository | Downloading or uploading artifacts over insecure protocol (eg. http or ftp) to/from repository http://insecure-repository.example |
| insecure-pom.xml:25:9:30:30 | snapshotRepository | Downloading or uploading artifacts over insecure protocol (eg. http or ftp) to/from repository http://insecure-repository.example |
| insecure-pom.xml:33:9:38:22 | repository | Downloading or uploading artifacts over insecure protocol (eg. http or ftp) to/from repository http://insecure-repository.example |
| insecure-pom.xml:41:9:46:28 | pluginRepository | Downloading or uploading artifacts over insecure protocol (eg. http or ftp) to/from repository http://insecure-repository.example |

View File

@@ -0,0 +1 @@
Security/CWE/CWE-829/InsecureDependencyResolution.ql

View File

@@ -0,0 +1,48 @@
<?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">
<!-- Duplicated in java/ql/src/Security/CWE/CWE-829/insecure-pom.xml -->
<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,48 @@
<?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">
<!-- Duplicated in java/ql/src/Security/CWE/CWE-829/secure-pom.xml -->
<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>