Skip to content

aws-core-sdk will not run without ReflectPermission "suppressAccessChecks" #528

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

Closed
rmuir opened this issue Oct 7, 2015 · 11 comments
Closed

Comments

@rmuir
Copy link
Contributor

rmuir commented Oct 7, 2015

Currently the static initializer of InternalConfig$Factory uses jackson-databind to do "fancy" deserialization of a ton of configuration classes from a json file. These classes are not public / do not have proper publicly accessible ctors/etc, hence jackson cannot perform the logic without calling AccessibleObject.setAccessible(true). Since it happens in clinit(), the whole library is unusable without granting this permission.

IMO, this is a very serious bug. This situation makes it nearly impossible to properly protect confidential data (such as AWS credentials) in any app using the library, because it means private fields are no longer private, and so on.

To hack around this bug in elasticsearch, we have to grant this horrible permission to our AWS plugins, and then use the following hack in all AWS plugins to try to contain the damage:

static {
        // This internal config is deserialized but with wrong access modifiers,
        // cannot work without suppressAccessChecks permission right now. We force
        // a one time load with elevated privileges as a workaround.
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new SpecialPermission());
        }
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            @Override
            public Void run() {
                try {
                    Class.forName("com.amazonaws.internal.config.InternalConfig$Factory");
                } catch (ClassNotFoundException e) {
                    throw new RuntimeException("Unable to initialize internal aws config", e);
                }
                return null;
            }
        });
    }

Personally, I don't see the need for fancy serialization here at all: a simple .properties file or similar could remove a ton of classes here, and possibly a 3rd-party library dependency on a popular library (jackson-databind) which would reduce jar hell for users of this library. That is how I would solve it.

Otherwise, at least set the access modifiers on all these classes/ctors/etc to be correct (public). By requiring suppressAccessChecks it means everything is effectively public.

@shorea
Copy link
Contributor

shorea commented Oct 30, 2015

Want to go for the simple approach where we just fix the access modifier as this style of configuration is on it's way out and I don't want to spend too much time refactoring the deserialization logic. In going down this route I believe I found an issue with Jackson databind that's still throwing exceptions even when the field/method/constructor is public. Opened an issue/PR with them, will update this issue when I hear back.

@cowtowncoder
Copy link
Contributor

As per FasterXML/jackson-databind#997:

  1. May want to disable MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS to avoid the problem (any 2.x version)
  2. For finer-grained control, Jackson 2.7 will add MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS, disabling of which prevents calls in case of accessors accessible using Reflection

@shorea
Copy link
Contributor

shorea commented Nov 6, 2015

Thanks for the suggestion! MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS works for us.

@shorea
Copy link
Contributor

shorea commented Nov 7, 2015

This has been fixed and is staged for our next release tentatively scheduled for next Tuesday.

@shorea shorea closed this as completed Nov 7, 2015
@manikandanrs
Copy link
Contributor

This is now released. https://aws.amazon.com/releasenotes/Java/2423908263921241

@rmuir
Copy link
Contributor Author

rmuir commented Nov 11, 2015

I just tested this release and it works, thanks again!

@prangdal
Copy link

prangdal commented Aug 8, 2016

I am trying to work with AWS SDK for S3 to download and upload documents from my bucket.. I have just added S3 dependency with "aws-java-sdk-bom" version 1.11.24.

I am getting following error when i am running the class "S3Sample" and I see this is relates to the topic of discuss here.. can someone suggest me a fix with this please. I am trying to refer to the region "AP_SOUTH_1"

Exception in thread "main" java.lang.NoSuchFieldError: ALLOW_FINAL_FIELDS_AS_MUTATORS
at com.amazonaws.partitions.PartitionsLoader.(PartitionsLoader.java:52)
at com.amazonaws.regions.RegionMetadataFactory.create(RegionMetadataFactory.java:30)
at com.amazonaws.regions.RegionUtils.initialize(RegionUtils.java:66)
at com.amazonaws.regions.RegionUtils.getRegionMetadata(RegionUtils.java:54)
at com.amazonaws.regions.RegionUtils.getRegion(RegionUtils.java:107)
at com.amazonaws.regions.Region.getRegion(Region.java:43)
at com.soc.services.s3.connect.S3Sample.main(S3Sample.java:84)

appreciate your help here..
Thanks
Pradeep Rangdal

@cowtowncoder
Copy link
Contributor

@prangdal That would be a version discrepancy; jackson-databind version in your classpath is older than what library/framework (s3 SDK presumably) has been compiled against.

@9dragon
Copy link

9dragon commented Mar 1, 2017

@prangdal I had the same problem with you, and it works with me when i changed the version of jackson-databind to 2.6.6. Thank you @cowtowncoder.

@abirkhan04
Copy link

@roamingdragon This issue is not fixed in my case. I checked both version of jackson-databind but the issue persists.

@viveksinghtt
Copy link

@abirkhan04 did you get a solution...i Am stuck with this too!!!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants