Play Store Alert - Unsafe Implementation of onReceivedSSLError - ssl

One of my app in the play store has received this alert recently and I am completely lost as to what should be done to stop this alert. Please refer this.
Scenarios in my app:
There's a payment gateway involved in the app but the payment takes place through a webview and I am almost sure that this alert might be a result of those webviews.
Insights from Google :
As far as I've searched, I've come across the OnReceivedSslError more often and even the alert clearly states me to handle that method properly. But I am totally lost cause I haven't implemented that method in the first place.
Deeper surfing lead me to links like this,this and this too. The common thing that I found in all the links is that they were all referring to an older version of android. But I am using my minSDK as 14 which is Android 4.0 and above. So I got lost again. And I presume that this alert comes when we use a https in our webview.
So my questions are
How did I get this issue suddenly ?
This app has been in the play store for more than 6 months and this alert comes out of the blue !!! Absolutely no idea what happened !!
How do I reproduce the issue ?
I have tried many methods to reproduce this issue and I have implemented the SSL method as given in here:But nothing seems to be working.
Will this issue affect my payment or my app in any ways ?
How can I reproduce this issue to know more and how can i stop this alert ?
What have I tried ? :
As I had my doubts in older android versions, I designed an emulator with my minSDK but even in that my flow did not enter the method.
My doubt :
Could there be a not-so-genuine SSL which could've triggered this issue ?
Any ideas and insights on this issue will be much helpful. Thanks in advance. I just need to disable that alert, as simple as that.

It seems that Google has upgraded their security checks when you use WebViewClients. In many cases - no pun intended - developers fix an SSL problem like this:
#Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
handler.proceed();
}
I had this issue too, and it seems that Lint doesn't implement this check yet. So it'll be quite difficult to reproduce. If you would like to see what happens, create a self-signed certificate, set-up a webserver using this certificate and connect a webviewclient to this "untrusted" webserver. If you don't handle the onReceivedSSLError, you'll either get an error, or nothing will happen in the webview (by default).
Will it affect your payment? I guess it would, IF the SSL certificate is untrusted, as the request to the url/api will be cancelled.
The above snippet would just ignore the SSL error, and provide the possibility for a MITM-attack. Have you tried intercepting the request, alerting the user, and allowing them to make the choice to continue?
e.g.
#Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
//super.onReceivedSslError(view, handler, error);
AlertDialog.Builder builder = new AlertDialog.Builder(GroupsActivity.this);
builder.setTitle("Invalid/Untrusted certificate");
builder.setMessage("You're accessing a page with an untrusted or invalid certificate. Do you want to continue?");
builder.setNegativeButton("Cancel", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
handler.cancel();
Toast.makeText(GroupsActivity.this, "Request cancelled", Toast.LENGTH_LONG).show();
}
});
builder.setPositiveButton("Continue", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
handler.proceed();
}
});
}

To properly handle SSL certificate validation, change your code to invoke handler.proceed() whenever the certificate presented by the server meets your expectations, and invoke handler.cancel() otherwise.
onReceivedSslError() should notify user about error by Alert Dialog.
If you remove onReceivedSslError() then it will call by default handler.cancel() in case of SSL error.This also will work.

Related

Is it possible to make chromium instantly reload on tab crash?

We are running chromium 83 on an embedded system and experience some random tab crashes.
Is it possible to directly reload a tab in chromium, if it crashes (without showing the "Aw snap!" page)?
We're currently trying to patch the source code to get it working and those were our approaches so far.
(both in sad_tab_helper.cc -> SadTabHelper::RenderProcessGone()
Approach 1:
if (SadTab::ShouldShow(status)) {
web_contents()->GetController().Reload(content::ReloadType::NORMAL, true);
}
Approach 2:
if (SadTab::ShouldShow(status)) {
content::RunOrPostTaskOnThread(
FROM_HERE,
content::BrowserThread::ID::UI,
base::BindOnce(
[](content::WebContents* contents) {
contents->GetController().Reload(content::ReloadType::NORMAL, true);
},
std::move(web_contents())));
}
Both changes finally lead to crash of the entire browser.
It seems that chromium tries to reload the page but as said, it then crashes. The log we get are:
[1663:1671:0321/090914.211931:VERBOSE1:network_delegate.cc(32)] NetworkDelegate::NotifyBeforeURLRequest: http://127.0.0.1/login
[1663:1671:0321/090919.082378:ERROR:broker_posix.cc(40)] Recvmsg error: Connection reset by peer (104)
After that the entire browser crashes. Is there a way to do what we want or are we on a dead end here?
The second approach is suboptimal, SadTabHelper::RenderProcessGone only runs on UI.
Initiating navigation while handling notifications from any WebContentsObserver (SadTabHelper is a WebContentsObserver) must be avoided. It leads to problems. The both approaches attempt to do this. I suppose using base::PostTask instead of content::RunOrPostTaskOnThread should help.
if (SadTab::ShouldShow(status)) {
base::PostTask(
FROM_HERE,
{content::BrowserThread::UI},
base::BindOnce(
[](content::WebContents* contents) {
contents->GetController().Reload(content::ReloadType::NORMAL, true);
},
web_contents()));
}
My reputation is not good enough to comment so I can't leave this comment where it should be.
If you come across this particular solution, the required includes are:
#include "base/task_scheduler/post_task.h"
#include "content/public/browser/browser_thread.h"
#include "base/bind.h"

After getting the permission soft keyboard does not show up for the first time

I read all the similar questions but nothing useful in my case..
I have an activity which shows soft keyboard automatically when it is started.
It's working fluently with no error. But the issue is I need to use permissions for this activity so when the first time activity is executed and permission is asked (then granted), softkeyboard does not show up no matter what (I even need to press edittext 2-3 times for it to load)
I can fix it with recreate() method obviously because it will be necessary only for one time but you know screen refreshing lag makes the application quality lower. Do you have any suggestion please? Thanks
I figured out a way, and though it might not be helpful in your particular scenario, might help someone else. You can set windowSoftInputMode as stateAlwaysVisible for the activity in which you wish to see the keyboard after accpeting/denying permissions, and it will pop up automatically.
I encountered this problem when I was using the Dexter library, and I assume you are using it too.
Solution for those who use the Dexter library: you must call token.continue Permission Request(); in the onPermissionRationaleShouldBeShown event of your PermissionListener.
Dexter.withContext(activity)
.withPermissions(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
.withListener(new MultiplePermissionsListener() {
#SuppressLint("MissingPermission")
#Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
}
#Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
token.continuePermissionRequest();
}
})
.check();

Is there any way to see country data for a Crash in Crashlytics?

Previously we used to rely on Firebase Console for crash reports. It was working pretty good but then Google also announced the official support for Crash reporting through Crashlytics and we went ahead with Crashlytics integration. The only problem being, we can't see the country code for a Crash anymore.
So, is there any way, we can have the country information for a Crash in Crashlytics?
Mike from Fabric here. By default, we don't capture country information for crashes. However, you can set this via a custom key.
On Android, use:
Crashlytics.setString("Country_Code", "Canada");
On iOS, use:
# Objective-C
[CrashlyticsKit setObjectValue:#"Canada" forKey:(#"Country_Code")];
# Swift
Crashlytics.sharedInstance().setObjectValue("Canada", forKey: "Country_Code")
To add on to what Mike have posted, you can get the Locale of the machine as a "guess" of the country.
It is not exactly accurate, but should suffice as an approximation of the app's distribution. (if you do not want to use the Location permission)
some thing like the following:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Fabric.with(this, new Crashlytics());
logCountry();
setContentView(R.layout.activity_main);
}
private void logCountry() {
Crashlytics.setString("Locale", Locale.getDefault().toString());
}
}
you will get to see the locale/country under the "KEYS" tab in the firebase console.
Would have been a lot cleaner if that information is in the "DATA" tab, but guess we have to make do with what's provided.

How to detect private browsing in iOS 11 Mobile Safari or MacOS High Sierra Safari?

On the new iOS 11 Safari and MacOS High Sierra Safari, that trick of seeing if window.localStorage.setItem('test', 1); (see https://stackoverflow.com/a/17741714/1330341) throws an error no longer works, because it no longer throws an error, and it also properly sets the localStorage item. Has anyone figured out any other way to check for private browsing mode in the new versions of Safari?
Haven't actually tried it, but from reading Apple's document:
https://support.apple.com/kb/ph21413?locale=en_US
It lists various characteristics of private mode browsing (~snip):
When you use a Private Browsing window:
Each tab in the window is isolated from the others, so websites you
view in one tab can’t track your browsing in other tabs.
Safari doesn’t remember the webpages you visit or your AutoFill
information.
Safari doesn’t store your open webpages in iCloud, so they aren’t
shown when you view all your open tabs from other devices.
Your recent searches aren’t included in the results list when you use
the Smart Search field.
Items you download aren’t included in the downloads list. (The items
do remain on your computer.)
If you use Handoff, Private Browsing windows are not passed to your
iOS devices or other Mac computers.
Safari doesn’t remember changes to your cookies or other website
data. Safari also asks websites and others who provide those sites
with content (including advertisers) not to keep track of your
browsing, although it is up to the websites to honor this request.
Plug-ins that support Private Browsing stop storing cookies and other
tracking information.
From the above, in particular I found interesting that Safari specifically asks websites to "not track" the browsing. This could potentially be a mechanism to look for, to determine if using private browsing.
See this answer for an example:
Implementing Do not track in asp.net mvc
Again, haven't tested and unsure if it will work, but if not the list provides other potential options. HTH.
I find a solution here:
https://gist.github.com/cou929/7973956#gistcomment-2272103
var isPrivate = false;
try {
window.openDatabase(null, null, null, null);
} catch (_) {
isPrivate = true;
}
alert((isPrivate ? 'You\'re' : 'You aren\'t') + ' in private browsing mode');
Hope it helps :)
Quote from apple's website. https://support.apple.com/kb/ph21413?locale=en_US
Websites can’t modify information stored on your device, so services
normally available at such sites may work differently until you turn
off Private Browsing
So, store a test variable, change its value, then read the test variable.
If you get an exception, are unable to find the variable, the value didn't change or you get a null/undefined value back, they are most likely in private mode.
Alternatively, in private browsing, you have no stored search history accessible. So, redirect to a new page in your site on startup and then test if you have any previous history. If not and the fact that you are getting a Do Not Track most likely means your in private mode on safari.
Please note that I have not tested this. This is based off the information provided by Apple in the above link.
Thing that I realized is Safari throws a "Quota Exceeded" error in the Private mode. So here is what I did!
isPrivateMode: function () {
if (localStorage.length === 0) {
try {
localStorage.setItem('isLocalStorageAvaialble', 'That is being tested!');
localStorage.removeItem('isLocalStorageAvaialble');
return false;
} catch (e) {
return true;
}
}
}
Checking the length of localStorage is important for the fact that, if you are trying this method on a browser that supports localStorage, but is full, you still will get the "Quota Exceeded" error.
In private mode, the length of localStorage is always 0.
Hope this helps!

NSUserNotificationCenterDelegate methods not called on only one machine

I'm trying to use NSUserNotificationCenter. I'm able to deliver notifications successfully. I'm using the ShouldPresentNotification callback on NSUserNotificationCenterDelegate to present notifications, even when the app is running in the foreground.
This works great, except on one of my machines!
I have stripped the code down to it's most basic example. All my machines are running 10.8.3 and Mono 2.10.12. On my 2008 Macbook Pro and a colleague's 2012 rMBP, everything works as excepted. However, on my identical 2012 rMBP the notification is not presented if the app is in the foreground. In fact, on this machine, and this machine only, none of the NSUserNotificationCenterDelegate methods are invoked.
Note that the notification is still delivered on this machine - the notification works - it just doesn't get presented when the app is in the foreground (because the delegate methods are never invoked).
I would really appreciate if anyone has some insight on what settings or configuration might causes this behaviour, or if there is some mechanism I can use to debug this behaviour.
Here is my code:
UNCShouldPresentNotification ShouldPresent = (a, b) => { return true; };
// Shared initialization code
void Initialize()
{
NSUserNotificationCenter.DefaultUserNotificationCenter.ShouldPresentNotification = this.ShouldPresent;
}
partial void notify(NSObject sender)
{
DoNotify();
}
[Export("doNotify")]
private void DoNotify()
{
NSUserNotification notification = new NSUserNotification();
notification.Title = notificationText.StringValue;
NSUserNotificationCenter.DefaultUserNotificationCenter.DeliverNotification(notification);
}
Ok we had exactly the same bug.
Firstly we contacted Xamarin and they've fixed it in the most recent code.
Secondly it was due to overriding BOTH the Delegate delegate (great name I know) and the ShouldPresent setting.
If you want to override the ShouldPresent setting, do this in your NSUserNotificationCenter.Delegate instead.
I hope that's clear. We've a resolved bugzille entry at https://bugzilla.xamarin.com/show_bug.cgi?id=11456
This now works, somewhere between updating MonoMac, Mono and OS X on my machine.