AndroidStudio began to show me warning "WebView.addJavascriptInterface should not be called". But this method exists and is not deprecated. What's wrong with it? May be I am missing something and now there is better way to make interaction with Javascript?
It has known security vulnerabilities in earlier Android versions. From the docs:
This is a powerful feature, but also presents a security risk for
applications targeted to API level JELLY_BEAN or below, because
JavaScript could use reflection to access an injected object's public
fields. Use of this method in a WebView containing untrusted content
could allow an attacker to manipulate the host application in
unintended ways, executing Java code with the permissions of the host
application. Use extreme care when using this method in a WebView
which could contain untrusted content.
Related
Starting Android 11 the Reflection based non-sdk(Private) api calls are blocked. Android system checks the caller of the reflection method and if its non-system app it rejects with error as blocklist/blacklist.
"Accessing hidden method Lcom/example/com;->getSomeMethod()Lcom/example/com; (blacklist, reflection, denied)"
More details in links below.
https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces#results-of-keeping-non-sdk
https://www.xda-developers.com/android-11-harden-hidden-api-restriction-meta-reflection/
https://androidreverse.wordpress.com/2020/05/02/android-api-restriction-bypass-for-all-android-versions/
one way to bypass is as below.
https://github.com/ChickenHook/RestrictionBypass
Queries:
"The hidden API blacklist only applies to non-whitelisted user applications. System applications, applications signed with the platform signature, and applications specified in a configuration file are all exempt from the blacklist"
1)All Above quote still hold good for Android 11? what are the ways OEMs can whitelist a app to use Reflection like before?
2)Is the manufacturer-supplied libraries apis treated as non-sdk apis?
How is the Reflection worked in android 10(Target 29) for the same manufacturer-supplied libraries even when META REFLECTION not used?
https://www.xda-developers.com/android-development-bypass-hidden-api-restrictions/
Thanks
Old question, but I've run into this issue recently, and apparently the reflection restrictions can be bypassed easily, using a method called "double reflection", outlined here.
In the app that I'm working on I'm trying to get the Album artist from a song file. I made the query with the cursor and extract the album_artist column (https://stackoverflow.com/a/59631970), but the constant with this String (MediaStore.Audio.AudioColumns.ALBUM_ARTIST) prevent my app from compiling causing a Unresolved reference exception.
The constant has a #hide in its JavaDoc which seems to "hide" the field from outside (couldn't find a legit source to back me up here, I might be very wrong).
MediaStore source-code
What is bugging my mind is that the constant exists in the SDK, the column exists (passing the String manually works) and the constant is in the code, so why I cannot use it? If there is a better way what is it? There is no indication in the code and MediaStore.Audio.Albums.ARTIST don't give me the data that I want (gives me the "artist" not the "album artist").
Does someone know what is the proper way to get this data?
(For now I'm leaving the hard-coded String)
One solution is the answer
Which might not reliable do what you want, to guarantee reading of album_artist tag, you must read the tag manually through mediaMetadataRetriever.
You're trying to access a non-sdk interface, those are all methods, constants, classes, etc, that are not referenced in the android documentation.
Before android pie (api 28), you could attempt to use and reference these methods trough reflection, but since then google has blacklisted all usage of non-sdk interfaces. The only exception is when using non-sdk interfaces available at an specific api level, but your app must not support any bellow api levels.
The reason for such change is that non-sdk interfaces are parts of the android ecosystem that must be available at AOSP for some internal reason but are not final or available to the public. Google does not guarantee that any non-sdk interfaces wont change behavior or be deleted, breaking your app. Since developers insisted on using such interfaces in production apps, they decided to rigorously enforce the restriction.
The #hide annotation in javadoc excludes the code from the compiled javaDoc. So, when google builds its documentation, the constant not being in the android documentation is the intended behavior.
You can refer to this question
question and the documentation
ps: The constant you want to access will become part of the android sdk after android R
I want to play widevine drm content in webview android using html5 code.
I tried a lot not succeeded, does widevine not supported in webview?
please give a way to play widevine in webview android and let me know if widevine does not support in widevine and why?
Any help and suggestion would be appreciated.
Unfortunately, the webview shipped with Android devices differs between devices and between Android versions.
There is an excellent overview here:
http://slides.com/html5test/the-android-browser#/42
You can test whether your device supports it by using an open source HTML5 player like Shaka in your webview and trying some of their demo content.
Shakaplayer includes a basic tutorial showing how to include the player in a webpage:
https://shaka-player-demo.appspot.com/docs/api/tutorial-basic-usage.html
You can also use a test app like the HTML5test Webview app - checking the streaming section to make sure MSE and DRM are both ticked:
https://play.google.com/store/apps/details?id=com.html5test.webview&hl=en
Widevine is supported on Android WebView. The following test page, can be loaded on the WebView to confirm that.
There is a drm key in the response:
"drm": {
"com.widevine.alpha": {
"persistentState": false
}
}
However, to ensure that Widevine is properly activated you need to make sure that you are loading the content within a secure context. You can read about secure contexts here. Quoting:
A secure context is a Window or Worker for which certain minimum standards of authentication and confidentiality are met. Many Web APIs and features are accessible only in a secure context. The primary goal of secure contexts is to prevent MITM attackers from accessing powerful APIs that could further compromise the victim of an attack.
In particular, don't use the loadData method as that wouldn't give you a secure context. Quoting the relevant part of the documentation:
Content loaded using this method will have a window.origin value of "null". This must not be considered to be a trusted origin by the application or by any JavaScript code running inside the WebView (for example, event sources in DOM event handlers or web messages), because malicious content can also create frames with a null origin. If you need to identify the main frame's origin in a trustworthy way, you should use loadDataWithBaseURL() with a valid HTTP or HTTPS base URL to set the origin.
Instead it is recommended to use loadDataWithBaseURL().
Finally, note that Widevine comes with 3 different levels of certification (L1, L2 and L3). L1 being the highest, using the Trusted Execution Environment. AFAIK, L1 may still not be supported yet
on WebViews as shown by this code review comment:
Unless there's some other hidden magic, I believe so. We'll enable L1 on WebView when AndroidOverlay is supported on WebView.
Note that this comment dates from 2017, so not sure whether it is still relevant. The point is that another reason why this wouldn't work is if decrypting the code requires L1 level and either your device or the WebView don't support it.
Hope that helps.
Amazing discovery of the day: JNI on Android lets you access object fields that you're not supposed to, according to Java rules.
Is this capability to bypass access restrictions documented anywhere? Is this an official JNI behavior or specific to the Android flavor of JNI? Is this an undefined behavior? Will the OOP police come for me any moment now?
I understand that relying on unpublished object fields is inherently dangerous and may break anytime; that's not the question here.
UPDATE: looks like applications that target API28 no longer have this capability.
The problem has been described and even addressed in an article, or rather proposal published back in 2006.
Note that Javs defines SecurityManager class, but it considers all JNI calls as security breach and thus your question is a non-issue from their standpoint, like asking "why can I get elevation to Administrator when I only install some driver/service?".
But on Android, things are even more explicit. The official documentation describes this class with the following preface:
Legacy security code; do not use.
Security managers do not provide a secure environment for executing untrusted code. Untrusted code cannot be safely isolated within the Dalvik VM.
(the emphasis is theirs)
If you are looking for stronger words that guarantee that access to native fields and methods from JNI will not go away in a next version of Android, good luck to you.
On the other hand, the chances are higher that some future version of Android will change the names or signatures of some private fields and methods. Moreover, they can change the implementation such that the filed remains, but must be used differently.
Finally note, that all these considerations apply not only to private or package private methods, but also to public methods and fields that did not make it into the official documentation!
Amazing discovery of the day: JNI on Android lets you access object fields that you're not supposed to, according to Java rules.
The abbreviation JNI does not appear anywhere in the question and answers that you linked to, except as a dynamically-generated link to this very question.
Is this documented anywhere?
Any decent book on Java development should cover public, private, etc.
Is this an official JNI behavior or Android-specific?
Neither.
What is Android-specific is compile-time steps to make it difficult for you to add code in some android, java, and javax packages.
Is this an undefined behavior?
That depends on what underlying noun or concept you are tying to tying to the pronoun "this".
If "this" is "accessing private, etc. stuff", then the behavior is not undefined.
If "this" is "accessing something specific private, etc. in the Android framework", that is undefined. There are many, many versions of Android around, and many, many versions of framework classes. Their internal implementations are not identical. Anything not exposed via the Android SDK is eligible for change by Google, device manufacturers, ROM mod maintainers, etc.
How does Android perform security checks on native code? Suppose we declare permission X in AndroidManifest.xml, does it mean we inherit that same permission X in our native code?
How does Android perform security checks?
There are basically two ways the permissions are enforced.
First of all on kernel level: each installed app is assigned a unique (linux) user id and each time your app is started Android will spawn a process and sets the user id of that process to whatever your app userid is. Now accessing e.g. the filesystem or certain hardware features like network is enforced by using the standard linux group permission system. E.g. access to network is only allowed for a network group and your app user is part of that group if you request the network permission in your manifest.
Security in userspace like accessing certain ContentProviders or sending broadcast messages and so on simply can't be relayed to the OS. So once you call a method from either Java or native code you can be (pretty) sure that there is some software check in the end that ensures that you can't do things you have no permission for. The NDK API will most probably simply call (maybe indirectly) some Java method so there is probably no need to have separate checks for native and Java code (but Idk exactly how that is done).
It is likely that you can circumvent some of the Java checks by using native code like networking on the UI thread should work (if you have the network permission). It is also possible that there are loopholes that can only be exploited by using native code but that should be rare. It should not matter in the end what type of code you use.
#user827992
the NDK just produce some digested machine code for the dalvik, there aren't API available in C/C++ for Android; you don't have a problem about using a particular set of API that requires a certain permission because you simply can't even code that and access the API in the first place.
Not true, native code written in C/C++ is at compile time of the app compiled in native machine code for the CPU and at runtime executed directly by the CPU, no dalvik involved. You get back to dalvik if you call some Java method via JNI (through the NDK API) though.
Also there is a lot of Android API available through the NDK, thats the reason it exists.
According to the "Android logic" there is no point to do that for at least 2 reasons:
you always need to code some java lines to make your app, so your entry point will always be the java language and your java app; you can't do an apk with only C/C++ code.
the NDK just produce some digested machine code for the dalvik, there aren't API available in C/C++ for Android; you don't have a problem about using a particular set of API that requires a certain permission because you simply can't even code that and access the API in the first place.
In the end just think about an android as a java application where you can code in C/C++ your own business logic for the heavy computational stuff, everything that Google provides you in terms of API and policy is supposed to be related only with the Java language.