Initial commit
This commit is contained in:
33
.gitignore
vendored
Normal file
33
.gitignore
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
*.class
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Exclude mvn-repo
|
||||
!/mvn-repo
|
||||
|
||||
# Package Files #
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
# Maven
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
|
||||
# Exclude maven wrapper
|
||||
!/.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
**/.idea
|
||||
**/out/
|
||||
**/.idea_modules/
|
||||
*.iml
|
||||
BIN
.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
BIN
.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
Binary file not shown.
1
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
1
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@@ -0,0 +1 @@
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
|
||||
34
CHANGES
Normal file
34
CHANGES
Normal file
@@ -0,0 +1,34 @@
|
||||
Changelog
|
||||
|
||||
=========
|
||||
|
||||
Version 1.0.6
|
||||
|
||||
- feature change simple-json to gson
|
||||
- feature default not include provided scope dependencies
|
||||
|
||||
Version 1.0.5
|
||||
|
||||
- feature default BUILD FAIL when found vulnerable
|
||||
|
||||
Version 1.0.4
|
||||
|
||||
- feature BUILD FAIL when found vulnerable && parameter support
|
||||
- remove endpoint and includeProvidedDependencies parameters
|
||||
|
||||
Version 1.0.3
|
||||
|
||||
- feature throw MojoFailureException when Dependency Collection Error
|
||||
|
||||
Version 1.0.2
|
||||
|
||||
- feature warning detail add title and cve
|
||||
|
||||
Version 1.0.1
|
||||
|
||||
- feature add onlyProvenance parameter
|
||||
- feature add http timeout
|
||||
|
||||
Version 1.0.0
|
||||
|
||||
- Init
|
||||
13
LICENSE
Normal file
13
LICENSE
Normal file
@@ -0,0 +1,13 @@
|
||||
Copyright 2020 momosecurity.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
90
README.md
Normal file
90
README.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# MOSEC-MAVEN-PLUGIN
|
||||
|
||||
用于检测maven项目的第三方依赖组件是否存在安全漏洞。
|
||||
|
||||
该项目是基于 [snyk-maven-plugin](https://github.com/snyk/snyk-maven-plugin.git) 的二次开发。
|
||||
|
||||
## 版本要求
|
||||
|
||||
Maven >= 3.1
|
||||
|
||||
## 安装
|
||||
|
||||
#### 从github安装至本地仓库
|
||||
|
||||
```shell script
|
||||
> mvn dependency:get \
|
||||
-Dartifact=com.immomo.momosec:mosec-maven-plugin:1.6 \
|
||||
-DremoteRepositories=gh::::https://raw.github.com/momosecurity/mosec-maven-plugin/master/mvn-repo/
|
||||
```
|
||||
|
||||
## 使用
|
||||
|
||||
首先运行 [MOSEC-X-PLUGIN Backend](https://github.com/momosecurity/mosec-x-plugin-backend.git)
|
||||
|
||||
#### 命令行使用
|
||||
```
|
||||
> cd your_maven_project_dir/
|
||||
> MOSEC_ENDPOINT=http://127.0.0.1:9000/api/plugin \
|
||||
mvn com.immomo.momosec:mosec-maven-plugin:1.6:test \
|
||||
-DonlyProvenance=true
|
||||
|
||||
# .m2/settings.xml 中增加如下配置,可简化使用命令
|
||||
--------------------------------
|
||||
<!-- .m2/settings.xml -->
|
||||
|
||||
<pluginGroups>
|
||||
<pluginGroup>com.immomo.momosec</pluginGroup>
|
||||
</pluginGroups>
|
||||
--------------------------------
|
||||
> MOSEC_ENDPOINT=http://127.0.0.1:9000/api/plugin \
|
||||
mvn mosec:test -DonlyProvenance=true
|
||||
```
|
||||
|
||||
#### 项目中使用
|
||||
|
||||
```xml
|
||||
<!-- pom.xml -->
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.immomo.momosec</groupId>
|
||||
<artifactId>mosec-maven-plugin</artifactId>
|
||||
<version>1.0.6</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>test</id>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<endpoint>http://127.0.0.1:9000/api/plugin</endpoint>
|
||||
<severityLevel>High</severityLevel>
|
||||
<onlyProvenance>true</onlyProvenance>
|
||||
<failOnVuln>true</failOnVuln>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
```
|
||||
|
||||
## 开发
|
||||
|
||||
#### Intellij 远程调试 Maven 插件
|
||||
|
||||
1.将mosec-maven-plugin安装至本地仓库
|
||||
|
||||
2.git clone mosec-maven-plugin
|
||||
|
||||
3.Intellij 中新建 Remote Configuration 并填入如下信息
|
||||
|
||||

|
||||
|
||||
4.在另一个maven工程中执行如下命令
|
||||
|
||||
```shell script
|
||||
> mvnDebug com.immomo.momosec:mosec-maven-plugin:1.0.6:test
|
||||
```
|
||||
|
||||
5.回到Intellij中,下断点,开始Debug
|
||||
10
mvn-repo/com/immomo/momosec/maven-metadata.xml
Normal file
10
mvn-repo/com/immomo/momosec/maven-metadata.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<name>Mosec Maven Plugin</name>
|
||||
<prefix>mosec</prefix>
|
||||
<artifactId>mosec-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</metadata>
|
||||
1
mvn-repo/com/immomo/momosec/maven-metadata.xml.md5
Normal file
1
mvn-repo/com/immomo/momosec/maven-metadata.xml.md5
Normal file
@@ -0,0 +1 @@
|
||||
eca404dcb7ed57c74cd03e4906579146
|
||||
1
mvn-repo/com/immomo/momosec/maven-metadata.xml.sha1
Normal file
1
mvn-repo/com/immomo/momosec/maven-metadata.xml.sha1
Normal file
@@ -0,0 +1 @@
|
||||
3987d2c89456b348a2cc02b689376c4234a8b177
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
5ccc316f287eca445a26116263f53660
|
||||
@@ -0,0 +1 @@
|
||||
adc663bf033dbba5fb9303030a9ef57f7514ac23
|
||||
@@ -0,0 +1,124 @@
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<prerequisites>
|
||||
<maven>3.1.0</maven>
|
||||
</prerequisites>
|
||||
|
||||
<groupId>com.immomo.momosec</groupId>
|
||||
<artifactId>mosec-maven-plugin</artifactId>
|
||||
<version>1.0.6</version>
|
||||
<packaging>maven-plugin</packaging>
|
||||
|
||||
<name>Mosec Maven Plugin</name>
|
||||
<description>用于检测Maven项目的第三方依赖组件是否存在安全漏洞</description>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>zhang.liang_2745</name>
|
||||
<email>zhang.liang_2745@immomo.com</email>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<mavenVersion>3.3.9</mavenVersion>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-core</artifactId>
|
||||
<version>${mavenVersion}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugin-tools</groupId>
|
||||
<artifactId>maven-plugin-annotations</artifactId>
|
||||
<version>3.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.10</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugin-testing</groupId>
|
||||
<artifactId>maven-plugin-testing-harness</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>2.28.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-compat</artifactId>
|
||||
<version>3.3.9</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-plugin-plugin</artifactId>
|
||||
<version>3.5</version>
|
||||
<configuration>
|
||||
<goalPrefix>mosec</goalPrefix>
|
||||
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>mojo-descriptor</id>
|
||||
<goals>
|
||||
<goal>descriptor</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>help-goal</id>
|
||||
<goals>
|
||||
<goal>helpmojo</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.6.2</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<compilerArgument>-Xlint</compilerArgument>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>internal</id>
|
||||
<url>file://mvn-repo</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</project>
|
||||
@@ -0,0 +1 @@
|
||||
7c8c6f5b65742333e243d1f3d4202c04
|
||||
@@ -0,0 +1 @@
|
||||
1ba8971379c6640a2c4ff44e5c7271ce478e6d5a
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<groupId>com.immomo.momosec</groupId>
|
||||
<artifactId>mosec-maven-plugin</artifactId>
|
||||
<versioning>
|
||||
<latest>1.0.6</latest>
|
||||
<release>1.0.6</release>
|
||||
<versions>
|
||||
<version>1.0.6</version>
|
||||
</versions>
|
||||
<lastUpdated>20200728032456</lastUpdated>
|
||||
</versioning>
|
||||
</metadata>
|
||||
@@ -0,0 +1 @@
|
||||
93455bf88c3f9e99f4750e2911e008fb
|
||||
@@ -0,0 +1 @@
|
||||
d708fc9ffdb8f4ce006ca96cb40a72a7a09845f8
|
||||
286
mvnw
vendored
Executable file
286
mvnw
vendored
Executable file
@@ -0,0 +1,286 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven2 Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
export JAVA_HOME="`/usr/libexec/java_home`"
|
||||
else
|
||||
export JAVA_HOME="/Library/Java/Home"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=`java-config --jre-home`
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ] ; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="`dirname "$PRG"`/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=`pwd`
|
||||
|
||||
M2_HOME=`dirname "$PRG"`/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||
# TODO classpath?
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="`which javac`"
|
||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=`which readlink`
|
||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||
else
|
||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||
fi
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="`which java`"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=`cd "$wdir/.."; pwd`
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' < "$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||
fi
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||
fi
|
||||
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
|
||||
while IFS="=" read key value; do
|
||||
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
||||
esac
|
||||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Downloading from: $jarUrl"
|
||||
fi
|
||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
|
||||
if command -v wget > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found wget ... using wget"
|
||||
fi
|
||||
wget "$jarUrl" -O "$wrapperJarPath"
|
||||
elif command -v curl > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found curl ... using curl"
|
||||
fi
|
||||
curl -o "$wrapperJarPath" "$jarUrl"
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Falling back to using Java to download"
|
||||
fi
|
||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
if [ -e "$javaClass" ]; then
|
||||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
# Compiling the Java class
|
||||
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||
fi
|
||||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
# Running the downloader
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Running MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo $MAVEN_PROJECTBASEDIR
|
||||
fi
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||
fi
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
||||
161
mvnw.cmd
vendored
Executable file
161
mvnw.cmd
vendored
Executable file
@@ -0,0 +1,161 @@
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven2 Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
|
||||
FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
|
||||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
echo Found %WRAPPER_JAR%
|
||||
) else (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %DOWNLOAD_URL%
|
||||
powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||
|
||||
exit /B %ERROR_CODE%
|
||||
118
pom.xml
Normal file
118
pom.xml
Normal file
@@ -0,0 +1,118 @@
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<prerequisites>
|
||||
<maven>3.1.0</maven>
|
||||
</prerequisites>
|
||||
|
||||
<groupId>com.immomo.momosec</groupId>
|
||||
<artifactId>mosec-maven-plugin</artifactId>
|
||||
<version>1.0.6</version>
|
||||
<packaging>maven-plugin</packaging>
|
||||
|
||||
<name>Mosec Maven Plugin</name>
|
||||
<description>用于检测Maven项目的第三方依赖组件是否存在安全漏洞</description>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>retanoj</name>
|
||||
<email>mmsrc@immomo.com</email>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<mavenVersion>3.3.9</mavenVersion>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-core</artifactId>
|
||||
<version>${mavenVersion}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugin-tools</groupId>
|
||||
<artifactId>maven-plugin-annotations</artifactId>
|
||||
<version>3.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.10</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugin-testing</groupId>
|
||||
<artifactId>maven-plugin-testing-harness</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>2.28.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-compat</artifactId>
|
||||
<version>3.3.9</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-plugin-plugin</artifactId>
|
||||
<version>3.5</version>
|
||||
<configuration>
|
||||
<goalPrefix>mosec</goalPrefix>
|
||||
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>mojo-descriptor</id>
|
||||
<goals>
|
||||
<goal>descriptor</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>help-goal</id>
|
||||
<goals>
|
||||
<goal>helpmojo</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.6.2</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<compilerArgument>-Xlint</compilerArgument>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.immomo.momosec.maven.plugins;
|
||||
|
||||
public class Constants {
|
||||
|
||||
public static final String ERROR_GENERAL = "There was a problem with the Mosec plugin.";
|
||||
|
||||
public static final String ERROR_RERUN_WITH_DEBUG = "Re-run Maven using the -X switch to enable full debug logging.";
|
||||
|
||||
public static final String ERROR_ON_VULNERABLE = "Dependency Vulnerable Found!";
|
||||
|
||||
public static final String ERROR_ON_API = "API return data format error.";
|
||||
|
||||
public static final String ERROR_ON_NULL_ENDPOINT = "API endpoint not setting. Setting by <endpoint></endpoint> or MOSEC_ENDPOINT env.";
|
||||
|
||||
public static final String CONTENT_TYPE_JSON = "application/json";
|
||||
|
||||
public static final String PROJECT_LANGUAGE = "java";
|
||||
|
||||
public static final String BUILD_TOOL_TYPE = "Maven";
|
||||
|
||||
public static final String MOSEC_ENDPOINT_ENV = "MOSEC_ENDPOINT";
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.immomo.momosec.maven.plugins;
|
||||
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.CredentialsProvider;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.LaxRedirectStrategy;
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
import org.apache.maven.settings.Proxy;
|
||||
import org.apache.maven.settings.Settings;
|
||||
|
||||
/**
|
||||
* Helper that builds a {@link HttpClient}, setting up a proxy server, if one is present in ~/.m2/settings.xml
|
||||
*/
|
||||
public class HttpClientHelper {
|
||||
|
||||
private final Log log;
|
||||
private final Settings settings;
|
||||
private final int timeout = 15 * 1000;
|
||||
|
||||
public HttpClientHelper(Log log, Settings settings) {
|
||||
this.log = log;
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public HttpClient buildHttpClient() {
|
||||
RequestConfig config = RequestConfig.custom()
|
||||
.setConnectTimeout(timeout)
|
||||
.setConnectionRequestTimeout(timeout)
|
||||
.setSocketTimeout(timeout)
|
||||
.build();
|
||||
|
||||
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create()
|
||||
.setDefaultRequestConfig(config)
|
||||
.setRedirectStrategy(new LaxRedirectStrategy())
|
||||
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
|
||||
return addProxy(httpClientBuilder)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds first active proxy server from ~/.m2/settings.xml, if present,
|
||||
* that will be passed to <code>HttpClientBuilder</code> used by <code>HttpClient</code>
|
||||
*
|
||||
* @param builder {@link HttpClientBuilder}
|
||||
*/
|
||||
private HttpClientBuilder addProxy(HttpClientBuilder builder) {
|
||||
Proxy settingsProxy = settings.getActiveProxy();
|
||||
if (settingsProxy != null) {
|
||||
getLog().debug("proxy server present, trying to set the first active one");
|
||||
final String proxyHost = settingsProxy.getHost();
|
||||
final int proxyPort = settingsProxy.getPort();
|
||||
final String proxyUsername = settingsProxy.getUsername();
|
||||
final String proxyPassword = settingsProxy.getPassword();
|
||||
|
||||
if (proxyHost != null && !proxyHost.isEmpty()) {
|
||||
getLog().debug("Using proxy=" + proxyHost + " with port=" + proxyPort + ".");
|
||||
|
||||
final HttpHost proxy = new HttpHost(proxyHost, proxyPort);
|
||||
builder.setProxy(proxy);
|
||||
prepareCredentials(builder, proxyUsername, proxyPassword);
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private void prepareCredentials(HttpClientBuilder builder,
|
||||
String proxyUsername,
|
||||
String proxyPassword) {
|
||||
if (proxyUsername != null && !proxyUsername.isEmpty()) {
|
||||
getLog().debug("Using proxy user name=" + proxyUsername + ".");
|
||||
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
|
||||
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(proxyUsername, proxyPassword));
|
||||
builder.setDefaultCredentialsProvider(credentialsProvider);
|
||||
}
|
||||
}
|
||||
|
||||
private Log getLog() {
|
||||
return log;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.immomo.momosec.maven.plugins;
|
||||
|
||||
public class MosecLogHelper {
|
||||
private static final String YELLOW = "\033[1;33m";
|
||||
private static final String LIGHT_RED = "\033[1;31m";
|
||||
private static final String LIGHT_GREEN = "\033[1;32m";
|
||||
|
||||
private static final String CANCEL_COLOR = "\033[0m";
|
||||
|
||||
public String strongWarning(String content) {
|
||||
return YELLOW + content + CANCEL_COLOR;
|
||||
}
|
||||
|
||||
public String strongError(String content) {
|
||||
return LIGHT_RED + content + CANCEL_COLOR;
|
||||
}
|
||||
|
||||
public String strongInfo(String content) {
|
||||
return LIGHT_GREEN + content + CANCEL_COLOR;
|
||||
}
|
||||
}
|
||||
149
src/main/java/com/immomo/momosec/maven/plugins/MosecTest.java
Normal file
149
src/main/java/com/immomo/momosec/maven/plugins/MosecTest.java
Normal file
@@ -0,0 +1,149 @@
|
||||
package com.immomo.momosec.maven.plugins;
|
||||
|
||||
import com.google.gson.*;
|
||||
import com.immomo.momosec.maven.plugins.exceptions.NetworkErrorException;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
import org.apache.maven.plugins.annotations.Component;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.apache.maven.settings.Settings;
|
||||
import org.eclipse.aether.RepositorySystem;
|
||||
import org.eclipse.aether.RepositorySystemSession;
|
||||
import org.eclipse.aether.collection.DependencyCollectionException;
|
||||
import org.eclipse.aether.repository.RemoteRepository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Mojo(name = "test")
|
||||
public class MosecTest extends AbstractMojo {
|
||||
|
||||
@Component
|
||||
private RepositorySystem repositorySystem;
|
||||
|
||||
@Parameter(property = "project", required = true, readonly = true)
|
||||
private MavenProject project;
|
||||
|
||||
@Parameter(defaultValue = "${repositorySystemSession}", readonly = true)
|
||||
private RepositorySystemSession repositorySystemSession;
|
||||
|
||||
@Parameter(defaultValue = "${project.remoteProjectRepositories}", readonly = true)
|
||||
private List<RemoteRepository> remoteProjectRepositories;
|
||||
|
||||
@Parameter(defaultValue = "${project.remotePluginRepositories}", readonly = true)
|
||||
private List<RemoteRepository> remotePluginRepositories;
|
||||
|
||||
@Parameter(defaultValue = "${settings}", readonly = true, required = true )
|
||||
private Settings settings;
|
||||
|
||||
/**
|
||||
* 威胁等级 [High|Medium|Low]
|
||||
*/
|
||||
@Parameter(property = "severity", defaultValue = "High")
|
||||
private String severityLevel;
|
||||
|
||||
/**
|
||||
* 仅检查直接依赖
|
||||
*/
|
||||
@Parameter(property = "onlyProvenance", defaultValue = "false")
|
||||
private Boolean onlyProvenance;
|
||||
|
||||
/**
|
||||
* 发现漏洞即编译失败
|
||||
*/
|
||||
@Parameter(property = "failOnVuln", defaultValue = "true")
|
||||
private Boolean failOnVuln;
|
||||
|
||||
/**
|
||||
* 上报API
|
||||
*/
|
||||
@Parameter(property = "endpoint")
|
||||
private String endpoint;
|
||||
|
||||
/**
|
||||
* 是否包含Provided Scope依赖
|
||||
*/
|
||||
@Parameter(property = "includeProvidedDependency", defaultValue = "false")
|
||||
private Boolean includeProvidedDependency;
|
||||
|
||||
public void execute() throws MojoFailureException {
|
||||
String env_endpoint = System.getenv(Constants.MOSEC_ENDPOINT_ENV);
|
||||
if (env_endpoint != null) {
|
||||
endpoint = env_endpoint;
|
||||
}
|
||||
|
||||
if (endpoint == null) {
|
||||
throw new MojoFailureException(Constants.ERROR_ON_NULL_ENDPOINT);
|
||||
}
|
||||
|
||||
if (remoteProjectRepositories == null) {
|
||||
remoteProjectRepositories = new ArrayList<>();
|
||||
}
|
||||
|
||||
if (remotePluginRepositories == null) {
|
||||
remotePluginRepositories = new ArrayList<>();
|
||||
}
|
||||
|
||||
try {
|
||||
for (RemoteRepository remoteProjectRepository : remoteProjectRepositories) {
|
||||
getLog().debug("Remote project repository: " + remoteProjectRepository);
|
||||
}
|
||||
for (RemoteRepository remotePluginRepository : remotePluginRepositories) {
|
||||
getLog().debug("Remote plugin repository: " + remotePluginRepository);
|
||||
}
|
||||
List<RemoteRepository> remoteRepositories = new ArrayList<>(remoteProjectRepositories);
|
||||
remoteRepositories.addAll(remotePluginRepositories);
|
||||
|
||||
ProjectDependencyCollector collector = new ProjectDependencyCollector(
|
||||
project,
|
||||
repositorySystem,
|
||||
repositorySystemSession,
|
||||
remoteRepositories,
|
||||
includeProvidedDependency,
|
||||
onlyProvenance
|
||||
);
|
||||
collector.collectDependencies();
|
||||
JsonObject projectTree = collector.getTree();
|
||||
|
||||
projectTree.addProperty("type", Constants.BUILD_TOOL_TYPE);
|
||||
projectTree.addProperty("language", Constants.PROJECT_LANGUAGE);
|
||||
projectTree.addProperty("severityLevel", severityLevel);
|
||||
getLog().debug(new GsonBuilder().setPrettyPrinting().create().toJson(projectTree));
|
||||
|
||||
HttpPost request = new HttpPost(endpoint);
|
||||
request.addHeader("content-type", Constants.CONTENT_TYPE_JSON);
|
||||
HttpEntity entity = new StringEntity(projectTree.toString());
|
||||
request.setEntity(entity);
|
||||
|
||||
HttpClientHelper httpClientHelper = new HttpClientHelper(getLog(), settings);
|
||||
HttpClient client = httpClientHelper.buildHttpClient();
|
||||
HttpResponse response = client.execute(request);
|
||||
|
||||
if (response.getStatusLine().getStatusCode() >= 400) {
|
||||
throw new NetworkErrorException(response.getStatusLine().getReasonPhrase());
|
||||
}
|
||||
|
||||
Renderer renderer = new Renderer(getLog(), failOnVuln);
|
||||
renderer.renderResponse(response.getEntity().getContent());
|
||||
|
||||
} catch (DependencyCollectionException e) {
|
||||
throw new MojoFailureException(e.getMessage());
|
||||
} catch(MojoFailureException e) {
|
||||
throw e;
|
||||
} catch(Exception e) {
|
||||
if (getLog().isDebugEnabled()) {
|
||||
getLog().error(Constants.ERROR_GENERAL, e);
|
||||
} else {
|
||||
getLog().error(Constants.ERROR_GENERAL);
|
||||
getLog().error(Constants.ERROR_RERUN_WITH_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.immomo.momosec.maven.plugins;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.eclipse.aether.DefaultRepositorySystemSession;
|
||||
import org.eclipse.aether.RepositorySystem;
|
||||
import org.eclipse.aether.RepositorySystemSession;
|
||||
import org.eclipse.aether.artifact.Artifact;
|
||||
import org.eclipse.aether.artifact.DefaultArtifact;
|
||||
import org.eclipse.aether.collection.CollectRequest;
|
||||
import org.eclipse.aether.collection.CollectResult;
|
||||
import org.eclipse.aether.collection.DependencyCollectionException;
|
||||
import org.eclipse.aether.graph.Dependency;
|
||||
import org.eclipse.aether.graph.DependencyNode;
|
||||
import org.eclipse.aether.repository.RemoteRepository;
|
||||
import org.eclipse.aether.util.artifact.JavaScopes;
|
||||
import org.eclipse.aether.util.graph.selector.AndDependencySelector;
|
||||
import org.eclipse.aether.util.graph.selector.OptionalDependencySelector;
|
||||
import org.eclipse.aether.util.graph.selector.ScopeDependencySelector;
|
||||
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
public class ProjectDependencyCollector {
|
||||
|
||||
private final MavenProject project;
|
||||
private final RepositorySystem repoSystem;
|
||||
private final DefaultRepositorySystemSession session;
|
||||
private final List<RemoteRepository> remoteRepositories;
|
||||
private final boolean includeProvidedDependencies;
|
||||
private final boolean onlyProvenance;
|
||||
|
||||
private JsonObject tree;
|
||||
|
||||
public ProjectDependencyCollector(MavenProject project,
|
||||
RepositorySystem repoSystem,
|
||||
RepositorySystemSession repoSession,
|
||||
List<RemoteRepository> remoteRepositories,
|
||||
boolean includeProvidedDependencies,
|
||||
boolean onlyProvenance) {
|
||||
if(project == null || repoSystem == null || repoSession == null) {
|
||||
throw new InvalidParameterException();
|
||||
}
|
||||
|
||||
this.project = project;
|
||||
this.repoSystem = repoSystem;
|
||||
this.session = new DefaultRepositorySystemSession(repoSession);
|
||||
this.remoteRepositories = remoteRepositories;
|
||||
this.includeProvidedDependencies = includeProvidedDependencies;
|
||||
this.onlyProvenance = onlyProvenance;
|
||||
}
|
||||
|
||||
public void collectDependencies() throws DependencyCollectionException {
|
||||
Artifact artifact = new DefaultArtifact(
|
||||
String.format("%s:%s:%s", project.getGroupId(), project.getArtifactId(), project.getVersion()));
|
||||
|
||||
if (includeProvidedDependencies) {
|
||||
session.setDependencySelector(
|
||||
new AndDependencySelector(
|
||||
new ScopeDependencySelector(
|
||||
asList(JavaScopes.COMPILE, JavaScopes.PROVIDED),
|
||||
singletonList(JavaScopes.TEST)
|
||||
),
|
||||
new OptionalDependencySelector()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
CollectRequest collectRequest = new CollectRequest();
|
||||
collectRequest.setRoot(new Dependency(artifact, JavaScopes.COMPILE));
|
||||
collectRequest.setRepositories(remoteRepositories);
|
||||
|
||||
CollectResult collectResult = repoSystem.collectDependencies(session, collectRequest);
|
||||
DependencyNode node = collectResult.getRoot();
|
||||
|
||||
this.tree = createJsonTree(node, null);
|
||||
}
|
||||
|
||||
private JsonObject createJsonTree(DependencyNode depNode, JsonArray ancestors) {
|
||||
Artifact artifact = depNode.getArtifact();
|
||||
JsonObject treeNode = createTreeNode(artifact, ancestors);
|
||||
|
||||
if (this.onlyProvenance && treeNode.get("from").getAsJsonArray().size() > 1) {
|
||||
if (Boolean.FALSE.equals(treeNode.has("dependencies"))) {
|
||||
treeNode.add("dependencies", new JsonObject());
|
||||
}
|
||||
return treeNode;
|
||||
}
|
||||
|
||||
List<DependencyNode> children = depNode.getChildren();
|
||||
JsonObject dependencies = new JsonObject();
|
||||
for(DependencyNode childDep : children) {
|
||||
Artifact childArtifact = childDep.getArtifact();
|
||||
JsonObject childNode = createJsonTree(childDep, treeNode.get("from").getAsJsonArray());
|
||||
dependencies.add(String.format("%s:%s", childArtifact.getGroupId(), childArtifact.getArtifactId()), childNode);
|
||||
}
|
||||
treeNode.add("dependencies", dependencies);
|
||||
|
||||
return treeNode;
|
||||
}
|
||||
|
||||
private JsonObject createTreeNode(Artifact artifact, JsonArray ancestors) {
|
||||
JsonObject treeNode = new JsonObject();
|
||||
|
||||
treeNode.addProperty("version", artifact.getVersion());
|
||||
treeNode.addProperty("name", String.format("%s:%s", artifact.getGroupId(), artifact.getArtifactId()));
|
||||
|
||||
JsonArray from = new JsonArray();
|
||||
if(ancestors != null) {
|
||||
from.addAll(ancestors);
|
||||
}
|
||||
from.add(String.format("%s:%s@%s", artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion()));
|
||||
treeNode.add("from", from);
|
||||
|
||||
return treeNode;
|
||||
}
|
||||
|
||||
public JsonObject getTree() { return this.tree; }
|
||||
}
|
||||
78
src/main/java/com/immomo/momosec/maven/plugins/Renderer.java
Normal file
78
src/main/java/com/immomo/momosec/maven/plugins/Renderer.java
Normal file
@@ -0,0 +1,78 @@
|
||||
package com.immomo.momosec.maven.plugins;
|
||||
|
||||
import com.google.gson.*;
|
||||
import com.immomo.momosec.maven.plugins.exceptions.FoundVulnerableException;
|
||||
import com.immomo.momosec.maven.plugins.exceptions.NetworkErrorException;
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
public class Renderer {
|
||||
|
||||
private final MosecLogHelper logHelper = new MosecLogHelper();
|
||||
|
||||
private final Log log;
|
||||
private final Boolean failOnVuln;
|
||||
|
||||
public Renderer(Log log, Boolean failOnVuln) {
|
||||
this.log = log;
|
||||
this.failOnVuln = failOnVuln;
|
||||
}
|
||||
|
||||
public void renderResponse(InputStream in) throws NetworkErrorException, FoundVulnerableException {
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject responseJson;
|
||||
try {
|
||||
responseJson = parser.parse(new BufferedReader(new InputStreamReader(in))).getAsJsonObject();
|
||||
} catch (JsonParseException | IllegalStateException e) {
|
||||
throw new NetworkErrorException(Constants.ERROR_ON_API);
|
||||
}
|
||||
|
||||
if(responseJson.get("ok") != null && responseJson.get("ok").getAsBoolean()) {
|
||||
String ok = "✓ Tested %s dependencies, no vulnerable found.";
|
||||
getLog().info(logHelper.strongInfo(String.format(ok, responseJson.get("dependencyCount").getAsString())));
|
||||
} else if (responseJson.get("vulnerabilities") != null) {
|
||||
JsonArray vulns = responseJson.get("vulnerabilities").getAsJsonArray();
|
||||
|
||||
for (JsonElement vuln : vulns) {
|
||||
printSingleVuln(vuln.getAsJsonObject());
|
||||
}
|
||||
|
||||
String fail = "Tested %s dependencies, found %d vulnerable pathes.";
|
||||
getLog().warn(logHelper.strongWarning(String.format(fail, responseJson.get("dependencyCount").getAsString(), vulns.size())));
|
||||
if (failOnVuln) {
|
||||
throw new FoundVulnerableException(Constants.ERROR_ON_VULNERABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void printSingleVuln(JsonObject vuln) {
|
||||
String vuln_warn = "✗ %s severity (%s - %s) found on %s@%s";
|
||||
getLog().warn(logHelper.strongError(String.format(vuln_warn,
|
||||
vuln.get("severity").getAsString(),
|
||||
vuln.get("title").getAsString(),
|
||||
vuln.get("cve").getAsString(),
|
||||
vuln.get("packageName").getAsString(),
|
||||
vuln.get("version").getAsString()
|
||||
)));
|
||||
if(vuln.get("from") != null) {
|
||||
JsonArray fromArr = vuln.get("from").getAsJsonArray();
|
||||
StringBuilder fromStrb = new StringBuilder();
|
||||
for(int i = 0; i < fromArr.size(); i++) {
|
||||
fromStrb.append(fromArr.get(i).getAsString());
|
||||
fromStrb.append(" > ");
|
||||
}
|
||||
getLog().warn(String.format("- Path: %s" ,fromStrb.substring(0, fromStrb.length() - 3)));
|
||||
}
|
||||
if (vuln.get("target_version").getAsJsonArray().size() >= 0) {
|
||||
getLog().warn(logHelper.strongInfo(String.format("! Fix version %s", vuln.get("target_version").getAsJsonArray())));
|
||||
}
|
||||
getLog().warn("");
|
||||
}
|
||||
|
||||
private Log getLog() {
|
||||
return log;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.immomo.momosec.maven.plugins.exceptions;
|
||||
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
|
||||
public class FoundVulnerableException extends MojoFailureException {
|
||||
|
||||
public FoundVulnerableException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.immomo.momosec.maven.plugins.exceptions;
|
||||
|
||||
import org.apache.maven.plugin.AbstractMojoExecutionException;
|
||||
|
||||
public class NetworkErrorException extends AbstractMojoExecutionException {
|
||||
|
||||
public NetworkErrorException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.immomo.momosec.maven.plugins;
|
||||
|
||||
import org.apache.maven.plugin.testing.MojoRule;
|
||||
import org.apache.maven.plugin.testing.resources.TestResources;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class TestMosecTest {
|
||||
|
||||
@Rule
|
||||
public MojoRule rule = new MojoRule();
|
||||
|
||||
@Rule
|
||||
public TestResources resources = new TestResources("src/test/resources/projects", "target/test-projects");
|
||||
|
||||
@Rule
|
||||
@SuppressWarnings(value = {"deprecation"})
|
||||
public ExpectedException exceptionRule = ExpectedException.none();
|
||||
|
||||
|
||||
@Test
|
||||
public void invalidProjectTest() throws Exception {
|
||||
File projectCopy = this.resources.getBasedir("empty-dir");
|
||||
File pom = new File(projectCopy, "pom.xml");
|
||||
Assert.assertNotNull(pom);
|
||||
Assert.assertFalse(pom.exists());
|
||||
|
||||
exceptionRule.expect(java.io.FileNotFoundException.class);
|
||||
exceptionRule.expectMessage("(No such file or directory)");
|
||||
|
||||
this.rule.lookupMojo("test", pom.getCanonicalPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validProjectTest() throws Exception {
|
||||
File projectCopy = this.resources.getBasedir("valid-project");
|
||||
File pom = new File(projectCopy, "pom.xml");
|
||||
|
||||
Assert.assertNotNull(pom);
|
||||
Assert.assertTrue(pom.exists());
|
||||
|
||||
MosecTest mosecTest = (MosecTest)this.rule.lookupMojo("test", pom);
|
||||
Assert.assertNotNull(mosecTest);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.immomo.momosec.maven.plugins;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.eclipse.aether.DefaultRepositorySystemSession;
|
||||
import org.eclipse.aether.RepositorySystem;
|
||||
import org.eclipse.aether.artifact.Artifact;
|
||||
import org.eclipse.aether.artifact.DefaultArtifact;
|
||||
import org.eclipse.aether.graph.DefaultDependencyNode;
|
||||
import org.eclipse.aether.graph.DependencyNode;
|
||||
import org.eclipse.aether.repository.RemoteRepository;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class TestProjectDependencyCollector {
|
||||
|
||||
private final MavenProject project = mock(MavenProject.class);
|
||||
private final RepositorySystem repoSystem = mock(RepositorySystem.class);
|
||||
private final DefaultRepositorySystemSession session = new DefaultRepositorySystemSession();
|
||||
private final List<RemoteRepository> remoteRepositories = singletonList(
|
||||
(new RemoteRepository.Builder("central", "default", "https://repo1.maven.org/maven2/")).build());
|
||||
|
||||
private final Artifact parent = new DefaultArtifact("com.study.parent:parent:1.0.0");
|
||||
private final Artifact child = new DefaultArtifact("com.study.child:child:1.0.0");
|
||||
private final Artifact child_child = new DefaultArtifact("com.study.child_child:child_child:1.0.0");
|
||||
|
||||
@Test
|
||||
@SuppressWarnings(value = {"unchecked", "rawtypes"})
|
||||
public void createJsonTreeTest() throws Exception {
|
||||
Class collectorClass = ProjectDependencyCollector.class;
|
||||
Method method = collectorClass.getDeclaredMethod("createJsonTree", DependencyNode.class, JsonArray.class);
|
||||
method.setAccessible(true);
|
||||
|
||||
DependencyNode parent_node = new DefaultDependencyNode(parent);
|
||||
DependencyNode child_node = new DefaultDependencyNode(child);
|
||||
DependencyNode child_child_node = new DefaultDependencyNode(child_child);
|
||||
child_node.setChildren(singletonList(child_child_node));
|
||||
parent_node.setChildren(singletonList(child_node));
|
||||
|
||||
JsonObject parentJson = getJsonObject(parent);
|
||||
JsonObject childJson = getJsonObject(child);
|
||||
JsonObject child_childJson = getJsonObject(child_child);
|
||||
|
||||
JsonArray parentFrom = new JsonArray();
|
||||
parentFrom.add(String.format("%s:%s@%s", parent.getGroupId(), parent.getArtifactId(), parent.getVersion()));
|
||||
parentJson.add("from", parentFrom);
|
||||
|
||||
JsonArray childFrom = new JsonArray();
|
||||
childFrom.addAll(parentFrom);
|
||||
childFrom.add(String.format("%s:%s@%s", child.getGroupId(), child.getArtifactId(), child.getVersion()));
|
||||
childJson.add("from", childFrom);
|
||||
|
||||
JsonArray child_childFrom = new JsonArray();
|
||||
child_childFrom.addAll(childFrom);
|
||||
child_childFrom.add(String.format("%s:%s@%s", child_child.getGroupId(), child_child.getArtifactId(), child_child.getVersion()));
|
||||
child_childJson.add("from", child_childFrom);
|
||||
|
||||
JsonObject parentDependencies = new JsonObject();
|
||||
parentDependencies.add(String.format("%s:%s", child.getGroupId(), child.getArtifactId()), childJson);
|
||||
parentJson.add("dependencies", parentDependencies);
|
||||
|
||||
JsonObject childDependencies = new JsonObject();
|
||||
childDependencies.add(String.format("%s:%s", child_child.getGroupId(), child_child.getArtifactId()), child_childJson);
|
||||
childJson.add("dependencies", childDependencies);
|
||||
|
||||
child_childJson.add("dependencies", new JsonObject());
|
||||
|
||||
JsonObject actualJson;
|
||||
|
||||
ProjectDependencyCollector collector_WithOnlyProvenance = new ProjectDependencyCollector(
|
||||
project, repoSystem, session, remoteRepositories, false, true
|
||||
);
|
||||
actualJson = (JsonObject)method.invoke(collector_WithOnlyProvenance, parent_node, null);
|
||||
Assert.assertNull(actualJson.getAsJsonObject("dependencies").getAsJsonObject("dependencies"));
|
||||
|
||||
ProjectDependencyCollector collector_WithoutOnlyProvenance = new ProjectDependencyCollector(
|
||||
project, repoSystem, session, remoteRepositories, false, false
|
||||
);
|
||||
actualJson = (JsonObject)method.invoke(collector_WithoutOnlyProvenance, parent_node, null);
|
||||
Assert.assertEquals(parentJson, actualJson);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings(value = {"unchecked", "rawtypes"})
|
||||
public void createTreeNodeTest() throws Exception {
|
||||
ProjectDependencyCollector collector = new ProjectDependencyCollector(
|
||||
project, repoSystem, session, remoteRepositories, false, true
|
||||
);
|
||||
Class collectorClass = ProjectDependencyCollector.class;
|
||||
Method method = collectorClass.getDeclaredMethod("createTreeNode", Artifact.class, JsonArray.class);
|
||||
method.setAccessible(true);
|
||||
|
||||
|
||||
JsonArray from = new JsonArray();
|
||||
from.add(String.format("%s:%s@%s", parent.getGroupId(), parent.getArtifactId(), parent.getVersion()));
|
||||
|
||||
JsonObject expectJson = getJsonObject(child);
|
||||
|
||||
JsonArray expectFrom = new JsonArray();
|
||||
expectFrom.addAll(from);
|
||||
expectFrom.add(String.format("%s:%s@%s", child.getGroupId(), child.getArtifactId(), child.getVersion()));
|
||||
expectJson.add("from", expectFrom);
|
||||
|
||||
JsonObject json = (JsonObject)method.invoke(collector, child, from);
|
||||
Assert.assertEquals(expectJson, json);
|
||||
}
|
||||
|
||||
private JsonObject getJsonObject(Artifact artifact) {
|
||||
JsonObject obj = new JsonObject();
|
||||
obj.addProperty("version", artifact.getVersion());
|
||||
obj.addProperty("name", String.format("%s:%s", artifact.getGroupId(), artifact.getArtifactId()));
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
103
src/test/java/com/immomo/momosec/maven/plugins/TestRenderer.java
Normal file
103
src/test/java/com/immomo/momosec/maven/plugins/TestRenderer.java
Normal file
@@ -0,0 +1,103 @@
|
||||
package com.immomo.momosec.maven.plugins;
|
||||
|
||||
import com.immomo.momosec.maven.plugins.exceptions.FoundVulnerableException;
|
||||
import com.immomo.momosec.maven.plugins.exceptions.NetworkErrorException;
|
||||
import org.apache.maven.monitor.logging.DefaultLog;
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
import org.codehaus.plexus.logging.console.ConsoleLogger;
|
||||
import org.junit.*;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
|
||||
public class TestRenderer {
|
||||
|
||||
@Rule
|
||||
@SuppressWarnings(value = {"deprecation"})
|
||||
public ExpectedException exceptionRule = ExpectedException.none();
|
||||
|
||||
private final Log log = new DefaultLog(new ConsoleLogger());
|
||||
private final MosecLogHelper logHelper = new MosecLogHelper();
|
||||
|
||||
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
|
||||
private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
|
||||
private final PrintStream originalOut = System.out;
|
||||
private final PrintStream originalErr = System.err;
|
||||
|
||||
private final String no_vulnerable_response =
|
||||
"{" +
|
||||
" \"ok\": true," +
|
||||
" \"dependencyCount\": 3" +
|
||||
"}";
|
||||
|
||||
private final String vulnerable_response =
|
||||
"{" +
|
||||
" \"ok\": false," +
|
||||
" \"dependencyCount\": 3," +
|
||||
" \"vulnerabilities\": [{" +
|
||||
" \"severity\": \"High\"," +
|
||||
" \"title\": \"Fake Vulnerable\"," +
|
||||
" \"cve\": \"CVE-0001-0001\"," +
|
||||
" \"packageName\": \"com.study.foo:bar\"," +
|
||||
" \"version\": \"1.0.0\"," +
|
||||
" \"target_version\": [\"1.1\"]" +
|
||||
" }]" +
|
||||
"}";
|
||||
|
||||
@Before
|
||||
public void setUpStreams() {
|
||||
System.setOut(new PrintStream(outContent));
|
||||
System.setErr(new PrintStream(errContent));
|
||||
}
|
||||
|
||||
@After
|
||||
public void restoreStreams() {
|
||||
System.setOut(originalOut);
|
||||
System.setErr(originalErr);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void renderResponseTest_ErrorJson() throws Exception {
|
||||
exceptionRule.expect(NetworkErrorException.class);
|
||||
exceptionRule.expectMessage(Constants.ERROR_ON_API);
|
||||
|
||||
Renderer renderer = new Renderer(log, true);
|
||||
renderer.renderResponse(new ByteArrayInputStream("_".getBytes()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderResponseTest_NotFoundVuln() throws Exception {
|
||||
Renderer renderer = new Renderer(log, true);
|
||||
renderer.renderResponse(new ByteArrayInputStream(no_vulnerable_response.getBytes()));
|
||||
|
||||
String expect = "[INFO] " + logHelper.strongInfo("✓ Tested 3 dependencies, no vulnerable found.") + "\n";
|
||||
Assert.assertEquals(expect, outContent.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderResponseTest_FoundVulnWithFailOnVuln() throws Exception {
|
||||
exceptionRule.expect(FoundVulnerableException.class);
|
||||
exceptionRule.expectMessage(Constants.ERROR_ON_VULNERABLE);
|
||||
|
||||
Renderer renderer = new Renderer(log, true);
|
||||
renderer.renderResponse(new ByteArrayInputStream(vulnerable_response.getBytes()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderResponseTest_FoundVulnWithoutFailOnVuln() throws Exception {
|
||||
Renderer renderer = new Renderer(log, false);
|
||||
renderer.renderResponse(new ByteArrayInputStream(vulnerable_response.getBytes()));
|
||||
|
||||
String expect =
|
||||
"[WARNING] " + logHelper.strongError("✗ High severity (Fake Vulnerable - CVE-0001-0001) found on com.study.foo:bar@1.0.0") + "\n" +
|
||||
"[WARNING] " + logHelper.strongInfo("! Fix version [\"1.1\"]") + "\n" +
|
||||
"[WARNING] \n" +
|
||||
"[WARNING] " + logHelper.strongWarning("Tested 3 dependencies, found 1 vulnerable pathes.") + "\n";
|
||||
Assert.assertEquals(expect, outContent.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.immomo.momosec.maven.plugins.stubs;
|
||||
|
||||
import org.apache.maven.settings.Proxy;
|
||||
import org.apache.maven.settings.Settings;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class MyTestProjectSettingsStub extends Settings {
|
||||
public List<Proxy> getProxies()
|
||||
{
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.immomo.momosec.maven.plugins.stubs;
|
||||
|
||||
import org.apache.maven.model.Build;
|
||||
import org.apache.maven.model.Model;
|
||||
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
|
||||
import org.apache.maven.plugin.testing.stubs.MavenProjectStub;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.codehaus.plexus.util.ReaderFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MyTestProjectStub extends MavenProjectStub {
|
||||
|
||||
@SuppressWarnings(value = {"unchecked", "rawtypes"})
|
||||
public MyTestProjectStub() {
|
||||
MavenXpp3Reader pomReader = new MavenXpp3Reader();
|
||||
Model model;
|
||||
|
||||
try {
|
||||
model = pomReader.read(ReaderFactory.newXmlReader(new File( getBasedir() + "/pom.xml")));
|
||||
setModel(model);
|
||||
MavenProject mavenProject = new MavenProject(model);
|
||||
this.setParent(mavenProject);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
|
||||
setGroupId(model.getGroupId());
|
||||
setArtifactId(model.getArtifactId());
|
||||
setVersion(model.getVersion());
|
||||
setName(model.getName());
|
||||
setUrl(model.getUrl());
|
||||
setPackaging(model.getPackaging());
|
||||
|
||||
|
||||
Build build = new Build();
|
||||
build.setFinalName(model.getArtifactId());
|
||||
build.setDirectory(getBasedir() + "/target");
|
||||
build.setSourceDirectory(getBasedir() + "/src/main/java");
|
||||
build.setOutputDirectory(getBasedir() + "/target/classes");
|
||||
build.setTestSourceDirectory(getBasedir() + "/src/test/java");
|
||||
build.setTestOutputDirectory(getBasedir() + "/target/test-classes");
|
||||
setBuild(build);
|
||||
|
||||
List compileSourceRoots = new ArrayList();
|
||||
compileSourceRoots.add(getBasedir() + "/src/main/java");
|
||||
setCompileSourceRoots(compileSourceRoots);
|
||||
|
||||
List testCompileSourceRoots = new ArrayList();
|
||||
testCompileSourceRoots.add(getBasedir() + "/src/test/java");
|
||||
setTestCompileSourceRoots(testCompileSourceRoots);
|
||||
}
|
||||
|
||||
public File getBasedir() {
|
||||
return new File(super.getBasedir() + "/src/test/resources/projects/valid-project");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
package com.immomo.momosec.maven.plugins.stubs;
|
||||
|
||||
import org.codehaus.plexus.PlexusTestCase;
|
||||
import org.eclipse.aether.*;
|
||||
import org.eclipse.aether.artifact.ArtifactType;
|
||||
import org.eclipse.aether.artifact.ArtifactTypeRegistry;
|
||||
import org.eclipse.aether.collection.*;
|
||||
import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
|
||||
import org.eclipse.aether.repository.*;
|
||||
import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
|
||||
import org.eclipse.aether.resolution.ResolutionErrorPolicy;
|
||||
import org.eclipse.aether.transfer.TransferListener;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MyTestProjectSystemSessionStub implements RepositorySystemSession {
|
||||
private final Map<String, String> systemProperties;
|
||||
private final Map<String, String> userProperties;
|
||||
private final Map<String, Object> configProperties;
|
||||
private final MirrorSelector mirrorSelector;
|
||||
private final ProxySelector proxySelector;
|
||||
private final AuthenticationSelector authenticationSelector;
|
||||
private LocalRepositoryManager localRepositoryManager;
|
||||
|
||||
@SuppressWarnings(value = {"unchecked", "rawtypes"})
|
||||
public MyTestProjectSystemSessionStub() {
|
||||
LocalRepository repository = new LocalRepository(PlexusTestCase.getBasedir());
|
||||
try {
|
||||
LocalRepositoryManager localRepositoryManager = new SimpleLocalRepositoryManagerFactory().newInstance(this, repository);
|
||||
this.setLocalRepositoryManager(localRepositoryManager);
|
||||
} catch (NoLocalRepositoryManagerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
this.systemProperties = new HashMap();
|
||||
this.userProperties = new HashMap();
|
||||
this.configProperties = new HashMap();
|
||||
this.mirrorSelector = MyTestProjectSystemSessionStub.NullMirrorSelector.INSTANCE;
|
||||
this.proxySelector = MyTestProjectSystemSessionStub.NullProxySelector.INSTANCE;
|
||||
this.authenticationSelector = MyTestProjectSystemSessionStub.NullAuthenticationSelector.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOffline() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIgnoreArtifactDescriptorRepositories() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResolutionErrorPolicy getResolutionErrorPolicy() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArtifactDescriptorPolicy getArtifactDescriptorPolicy() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getChecksumPolicy() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUpdatePolicy() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalRepository getLocalRepository() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalRepositoryManager getLocalRepositoryManager() {
|
||||
return this.localRepositoryManager;
|
||||
}
|
||||
|
||||
public MyTestProjectSystemSessionStub setLocalRepositoryManager(LocalRepositoryManager localRepositoryManager) {
|
||||
this.localRepositoryManager = localRepositoryManager;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorkspaceReader getWorkspaceReader() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepositoryListener getRepositoryListener() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransferListener getTransferListener() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getSystemProperties() {
|
||||
return this.systemProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getUserProperties() {
|
||||
return this.userProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getConfigProperties() {
|
||||
return this.configProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MirrorSelector getMirrorSelector() {
|
||||
return this.mirrorSelector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProxySelector getProxySelector() {
|
||||
return this.proxySelector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticationSelector getAuthenticationSelector() {
|
||||
return this.authenticationSelector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArtifactTypeRegistry getArtifactTypeRegistry() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DependencyTraverser getDependencyTraverser() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DependencyManager getDependencyManager() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DependencySelector getDependencySelector() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionFilter getVersionFilter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DependencyGraphTransformer getDependencyGraphTransformer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionData getData() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepositoryCache getCache() {
|
||||
return null;
|
||||
}
|
||||
|
||||
static final class NullArtifactTypeRegistry implements ArtifactTypeRegistry {
|
||||
public static final ArtifactTypeRegistry INSTANCE = new MyTestProjectSystemSessionStub.NullArtifactTypeRegistry();
|
||||
|
||||
NullArtifactTypeRegistry() {
|
||||
}
|
||||
|
||||
public ArtifactType get(String typeId) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static class NullAuthenticationSelector implements AuthenticationSelector {
|
||||
public static final AuthenticationSelector INSTANCE = new MyTestProjectSystemSessionStub.NullAuthenticationSelector();
|
||||
|
||||
NullAuthenticationSelector() {
|
||||
}
|
||||
|
||||
public Authentication getAuthentication(RemoteRepository repository) {
|
||||
return repository.getAuthentication();
|
||||
}
|
||||
}
|
||||
|
||||
static class NullMirrorSelector implements MirrorSelector {
|
||||
public static final MirrorSelector INSTANCE = new MyTestProjectSystemSessionStub.NullMirrorSelector();
|
||||
|
||||
NullMirrorSelector() {
|
||||
}
|
||||
|
||||
public RemoteRepository getMirror(RemoteRepository repository) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static class NullProxySelector implements ProxySelector {
|
||||
public static final ProxySelector INSTANCE = new MyTestProjectSystemSessionStub.NullProxySelector();
|
||||
|
||||
NullProxySelector() {
|
||||
}
|
||||
|
||||
public Proxy getProxy(RemoteRepository repository) {
|
||||
return repository.getProxy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
mock-maker-inline
|
||||
49
src/test/resources/projects/valid-project/pom.xml
Normal file
49
src/test/resources/projects/valid-project/pom.xml
Normal file
@@ -0,0 +1,49 @@
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.immomo.momosec</groupId>
|
||||
<artifactId>MyTestProject</artifactId>
|
||||
<version>1.0.0</version>
|
||||
|
||||
<name>Mosec Maven Plugin Test Project</name>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.33</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.immomo.momosec</groupId>
|
||||
<artifactId>mosec-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- The defined stubs -->
|
||||
<project implementation="com.immomo.momosec.maven.plugins.stubs.MyTestProjectStub"/>
|
||||
<settings implementation="com.immomo.momosec.maven.plugins.stubs.MyTestProjectSettingsStub"/>
|
||||
<repositorySystemSession implementation="com.immomo.momosec.maven.plugins.stubs.MyTestProjectSystemSessionStub" />
|
||||
<!-- The defined stubs end -->
|
||||
<remoteProjectRepositories></remoteProjectRepositories>
|
||||
<remotePluginRepositories></remotePluginRepositories>
|
||||
|
||||
<severityLevel>High</severityLevel>
|
||||
<failOnVuln>False</failOnVuln>
|
||||
<onlyProvenance>true</onlyProvenance>
|
||||
<endpoint>https://fake.endpoint.com/</endpoint>
|
||||
<includeProvidedDependency>false</includeProvidedDependency>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
BIN
static/remote-configuration.jpg
Normal file
BIN
static/remote-configuration.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
Reference in New Issue
Block a user