Giter Site home page Giter Site logo

scottyab / safetynethelper Goto Github PK

View Code? Open in Web Editor NEW
329.0 33.0 82.0 1.35 MB

SafetyNet Helper wraps the Google Play Services SafetyNet.API and verifies Safety Net API response with the Android Device Verification API.

Java 100.00%
safetynet-api android safetynet-helper security rootchecker

safetynethelper's Introduction

SafetyNet attest() Helper

SafetyNet Helper wraps the Google Play Services SafetyNet.API and verifies Safety Net API response with the Android Device Verification API. The SafetyNet.API analyses the device your app is running on to test its software/hardware configuration matches that of a device that has passed the Android Compatibility Test Suite (CTS). Note this is a client only validation, it's recommended to include server side validation.

Rooted devices seem to cause ctsProfileMatch=false.

Recommend reading the developers guide to getting started with SafetyNet

Extract from Android SafetyNet API doc

Check if your app is running on a device that matches a device model that has passed Android compatibility testing. This analysis can help you determine if your app will work as expected on the device where it is installed. The service evaluates both software and hardware characteristics of the device, and may use hardware roots of trust, when available.

Since this library release Google has created an Safety Net Sample

Features

  • Calls Google play services Safety Net test
  • Local verification of request
  • Verifies Safety Net API response with the Android Device Verification API (over SSL pinned connection)

Requires / Dependencies

  • Google Play services (specifically the SafetyNet API 'com.google.android.gms:play-services-safetynet:17.0.0')
  • Requires Internet permission
  • Google API key for the Android Device Verification API

Server Validation!!!

This library was built to get app developers up and going with SafetyNet attest API.

With skill and time any device based checks can be bypassed. This is why the validation must be handled by the server. Therefore you should look at implementing more robust and secure validation of the attest response via a server-side component.

  • App requests the nonce / request token from your server
  • Call SafetyNet.getClient(context).attest(requestNonce, apiKey)
  • When the Pass the JwsResult returned as part of the SafetyNet success response to your server for validation i.e
    • Check the nonce/request token matches the expected value
    • verify the SafetyNet response is from Google using the Android Device Verification API
    • verify app package, timestamp, apk and certificate digests
  • Based on the validation result your server can choose whether to trust the app install. The action you take is dependent on your app, you could log the user out by revoking OAUTH tokens or flag any high scores as potential cheating.

How to use

You'll need to get a API key from the Google developer console to allow you to verify with the Android Device Verification API (in the sample project this is set via a BuildConfig field to keep my api key out of GitHub)

    final SafetyNetHelper safetyNetHelper = new SafetyNetHelper(API_KEY);

    safetyNetHelper.requestTest(context, new SafetyNetHelper.SafetyNetWrapperCallback() {
            @Override
            public void error(int errorCode, String msg) {
                //handle and retry depending on errorCode
                Log.e(TAG, msg);
            }

            @Override
            public void success(boolean ctsProfileMatch, boolean basicIntegrity) {
                if (ctsProfileMatch) {
                    //profile of the device running your app matches the profile of a device that has passed Android compatibility testing.
                else if(basicIntegrity){
                    //then the device running your app likely wasn't tampered with, but the device has not necessarily passed Android compatibility testing.
                } else {
                    //handle fail, maybe warn user device is unsupported or in compromised state? (this is up to you!)
                }
            }
        });

Add as dependency

This library is not released in Maven Central, until then you can add as a library module or use JitPack.io

add remote maven url

    repositories {
        maven {
            url "https://jitpack.io"
        }
    }

then add a library dependency

    dependencies {
        compile 'com.github.scottyab:safetynethelper:<latest version>'
    }

Sample App

The sample app illustrates the helper library in practice. Test your own devices today. It's available on the playstore.


Licence

Copyright (c) 2022 Scott Alexander-Bown

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

safetynethelper's People

Contributors

aembleton avatar andrewjli avatar aymandf avatar chaoscalm avatar dgw avatar friederbluemle avatar luk1337 avatar mirokuratczyk avatar mpp-doric avatar robsmall avatar scottyab avatar tanghuaizhe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

safetynethelper's Issues

Clean up and publish sample app to play store

better present the response from safetynet API, and show some kind of icon/color based on cts pass/fail. Maybe even cache the pass/fail results in shared pref?

Publish to play store and update screen shots

small typo

v0.8 on Poco F3 currently shows "Advice: None availible"
You might want to correct this to "available".

Better error handling and error codes

At the moment there are only 3 error codes and the general error handling isn't great. Make it better so developers not whether they can retry for certain errors i.e not internet, or not i.e not google play services.

Test on captive network

payload validation failed

Hi, I always get "safetynet helper response payload validation failed" when i run safetynethelper

my device was rooted, I restored it and did a factory reset. but still, it won't pass

is there anything more I need to do ?

Reported critical issues with version 17.0.0. google play warning

Hello,

Using the version 0.8.0 of the library a warning is now displayed when uploading the app in the play store:

Le développeur de play-services-safetynet (com.google.android.gms:play-services-safetynet) a signalé des problèmes critiques pour la version 17.0.0. Pensez à passer à une version plus récente avant de publier une nouvelle release.

It means the version 17 of safety net must not be used anymore, can you please release a new version with an update version of the safety net library to avoid any issue ?

Thanks

Incompatible with safetynet 12.x

SafetyNet API has changed, some class names have changed and there's no need to connect to google api client manually anymore

hi

i design logo/icon for "open source projects" on utopian ..
i thınk your project need a good logo whıch make your applıcatıon vıew better..
wanna me desıgn a logo "free" for your applıcatıon?

please reply my post... ı ll start do design and share with you and than send a post on website "utopian.io"..
also u can connect wıth me on discord "@ahmeterbay#0466" or emaıl "[email protected]"

Display "ro.build.fingerprint" property on screen

Feedback email... "If you put the value of android's "ro.build.fingerprint" property on screen then it really helps to diagnose problems because it allows people to accurately compare experiences from the exact same phone+software."

Test seems to be stuck loading

when I click the button to test safetynet, it gets stuck loading. Even though my internet works perfectly fine.
Seems to happen with multiple devices, including devices that run Pokemon Go fine (hence they should pass the safetynet test)

Failed resolution of: Lcom/google/android/gms/safetynet/SafetyNetApi$AttestationResult

Hi, I'm using a safetynetlib-release-v0.3.aar

this is my implementation:

` private void checkSafetyNet() {

    final SafetyNetHelper safetyNetHelper = new SafetyNetHelper("myapikey");

    safetyNetHelper.requestTest(this, new SafetyNetHelper.SafetyNetWrapperCallback() {
        @Override
        public void error(int errorCode, String msg) {
            //handle and retry depending on errorCode
            Log.e(TAG, msg);
        }

        @Override
        public void success(boolean ctsProfileMatch, boolean basicIntegrity) {
            if (ctsProfileMatch) {
                Log.e(TAG, "ProfileMatch");
                //profile of the device running your app matches the profile of a device that has passed Android compatibility testing.
            } else if (basicIntegrity) {
                //then the device running your app likely wasn't tampered with, but the device has not necessarily passed Android compatibility testing.
                Log.e(TAG, "basicIntegrity");
            } else {
                //handle fail, maybe warn user device is unsupported or in compromised state? (this is up to you!)
                Log.e(TAG, "FAILED");
            }
        }
    });

    }`

But I get:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myapp, PID: 9697
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/android/gms/safetynet/SafetyNetApi$AttestationResult;
at com.scottyab.safetynet.SafetyNetHelper$1.onResult(SafetyNetHelper.java:121)
at com.google.android.gms.common.api.internal.BasePendingResult$CallbackHandler.handleMessage(Unknown Source:10)
at android.os.Handler.dispatchMessage(Handler.java:106)
at com.google.android.gms.internal.base.zap.dispatchMessage(Unknown Source:8)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6711)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:911)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.safetynet.SafetyNetApi$AttestationResult" on path: DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/com.myappSnawgpdOpiE20CcOc0oO_Q==/base.apk"],nativeLibraryDirectories=[/data/app/com.myapp-SnawgpdOpiE20CcOc0oO_Q==/lib/arm64, /data/app/com.myapp-SnawgpdOpiE20CcOc0oO_Q==/base.apk!/lib/arm64-v8a, /system/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)

Regards.

Use new advice field in the JWS payload

There is a new, undocumented, advice field that is present in the SafetyNet payload. It would be cool if we showed that advice on screen so users can know how to remediate their failures. This is still not documented as Google is iterating on the field.

Response signature validation: error on version 0.9

With the version 0.9 I get:

SafetyNet request: success
Response signature validation: error

Error Msg:
Response signature validation error: https://www.googleapis.com/androidcheck/v1/attestations/verify?key=...

I was passing correctly in the previous version and it still passing in another app called "SafetyNet Test".

Create exmaple server side implementation to improve safetynet strength

Based on feedback from Google's security team, for the safetynet to be more secure way of checking device integrity the

  • generate the nonce on the server, and have the server implement anti-replay
  • Verification of nonce performed server side
  • Verification of JWS should also be performed on the server side because the crypto libraries on your device may have been owned and hence it can return verified even if it's not.

Permission

All write permission on all files and folders

Safetynet Issue Status{statusCode=NETWORK_ERROR, resolution=null}

We are facing error of “Status{statusCode=NETWORK_ERROR, resolution=null}” event though 4G internet connectivity available in our android device with package name com.safetynet.sample where as sample project is working fine with package name com.scottyab.safetynet.sample

Add Missing Checks for Server Implementation to README

The bullet points from the quote snippit below are missing from the README about verifying the compatibility check response server side:

Verify the compatibility check response
You should take steps to make sure the response received by your app actually came from the SafetyNet service and matches the request data you provided. Follow these steps to verify the origin of the JWS message:

  • Extract the SSL certificate chain from the JWS message.
  • Validate the SSL certificate chain and use SSL hostname matching to verify that the leaf certificate was issued to the hostname attest.android.com.
  • Use the certificate to verify the signature of the JWS message.

After completing this validation, you should also check the data of the JWS message to make sure it matches your original request, including the nonce, timestamp, package name, and the SHA-256 hashes. You can perform these validation steps within your app, or as a more secure option, send the entire JWS response to your own server for verification, via a secure connection.

(From https://developer.android.com/training/safetynet/index.html)

Add extra validation checks

Finish the safetynet api response payload validation signature and .apk checksum.

Update: the code is pushed for these but commented out as I couldn't figure out how the digests for the app signature and .apk checksum were calculated.

I always receive 2 calls when invoke to the method requestTest

Hi!

Now when I invoke to method requestTest I always receive 2 calls onSuccess. I was reviewing the code and I found that first the library sends a callback success and after passes the call to AndroidDeviceVerifier and the AndroidDeviceVerifier returns another success response. In total 2 calls to methods success.

But I only need one call to method success. Why do the library send me 2 calls on success? Will have something fix?

Inconsistent CTS check results

Skycure's security app alerted me that my Samsung Note 5 failed CTS check and therefore was suspected of having been tampered with. I downloaded Safetynet Helper and Cigital's Safetynet Playground for second opinions.

Cigital's app tells me everything is fine every time I run the test.

Safetynet Helper gives me seemingly random results. So far, the first result is always negative (CTS =false), but pressing it again results in CTS = true within 1-2 retestsAs I continue to retest, it continues jumping back and forth between true and false results.

Status{statusCode=INTERNAL_ERROR, resolution=null}

I have tried to do the same as mentioned but getting INTERNAL_SERVER error as status in ResultCallback onResult(@nonnull SafetyNetApi.AttestationResult attestationResult).

Your project is working perfectly but mine test project is not.

Please help us to resolve this. Thanks.

Remove apkDigestSha256 check as per Google's suggestion

Email from SafetyNet group:

Hi,

Starting in March 2018, Google Play will be adding a small amount of metadata to all apps, as discussed in this blog post. If you’re using the SafetyNet Attestation API for validation, there is a possibility that your app could stop working for some users. Please read our recommended course of action below.

What’s changing
The apkDigestSha256 value in the SafetyNet Attestation API response will be different from the original hash value of the APK that you previously uploaded to Google Play. This value will now be a hash of the APK that includes the new metadata.

Action recommended
If you are using the apkDigestSha256 field for validation, we recommend that you change your logic to use the apkCertificateDigestSha256 and apkPackageName instead. The certificate digest will become the most reliable way to verify your app’s APK based on the signing key. If you continue to use apkDigestSha256, your app might stop working for some users.

If you are unable to implement the above changes before March 2018 please complete this form.

Regards,
SafetyNet API Clients Team

This should take effect on March 1, 2018

Catching and display new "evaluationType" field in SafetyNet response

There is a new field in in SafetyNet responce calling "evaluationType" (new test based on TEE hardware)
https://groups.google.com/forum/#!msg/safetynet-api-clients/lpDXBNeV7Fg/Ov2H6ZvhBQAJ
It would be great to display this value along with other.
New SafetyNet response payload:

{
"nonce":"J24WvVT+O4pfPlnOsrlTVn7RA7BXbY1WKcqzrlDXs40=",
"timestampMs":1591307294529,
"apkPackageName":"com.scottyab.safetynet.sample",
"apkDigestSha256":"xQOTLnqhtdLHN/daI6tSRAY6wT760nFEuyBF8JdJeQU=",
"ctsProfileMatch":true,
"apkCertificateDigestSha256":["MZNsDhz8VAJMmFxPPso38ZRvZE6r7VIyzUqypkakG8E="],
"basicIntegrity":true,
"evaluationType":"BASIC"
}

Verify the JWS Response

How can we verify the JWS response has signed by Google? I think that there is 2 ways to do it. Manually or using Google Device Verification API. In Android Developers page, there is a Note about this API :

"You need an API key to access the Android Device Verification API, and the API is rate-limited. For these reasons, you should use the API only for testing during the initial development stage. You shouldn't use this verification API in a production scenario."

How can I verify the JWS response signed by Google via using offline solution ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.