skip to Main Content

I went down the rabbit hole reading about SSL Pinning and how to implement it in Flutter, And I have two questions:

  1. Is it secure to store (.pem) certificate file in assets? And if not, where to store it?
  2. Is it secure and better practice to hit on the server on app load and get the certificate from there instead of storing it in app

I’m currently storing the certificate file in assets and fetching the path to it from app_settings.json using GlobalConfiguration().getValue() method.

2

Answers


    1. That’s how it usually works AFAIK
    2. In this case the first API call isn’t protected from MITM attack and SSL pinning purpose becomes broken

    We used this plugin while implemented SSL pinning in our app (our client used Dio).

    To implement this plugin you need to find corresponding fingerprint of your server certificate:

    1. Click "lock" icon at the url address line
    2. "Connection is secure"
    3. "Certificate is valid"
    4. General
    5. Look for SHA-256 fingerprint at the Fignerprints section

    Then you need to write this fingerprint into a constant list in your app to be used by the plugin.

    The check should happen for EACH request you send because this is the main security purpose of SSL pinning – to check whether somebody modifies the request in the middle, between a server and a client. As per using Dio, you can use InterceptorWrapper to perform checks. The checker will look like:

    class SslPinningInterceptor extends InterceptorsWrapper {
      @override
      Future<void> onRequest(
        RequestOptions options,
        RequestInterceptorHandler handler,
      ) async {
        try {
          // if the fingerprints do not match the plugin will throw a PlatformException 
          // SslPinningPlugin.check
    
          // you can perform handler.next here because the exception hasn't been thrown
        } on PlatformException catch (_) {
          // you can perform handler.reject because check hasn't passed
        }
      }
    
        @override
        void onResponse(Response response, ResponseInterceptorHandler handler) {
          // handler.next
        }
    
        @override
        void onError(DioError err, ErrorInterceptorHandler handler) {
          // handler.next
        }
    }
    
    Login or Signup to reply.
  1. Your Problem

    Is it secure to store (.pem) certificate file in assets? And if not, where to store it?

    No where in the app is secure to store it because it’s easy to extract via static binary analyses. The attacker will take the binary de-compile it with one of the many open-source tools out there, for example MobSF – Mobile Security Framework:

    Mobile Security Framework is an automated, all-in-one mobile application (Android/iOS/Windows) pen-testing framework capable of performing static analysis, dynamic analysis, malware analysis and web API testing.

    In a series of articles about Mobile API Security I show how to use MobSF to extract an API key, but the principle would be the same to extract a pem certificate. To have an idea on how MobSF can be used to decompile your app take a look to the article How to Extract an API key from a Mobile App with Static Binary Analysis:

    The range of open source tools available for reverse engineering is huge, and we really can’t scratch the surface of this topic in this article, but instead we will focus in using the Mobile Security Framework(MobSF) to demonstrate how to reverse engineer the APK of our mobile app. MobSF is a collection of open source tools that present their results in an attractive dashboard, but the same tools used under the hood within MobSF and elsewhere can be used individually to achieve the same results.

    During this article we will use the Android Hide Secrets research repository that is a dummy mobile app with API keys hidden using several different techniques.

    TOFU (Trust on First Use)

    Is it secure and better practice to hit on the server on app load and get the certificate from there instead of storing it in app

    Not recommended to trust on the first usage, because you are trusting to retrieve the certificatie on the first API request made by your mobile app, thus making it easier for an attacker to bypass your pinning by MitM attack this first request and provide instead it’s own certificate.

    Possible Solutions

    I really don’t recommend you to store the certificate in your mobile app, neither I recommend to use a PEM certificate to perform pinning due its operational complexities and how easy is to get it stolen, instead I recommend you to use public key pinning, where you pin to the hash of leaf, intermediate or root certificate, thus you only need to change pinning on your app when the pinned certificate its renewed with a different private key. Another benefit it’s that your PEM certificate it’s not anymore for grab by attackers and the public key hash used for pinning it’s not a secret, after all it’s an hash of the public key.

    Using the PEM Certificate

    Now, if you insist in going down this root of using a PEM certificate then you need a mechanism to only deliver the PEM certificate to the mobile app when it’s not running in a compromised device (rooted, jail broken), not running on an emulator, no debugger attached, not under a MitM attack, not being instrumented at runtime by Frida or similar, and that the mobile app itself is the same exact one that you uploaded to the official store, not a repackaged/cloned one. In other words you need to attest the device and app integrity before you return the PEM certificate from your server, as you suggested in 2:

    1. Is it secure and better practice to hit on the server on app load and get the certificate from there instead of storing it in app

    Read more about this approach in this answer to the question How to use an API from my mobile app without someone stealing the token where you will secure the PEM certificate as I suggest to secure the API token, by using a Runtime Secrets Protection.

    Public Key Pinning

    Did you considered to perform certificate pinning through the public key (not private, like the pem file) of the certificate? Android and iOS support this via configuration

    Android docs:

    Normally, an app trusts all pre-installed CAs. If any of these CAs were to issue a fraudulent certificate, the app would be at risk from an on-path attacker. Some apps choose to limit the set of certificates they accept by either limiting the set of CAs they trust or by certificate pinning.

    Certificate pinning is done by providing a set of certificates by hash of the public key (SubjectPublicKeyInfo of the X.509 certificate). A certificate chain is then valid only if the certificate chain contains at least one of the pinned public keys.

    iOS docs:

    If your app sends or receives data over the network, it’s critical to preserve the privacy and integrity of a person’s information and protect it from data breaches and attacks. You should use the Transport Layer Security (TLS) protocol to protect content in transit and authenticate the server receiving the data.

    When you connect through TLS, the server provides a certificate or certificate chain to establish its identity. You can further limit the set of server certificates your app trusts by pinning their public-key identities in your app. Here’s how to get started.

    For example, to generate the config for Android and iOS you can use the Mobile Certificate Pinning Generator online tool:

    Android App Example:

    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <domain-config>
            <domain includeSubdomains="true">approov.io</domain>
            <pin-set expiration="2023-07-21">
                <pin digest="SHA-256">INBbf7pLOYb+mX9IcJDaUPxo6DSqKObPtdy+uT92ccQ=</pin>
            </pin-set>
        </domain-config>
    </network-security-config>
    

    iOS App Example:

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSPinnedDomains</key>
        <dict>
            <key>approov.io</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSPinnedLeafIdentities</key>
                <array>
                    <dict>
                        <key>SPKI-SHA256-BASE64</key>
                        <string>INBbf7pLOYb+mX9IcJDaUPxo6DSqKObPtdy+uT92ccQ=</string>
                    </dict>
                </array>
            </dict>
        </dict>
    </dict>
    

    You can check in more detail how its done for Android on the article
    Securing HTTPS with Certificate Pinning:

    In order to demonstrate how to use certificate pinning for protecting the https traffic between your mobile app and your API server, we will use the same Currency Converter Demo mobile app that I used in the previous article.

    In this article we will learn what certificate pinning is, when to use it, how to implement it in an Android app, and how it can prevent a MitM attack.

    Do You Want To Go The Extra Mile?

    In any response to a security question I always like to reference the excellent work from the OWASP foundation.

    For APIS

    OWASP API Security Top 10

    The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.

    For Mobile Apps

    OWASP Mobile Security Project – Top 10 risks

    The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.

    OWASP – Mobile Security Testing Guide:

    The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search