DEV Community

Harsh Bangari Rawat
Harsh Bangari Rawat

Posted on

Implementing SSL Pinning in Flutter

HTTPS

While HTTPS encrypts communication between your app and the server, it relies on certificates issued by trusted authorities to verify the server's identity. Without additional security measures, the app might accept a fraudulent certificate presented by a Man-in-the-Middle MITM attacker. This attacker could then intercept and decrypt sensitive data like login credentials or financial information.

Regular HTTPS relies on trusting external authorities to verify a server's identity. SSL pinning adds an extra layer of security by checking if the server's certificate matches a "fingerprint" stored directly in your app. If they don't match, the app can block the connection, preventing imposters from eavesdropping on your communication.

SSL certificates, like passports, expire to maintain security. Even though your app itself might not change, updating the app with the new certificate ensures a secure connection.

Manual Implementation using http package

You'll need to:

  • Load the trusted certificate (usually in PEM format) from your assets.
  • Configure the SecurityContext to trust only the loaded certificate(s).
  • Use the SecurityContext with your HTTP client (e.g., HttpClient) to make secure connections.

1. Add ssl_certificate.pem into pubspec.yaml

# The following section is specific to Flutter packages.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true


  assets:
    - assets/ssl_certificate.pem
    - assets/app-logo.png
Enter fullscreen mode Exit fullscreen mode

2. Create Future to Load Certificate

Future<SecurityContext> get sslClient async {
  final sslCert = await rootBundle.load('assets/ssl_certificate.pem');
  SecurityContext securityContext = SecurityContext(withTrustedRoots: false);
  securityContext.setTrustedCertificatesBytes(sslCert.buffer.asInt8List());

  HttpClient client = HttpClient(context: securityContext);
  client.badCertificateCallback =
      (X509Certificate cert, String host, int port) => false;
  IOClient ioClient = IOClient(client);
  return ioClient;
}
Enter fullscreen mode Exit fullscreen mode

Here enabling SSL pinning by loading a trusted certificate from the app's assets and configuring the SecurityContext to only trust that specific certificate. This provides an extra layer of security for network connections by preventing man-in-the-middle attacks with fraudulent certificates.

Important points to consider:

  • Make sure the certificate file in your assets is valid and belongs to the server you want to connect to securely.
  • Updating the app might be necessary if the server's certificate changes and needs to be replaced in the assets.

Testing SSL Pinning

  • Valid Certificate

Your app will be able to establish a secure connection with the server.

  • Invalid Certificate ⚠️

Using an invalid or expired certificate poses a security risk. Your app won't be able to establish a secure connection with the server, potentially exposing sensitive data to eavesdroppers.
You might encounter exceptions like HandshakeException or CertificateNotFoundException in such scenarios.

By following the implementation steps you can effectively bolster the communication channel between your app and its backend servers.

Remember, SSL pinning is just one piece of the security puzzle.

Always adhere to secure coding practices and stay updated on the latest security threats to maintain a robust defense for your Flutter app.

Happy Coding! 🧑🏻‍💻

Top comments (4)

Collapse
 
naif_alluhaidanengr_aa profile image
Naif Alluhaidan (Engr)

isn't this not good way? because the certificate will be attached to apk file. hence, attacker can obtain certificate file from assets and use it.
is there any other way that either i can provide my certificate but it won't be attached in the apk file (no security concern exist)? or is there a way to do it without giving my server certificate to my flutter app? like attaching only hashed public key of server certificate or something like this, so if attacker obtain it, he can't use it.
thanks.

Collapse
 
harsh8088 profile image
Harsh Bangari Rawat

You're right to be concerned about embedding the certificate directly into your APK. This could potentially expose your private key to attackers, compromising the security of your app.
Using Server-Side Certificate Validation and Public Key Pinning (PKP) approaches one can mitigate these security risks.
The best approach will depend on the specific security requirements and technical expertise.

Collapse
 
_a0c62b87e99b32fd21e92 profile image
林子煬

Sorry, I would like to ask, if I want to bind credentials for firebase cloud functions, what should I do?

Collapse
 
harsh8088 profile image
Harsh Bangari Rawat

Credentials for Firebase Cloud Functions are managed on the server-side, not the client-side (Flutter).

Right Approach

Hope this helps!👍