解决方法:(代码中直接使用到native方法就会扫描出此错)
我遇到的问题是Object.getClass(),用myGetClass()代替报错位置的getClass()方法就解决了。
有时候需要重写下框架里边的方法,自己的方法和框架的方法都不要出现getClass()这样的方法名(改成比如:getMyClass 等等,本人猜想,极有可能扫描规则中有扫描这些方法名的方法),
然后把框架中调用的native方法用以下方法替换才能解决。
工具类:
//替换Object.getClass() public static Class<?> myGetClass(Object obj) { Class<?> clazz = null; if (obj == null) { throw new NullPointerException(); } try { clazz = ClassUtils.getClass(ClassUtils.getName(obj));// org.apache.commons.lang3.ClassUtils. } catch (ClassNotFoundException e) { //异常处理 } return clazz; }
其他的native方法替换方法:
//替换System.currentTimeMillis() public static long getCurrentTimeMillis() { return Instant.now().toEpochMilli(); } //替换isAssignableFrom() public static boolean isAssignableFromForCC( Class<?> cls, Class<?> tocls) { return ClassUtils.isAssignable(cls, tocls);// use org.apache.commons.lang3.ClassUtils; } //替换obj.hashCode() public static int hashCodeForCC(Object obj) { return ObjectUtils.hashCode(obj);//org.apache.commons.lang3.ObjectUtils; } //替换getModifiers() public static int getModifiersForCC(Class clazz) { return ReflectUtils.getClassInfo(clazz).getModifiers();//org.springframework.cglib.core.ReflectUtils; } //替换 Thread.sleep(1000L); TimeUnit.SECONDS.sleep(1); //替换Thread.currentThread().getContextClassLoader() ClassUtils.class.getClassLoader();
问题描述:
Abstract
不正确使用Java Native Interface(JNI)会使Java应用程序容易受到其他语言中的安全缺陷的攻击。
Explanation
当Java应用程序使用JNI调用用另一种编程语言编写的代码时,会出现不安全的JNI错误。示例:下面的Java代码定义了一个名为Echo的类。
该类声明了一个本机方法(定义如下),该方法使用C将在控制台上输入的命令回显给用户。
class Echo { public native void runEcho(); static { System.loadLibrary("echo"); } public static void main(String[] args) { new Echo().runEcho(); } }
下面的C代码定义在Echo类中实现的本机方法:
#include <jni.h> #include "Echo.h" //the java class above compiled with javah #include <stdio.h> JNIEXPORT void JNICALL Java_Echo_runEcho(JNIEnv *env, jobject obj) { char buf[64]; gets(buf); printf(buf); }
因为该示例是用Java实现的,所以它似乎不会受到诸如缓冲区溢出漏洞之类的内存问题的影响。尽管Java在确保内存操作安全方面做得很好,
但这种保护并不能扩展到使用Java Native Interface访问的其他语言编写的源代码中出现的漏洞。尽管Java提供了内存保护,但本例
中的C代码仍容易受到缓冲区溢出的攻击,因为它使用了get(),该函数不会对其输入执行任何边界检查。Sun Java(TM)教程提供了对JNI
[1]的以下描述:JNI框架使您的本机方法可以像Java代码使用这些对象一样利用Java对象。本机方法可以创建Java对象,包括数组和字符
串,然后检查并使用这些对象来执行其任务。本机方法还可以检查和使用由Java应用程序代码创建的对象。本机方法甚至可以更新它创建的或
传递给它的Java对象,这些更新后的对象可供Java应用程序使用。因此,应用程序的本地语言端和Java端都可以创建、更新和访问Java对象
,然后在它们之间共享这些对象。通过对本机方法实现的源代码审计,可以很容易地检测到上面示例中的漏洞。这可能不实用,也不可能实现,这
取决于C源代码的可用性和构建项目的方式,但在许多情况下可能就足够了。但是,在Java和本机方法之间共享对象的能力将潜在风险扩展到更
隐蔽的情况,即Java中不正确的数据处理可能导致本机代码中的意外漏洞或本机代码中的不安全操作损坏Java中的数据结构。通过Java应用
程序访问的本机代码中的漏洞通常与使用本机语言编写的应用程序中的漏洞被利用的方式相同。对这类攻击的唯一挑战是攻击者要识别Java
应用程序使用本机代码执行某些操作。这可以通过多种方式来完成,包括识别通常使用本机代码实现的特定行为,或者通过利用Java应用程序中
暴露其使用JNI的系统信息泄漏来实现[2]。
Recommendation
审核包含给定应用程序的所有源代码,包括用其他语言实现的本机方法。在审计过程中,请确保Java和本机代码在边界检查和其他行为方面的差异得到了考虑和正确处理。
特别是,验证共享对象在所有阶段都得到了正确处理:在将其传递给本机代码之前、由本机代码操作时以及在将其返回到Java应用程序之后。