Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component scanning should be able to ignore encrypted classes with invalid class version #27691

Closed
kakahu2015 opened this issue Nov 17, 2021 · 11 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: feedback-provided Feedback has been provided type: enhancement A general enhancement
Milestone

Comments

@kakahu2015
Copy link

I want to encrypt the class bytecode of some compiled core classes in the springboot project, and use the JVMTI monitoring mechanism to decrypt the class. Ordinary java projects have been able to decrypt the jar after the encrypted class can be decrypted normally. It runs, but even if a specific java class is not referenced in the code in springboot, if the directory of the class is in the spring scan path by default, the encrypted class file will be caused by org even if the class file is not referenced by any code. The validation bytecode of org.springframework.asm.ClassReader throws an exception, causing the service to stop. Can you provide a configuration for this requirement to ignore certain classes that are not validated?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Nov 17, 2021
@snicoll
Copy link
Member

snicoll commented Nov 17, 2021

@jhoeller jhoeller self-assigned this Nov 17, 2021
@jhoeller
Copy link
Contributor

What's the specific exception thrown when ClassReader encounters one of those class files? Maybe we can make our ASM fork more lenient in that respect...

@kakahu2015
Copy link
Author

Since jdk1.5, JVMTI was introduced. I tried to encrypt a normal java class bytecode, and then I asked JVM to load it. The prompt: This is not a normal class bytecode file, so I applied JVMTI, compiled a dynamic library with C++, added the startup parameter -agentpath, so that when the JVM loads the class, it decrypts the encrypted bytecode into a normal class in advance, so that the encrypted class can be run normally. But the spring framework does not adapt to this. For example, an encrypted class file is placed under the path scanned by spring boot by default. This class is not referenced by any other class code, but it will still be due to org.springframework.asm when it is started. ClassReader performs strong verification on all bytecodes in the path scanned by spring boot by default, so that an abnormal (encrypted) class file is detected and an exception (such as Incompatible magic value, etc.) is thrown, causing the program to stop starting. , I suggest exception handling for specific (encrypted class) without verification.

@rstoyanchev rstoyanchev added the in: core Issues in core modules (aop, beans, core, context, expression) label Nov 24, 2021
@jhoeller
Copy link
Contributor

Reviewing ASM's ClassReader implementation, it's not clear to me which part would actually fail here. Could you provide the stacktrace of an exception raised for one of your encrypted class files? Is it ultimately an IllegalArgumentException bubbling up from the ClassReader constructor, just like in case of an unsupported class file version?

@jsbxyyx
Copy link

jsbxyyx commented May 16, 2022

when fixed it?

@bclozel bclozel added the status: waiting-for-feedback We need additional information before we can continue label May 16, 2022
@bclozel
Copy link
Member

bclozel commented May 16, 2022

@jsbxyyx we didn't get @kakahu2015 's feedback to make progress. @jsbxyyx do you have the requested stacktrace showing the issue? Can you provide it here?

@spring-projects-issues
Copy link
Collaborator

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

@spring-projects-issues spring-projects-issues added the status: feedback-reminder We've sent a reminder that we need additional information before we can continue label May 23, 2022
@kakahu2015
Copy link
Author

First, please refer to https://github.com/kakahu2015/encrypt to download the demo to your local, I will use this demo as an example to describe the problem I want to solve. Note that the package name of the org.kakahu.util.Hello class is org.kakahu.util is not inside the default scan package (org.kakahu.encrypte) of springboot, but org.kakahu in my uncompiled and packaged application There is no problem in running java -jar unencrypted.jar when the class file of the .util.Hello class performs encryption processing
image

But now I encrypt the org.kakahu.util.Hello class file (remember this action), run java -jar util_hello_encrypted.jar again, because the class has been encrypted and processed without any decryption, it will definitely report a magic number error first :
image

Next, I use the jvmti-related interface technology to decrypt the encrypted calss of the org.kakahu.util.Hello class java -agentpath:./libkakahu.so -jar util_hello_encrypted.jar, so that the program can run normally:
image

Because org.kakahu.util is not under the default startup scan package of org.kakahu.encrypte springboot, the encrypted classes can be processed normally by using jvmti, and then I want to do the classes under the default startup scan package of org.kakahu.encrypte springboot. Encryption processing, the JVMTI level can definitely handle the decryption problem, but springboot's own verification mechanism will scan and verify all classes under the default startup scan package of org.kakahu.encrypte springboot (even if my business logic is not really used), it will definitely If an exception is thrown, I just hope that you will provide an exception to not verify some calss files under the default startup scan package of org.kakahu.encrypte springboot:
image
image
image

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue status: feedback-reminder We've sent a reminder that we need additional information before we can continue labels May 24, 2022
@lunxian8
Copy link

lunxian8 commented Nov 6, 2023

Hello, I have encountered the same issue, and the root cause lies in the extensive use of ASM technology in the Spring framework. Spring AOP utilizes ASM to directly read encrypted bytecode, bypassing the JVMTI mechanism, which results in the program throwing errors. Have you found a solution for this issue?

@kakahu2015
Copy link
Author

Perhaps java is not inherently designed to ensure protection against reverse engineering, as this issue seems to be unattractive to official springboot attention

@jhoeller jhoeller changed the title org.springframework.asm.ClassReader class verification rules ASM ClassReader should be able to ignore encrypted classes with invalid class version Nov 24, 2023
@jhoeller jhoeller added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Nov 24, 2023
@jhoeller jhoeller changed the title ASM ClassReader should be able to ignore encrypted classes with invalid class version Component scanning should ignore encrypted classes with invalid class version Nov 24, 2023
@jhoeller jhoeller added this to the 6.1.x milestone Nov 24, 2023
@jhoeller jhoeller modified the milestones: 6.1.x, 6.1.2 Dec 9, 2023
@jhoeller
Copy link
Contributor

jhoeller commented Dec 9, 2023

For 6.1.2, I'm introducing a system property spring.classformat.ignore which can be set to true in order to ignore class format mismatches during classpath scanning. For reliable detection, MetadataReader throws a new ClassFormatException now which the above system property reacts to. The exception messages are as descriptive as possible, suggesting common solutions such as a -target compilation downgrade, a framework upgrade, or setting spring.classformat.ignore to true now.

@jhoeller jhoeller changed the title Component scanning should ignore encrypted classes with invalid class version Component scanning should be able to ignore encrypted classes with invalid class version Dec 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: feedback-provided Feedback has been provided type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

8 participants