最近公司的app检测出使用了用含漏洞的三方组件,需要整改。记录一下:整改过程中遇到的一些问题及解决方案。
一、组件commons-net-3.3.jar存在漏洞CVE-2021-37533,根据官网公告描述,升级到3.10.0或以上即可。
app下的build.gradle
implementation 'commons-net:commons-net:3.10.0'
apache官网公告:
在ApacheCommonsNet3.9.0之前,默认情况下,Net的FTP客户端信任来自PASV响应的主机。一个恶意服务器可以重定向CommonsNet代码以使用其他主机,但用户必须首先连接到恶意服务器。这可能会导致有关以下方面的信息泄露在客户端的专用网络上运行的服务。版本3.9.0中的默认值 现在为false,以忽略此类主机。
二、组件excel-operation.jar版本3.9存在漏洞CVE-2019-12415,根据官网版本说明,升级到Apache POI 4.1.1或以上即可。
app下的build.gradle
implementation 'org.apache.poi:poi:5.2.4'
apache官网说明:
当使用工具XSSFExportToXml转换用户提供的Microsoft Excel文档时,特制的文档可使攻击者通过XML外部实体(XXE)处理从本地文件系统或内部网络资源读取文件。
缓解措施:Apache POI 4.1.0及之前版本:不使用工具XSSFExportToXml的用户不受影响。建议受影响的用户更新到Apache POI 4.1.1,该版本修复了此漏洞。
升级Apache POI后遇到两个问题:
1、升级到apache.poi 5.2.4 后。会同步导入commons-codec类库,所以如果原来项目有依赖commons-codec-1.x.jar的要删除掉
2、测试的时候报错:(打包编译能通过,但是运行测试的时候)
ava.lang.NoClassDefFoundError: Failed resolution of: Ljava/awt/Color;
org.apache.poi.hssf.util.HSSFColor$HSSFColorPredefined.<init>(HSSFColor.java:113)
找不到Color这个类看源码确实java.awt.Color标红了,编译能过是因为jdk本身有java.awt类库所以能正常编译。
看了一下整个rt.jar 六十多兆,无法接受,逐放弃导入,终极解决方案:在java目录下新建java.awt包,然后在该包下新建Color.java类,然后去rt.jar下找到Color类复制代码到自己新建的Color.java下。我复制好了,你也可以直接复制下面代码使用:
package java.awt;
import java.io.Serializable;
/**
* @author GEEK
*/
public class Color implements Serializable {
public static final Color white = new Color(255, 255, 255);
public static final Color WHITE;
public static final Color lightGray;
public static final Color LIGHT_GRAY;
public static final Color gray;
public static final Color GRAY;
public static final Color darkGray;
public static final Color DARK_GRAY;
public static final Color black;
public static final Color BLACK;
public static final Color red;
public static final Color RED;
public static final Color pink;
public static final Color PINK;
public static final Color orange;
public static final Color ORANGE;
public static final Color yellow;
public static final Color YELLOW;
public static final Color green;
public static final Color GREEN;
public static final Color magenta;
public static final Color MAGENTA;
public static final Color cyan;
public static final Color CYAN;
public static final Color blue;
public static final Color BLUE;
private static final long serialVersionUID = 118526816881161077L;
private static final double FACTOR = 0.7D;
static {
WHITE = white;
lightGray = new Color(192, 192, 192);
LIGHT_GRAY = lightGray;
gray = new Color(128, 128, 128);
GRAY = gray;
darkGray = new Color(64, 64, 64);
DARK_GRAY = darkGray;
black = new Color(0, 0, 0);
BLACK = black;
red = new Color(255, 0, 0);
RED = red;
pink = new Color(255, 175, 175);
PINK = pink;
orange = new Color(255, 200, 0);
ORANGE = orange;
yellow = new Color(255, 255, 0);
YELLOW = yellow;
green = new Color(0, 255, 0);
GREEN = green;
magenta = new Color(255, 0, 255);
MAGENTA = magenta;
cyan = new Color(0, 255, 255);
CYAN = cyan;
blue = new Color(0, 0, 255);
BLUE = blue;
}
int value;
private float[] frgbvalue;
private float[] fvalue;
private float falpha;
public Color(int var1, int var2, int var3) {
this(var1, var2, var3, 255);
}
public Color(int var1, int var2, int var3, int var4) {
this.frgbvalue = null;
this.fvalue = null;
this.falpha = 0.0F;
this.value = (var4 & 255) << 24 | (var1 & 255) << 16 | (var2 & 255) << 8 | (var3 & 255) << 0;
testColorValueRange(var1, var2, var3, var4);
}
public Color(int var1) {
this.frgbvalue = null;
this.fvalue = null;
this.falpha = 0.0F;
this.value = -16777216 | var1;
}
public Color(int var1, boolean var2) {
this.frgbvalue = null;
this.fvalue = null;
this.falpha = 0.0F;
if (var2) {
this.value = var1;
} else {
this.value = -16777216 | var1;
}
}
public Color(float var1, float var2, float var3) {
this((int) ((double) (var1 * 255.0F) + 0.5D), (int) ((double) (var2 * 255.0F) + 0.5D), (int) ((double) (var3 * 255.0F) + 0.5D));
testColorValueRange(var1, var2, var3, 1.0F);
this.frgbvalue = new float[3];
this.frgbvalue[0] = var1;
this.frgbvalue[1] = var2;
this.frgbvalue[2] = var3;
this.falpha = 1.0F;
this.fvalue = this.frgbvalue;
}
public Color(float var1, float var2, float var3, float var4) {
this((int) ((double) (var1 * 255.0F) + 0.5D), (int) ((double) (var2 * 255.0F) + 0.5D), (int) ((double) (var3 * 255.0F) + 0.5D), (int) ((double) (var4 * 255.0F) + 0.5D));
this.frgbvalue = new float[3];
this.frgbvalue[0] = var1;
this.frgbvalue[1] = var2;
this.frgbvalue[2] = var3;
this.falpha = var4;
this.fvalue = this.frgbvalue;
}
private static void testColorValueRange(int var0, int var1, int var2, int var3) {
boolean var4 = false;
String var5 = "";
if (var3 < 0 || var3 > 255) {
var4 = true;
var5 = var5 + " Alpha";
}
if (var0 < 0 || var0 > 255) {
var4 = true;
var5 = var5 + " Red";
}
if (var1 < 0 || var1 > 255) {
var4 = true;
var5 = var5 + " Green";
}
if (var2 < 0 || var2 > 255) {
var4 = true;
var5 = var5 + " Blue";
}
if (var4) {
throw new IllegalArgumentException("Color parameter outside of expected range:" + var5);
}
}
private static void testColorValueRange(float var0, float var1, float var2, float var3) {
boolean var4 = false;
String var5 = "";
if ((double) var3 < 0.0D || (double) var3 > 1.0D) {
var4 = true;
var5 = var5 + " Alpha";
}
if ((double) var0 < 0.0D || (double) var0 > 1.0D) {
var4 = true;
var5 = var5 + " Red";
}
if ((double) var1 < 0.0D || (double) var1 > 1.0D) {
var4 = true;
var5 = var5 + " Green";
}
if ((double) var2 < 0.0D || (double) var2 > 1.0D) {
var4 = true;
var5 = var5 + " Blue";
}
if (var4) {
throw new IllegalArgumentException("Color parameter outside of expected range:" + var5);
}
}
public static Color decode(String var0) throws NumberFormatException {
Integer var1 = Integer.decode(var0);
int var2 = var1;
return new Color(var2 >> 16 & 255, var2 >> 8 & 255, var2 & 255);
}
public static Color getColor(String var0) {
return getColor(var0, (Color) null);
}
public static Color getColor(String var0, Color var1) {
Integer var2 = Integer.getInteger(var0);
if (var2 == null) {
return var1;
} else {
int var3 = var2;
return new Color(var3 >> 16 & 255, var3 >> 8 & 255, var3 & 255);
}
}
public static Color getColor(String var0, int var1) {
Integer var2 = Integer.getInteger(var0);
int var3 = var2 != null ? var2 : var1;
return new Color(var3 >> 16 & 255, var3 >> 8 & 255, var3 >> 0 & 255);
}
public static int HSBtoRGB(float var0, float var1, float var2) {
int var3 = 0;
int var4 = 0;
int var5 = 0;
if (var1 == 0.0F) {
var3 = var4 = var5 = (int) (var2 * 255.0F + 0.5F);
} else {
float var6 = (var0 - (float) Math.floor((double) var0)) * 6.0F;
float var7 = var6 - (float) Math.floor((double) var6);
float var8 = var2 * (1.0F - var1);
float var9 = var2 * (1.0F - var1 * var7);
float var10 = var2 * (1.0F - var1 * (1.0F - var7));
switch ((int) var6) {
case 0:
var3 = (int) (var2 * 255.0F + 0.5F);
var4 = (int) (var10 * 255.0F + 0.5F);
var5 = (int) (var8 * 255.0F + 0.5F);
break;
case 1:
var3 = (int) (var9 * 255.0F + 0.5F);
var4 = (int) (var2 * 255.0F + 0.5F);
var5 = (int) (var8 * 255.0F + 0.5F);
break;
case 2:
var3 = (int) (var8 * 255.0F + 0.5F);
var4 = (int) (var2 * 255.0F + 0.5F);
var5 = (int) (var10 * 255.0F + 0.5F);
break;
case 3:
var3 = (int) (var8 * 255.0F + 0.5F);
var4 = (int) (var9 * 255.0F + 0.5F);
var5 = (int) (var2 * 255.0F + 0.5F);
break;
case 4:
var3 = (int) (var10 * 255.0F + 0.5F);
var4 = (int) (var8 * 255.0F + 0.5F);
var5 = (int) (var2 * 255.0F + 0.5F);
break;
case 5:
var3 = (int) (var2 * 255.0F + 0.5F);
var4 = (int) (var8 * 255.0F + 0.5F);
var5 = (int) (var9 * 255.0F + 0.5F);
}
}
return -16777216 | var3 << 16 | var4 << 8 | var5 << 0;
}
public static float[] RGBtoHSB(int var0, int var1, int var2, float[] var3) {
if (var3 == null) {
var3 = new float[3];
}
int var7 = var0 > var1 ? var0 : var1;
if (var2 > var7) {
var7 = var2;
}
int var8 = var0 < var1 ? var0 : var1;
if (var2 < var8) {
var8 = var2;
}
float var6 = (float) var7 / 255.0F;
float var5;
if (var7 != 0) {
var5 = (float) (var7 - var8) / (float) var7;
} else {
var5 = 0.0F;
}
float var4;
if (var5 == 0.0F) {
var4 = 0.0F;
} else {
float var9 = (float) (var7 - var0) / (float) (var7 - var8);
float var10 = (float) (var7 - var1) / (float) (var7 - var8);
float var11 = (float) (var7 - var2) / (float) (var7 - var8);
if (var0 == var7) {
var4 = var11 - var10;
} else if (var1 == var7) {
var4 = 2.0F + var9 - var11;
} else {
var4 = 4.0F + var10 - var9;
}
var4 /= 6.0F;
if (var4 < 0.0F) {
++var4;
}
}
var3[0] = var4;
var3[1] = var5;
var3[2] = var6;
return var3;
}
public static Color getHSBColor(float var0, float var1, float var2) {
return new Color(HSBtoRGB(var0, var1, var2));
}
public int getRed() {
return this.getRGB() >> 16 & 255;
}
public int getGreen() {
return this.getRGB() >> 8 & 255;
}
public int getBlue() {
return this.getRGB() >> 0 & 255;
}
public int getAlpha() {
return this.getRGB() >> 24 & 255;
}
public int getRGB() {
return this.value;
}
public Color brighter() {
int var1 = this.getRed();
int var2 = this.getGreen();
int var3 = this.getBlue();
int var4 = this.getAlpha();
byte var5 = 3;
if (var1 == 0 && var2 == 0 && var3 == 0) {
return new Color(var5, var5, var5, var4);
} else {
if (var1 > 0 && var1 < var5) {
var1 = var5;
}
if (var2 > 0 && var2 < var5) {
var2 = var5;
}
if (var3 > 0 && var3 < var5) {
var3 = var5;
}
return new Color(Math.min((int) ((double) var1 / 0.7D), 255), Math.min((int) ((double) var2 / 0.7D), 255), Math.min((int) ((double) var3 / 0.7D), 255), var4);
}
}
public Color darker() {
return new Color(Math.max((int) ((double) this.getRed() * 0.7D), 0), Math.max((int) ((double) this.getGreen() * 0.7D), 0), Math.max((int) ((double) this.getBlue() * 0.7D), 0), this.getAlpha());
}
public int hashCode() {
return this.value;
}
public boolean equals(Object var1) {
return var1 instanceof Color && ((Color) var1).getRGB() == this.getRGB();
}
public String toString() {
return this.getClass().getName() + "[r=" + this.getRed() + ",g=" + this.getGreen() + ",b=" + this.getBlue() + "]";
}
public float[] getRGBComponents(float[] var1) {
float[] var2;
if (var1 == null) {
var2 = new float[4];
} else {
var2 = var1;
}
if (this.frgbvalue == null) {
var2[0] = (float) this.getRed() / 255.0F;
var2[1] = (float) this.getGreen() / 255.0F;
var2[2] = (float) this.getBlue() / 255.0F;
var2[3] = (float) this.getAlpha() / 255.0F;
} else {
var2[0] = this.frgbvalue[0];
var2[1] = this.frgbvalue[1];
var2[2] = this.frgbvalue[2];
var2[3] = this.falpha;
}
return var2;
}
public float[] getRGBColorComponents(float[] var1) {
float[] var2;
if (var1 == null) {
var2 = new float[3];
} else {
var2 = var1;
}
if (this.frgbvalue == null) {
var2[0] = (float) this.getRed() / 255.0F;
var2[1] = (float) this.getGreen() / 255.0F;
var2[2] = (float) this.getBlue() / 255.0F;
} else {
var2[0] = this.frgbvalue[0];
var2[1] = this.frgbvalue[1];
var2[2] = this.frgbvalue[2];
}
return var2;
}
public float[] getComponents(float[] var1) {
if (this.fvalue == null) {
return this.getRGBComponents(var1);
} else {
int var3 = this.fvalue.length;
float[] var2;
if (var1 == null) {
var2 = new float[var3 + 1];
} else {
var2 = var1;
}
for (int var4 = 0; var4 < var3; ++var4) {
var2[var4] = this.fvalue[var4];
}
var2[var3] = this.falpha;
return var2;
}
}
public float[] getColorComponents(float[] var1) {
if (this.fvalue == null) {
return this.getRGBColorComponents(var1);
} else {
int var3 = this.fvalue.length;
float[] var2;
if (var1 == null) {
var2 = new float[var3];
} else {
var2 = var1;
}
for (int var4 = 0; var4 < var3; ++var4) {
var2[var4] = this.fvalue[var4];
}
return var2;
}
}
public int getTransparency() {
int var1 = this.getAlpha();
if (var1 == 255) {
return 1;
} else {
return var1 == 0 ? 2 : 3;
}
}
}
三、组件libBaiduMapSDK_map_v6_4_0.so存在漏洞,是因为百度地图SDK内使用了libpng、libjpeg用于处理PNG和JPEG格式图像数据的C语言库。
所以去百度地图官网找了一遍,终于找到了百度地图v4.2.1的更新日志:对底图渲染libpng库做了升级,但是并没有找到对libjpeg库升级的日志。
然而我用的6.4.0版本还是有被检测出漏洞:libjpeg库漏洞编号CVE-2020-14153,CVE-2020-14152;libpng库漏洞编号CVE-2018-14550,CVE-2019-7317。这些漏洞可能百度地图SDK-v4.2.1后出现的新漏洞吧,虽然没有找到百度地图官网后续的更新日志,但是我还是对百度SDK进行了升级,目前最新版本是7.5.9。
百度地图SDK官网更新日志:
关于libpng漏洞整改,更新日志:V4.2.1-升级底图渲染libpng库,解决旧版本的可能存在的漏洞问题
**********************
*好记忆不如烂笔头。*
*不足之处欢迎指正。*
**********************