关于flutter:保护你的-Flutter-应用程序

1次阅读

共计 6524 个字符,预计需要花费 17 分钟才能阅读完成。

爱护你的 Flutter 应用程序

原文 https://medium.com/flutter-co…

如果本文对你有帮忙,请转发让更多的敌人浏览。

如果您不晓得须要更改哪些内容以及这些内容如何影响整个构建,那么爱护 Flutter 应用程序可能是一项工作,但在生产应用程序时,这是惟一最重要的事件。

爱护 Flutter 应用程序的平安应该是每个开发人员都必须认真对待的事件,因为这间接影响到应用程序的最终用户。他们的数据和通过 Internet 产生在您的应用程序之间的所有通信都可能受到各种攻打,意识到这些危险并采取措施防备这些危险应该是每个开发人员的责任。

Flutter + Security = ❤

这里须要留神的一点是,我在本文中提到的所有内容都取决于您的应用程序是否须要它。您必须决定这对您的应用程序是否至关重要。

首先,让咱们从一些根本的列表我的项目开始,而后转向更加技术性的列表我的项目。

应用受信赖的软件包,总体上应用较少的软件包(如果可能的话)

大多数应用程序的性能或 UI 组件将依赖于内部包,确保所应用的包由受信赖的开发人员开发、保护良好并被相当多的人应用十分重要。这样做的起因是,在呈现问题的状况下,因为应用它的人数较多,所以它被提前发现。Dev 得分和受欢迎水平应该是一个很好的终点。

始终通过 HTTPS 进行通信

如果您的应用程序与内部 API 和服务通信,请确保应用程序与近程服务器之间的通信是通过 HTTPS 进行的,以便数据在传输过程中被加密,并且在传输过程中没有内部黑客能够轻易拜访数据。简直所有在互联网上的货色都曾经迁徙到应用 HTTPS,所以这真的不应该再是一个选项,而是一种默认的做事形式。

HTTP vs HTTPS

正确的错误处理和消息传递

有可能抛出异样的函数应该总是放在 try-catch 块中,这样就不会给用户带来不可预感的应用程序解体。除此之外,向用户显示有用的错误信息也是一个很好的做法,然而始终不要显示谬误的确切细节,因为这些信息可能 / 能够很容易地用来找到破绽。

import 'package:flutter/material.dart';

Future<dynamic> functionThatThrowsException() async {
  // some code
  throw Exception('Could not perform operation.');
}

Future<void> testFunction() async {
  try {var x = await functionThatThrowsException();
    // do something with x
  } catch (e) {debugPrint(e.toString());
  }
}

Try Catch with Flutter

当 Flutter 应用程序生产公布,如果产生谬误,灰色屏幕显示给用户,这能够从用户的观点令人丧气。因而,显示一个有用的谬误小部件 / 屏幕可能是简化用户体验的好办法。

return MaterialApp(
      title: 'Flutter App',
      builder: (context, widget) {ErrorWidget.builder = (FlutterErrorDetails errorDetails) {return CustomErrorWidget(errorDetails: errorDetails);
        };
        return widget ?? const Scaffold();},
    ...
    ...


class CustomErrorWidget extends StatelessWidget {
  final FlutterErrorDetails errorDetails;

  const CustomErrorWidget({
    Key? key,
    required this.errorDetails,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const Card(
      color: Colors.red,
      margin: EdgeInsets.zero,
      child: Padding(padding: EdgeInsets.all(8.0),
        child: Text(
          "Something is not right here...",
          style: TextStyle(
            color: Colors.white,
            fontWeight: FontWeight.bold,
          ),
        ),
      ),
    );
  }
}

Displaying a Custom Error Widget

📱Minimal Permissions

确保只应用您须要的足够的应用程序权限。如果某个特定权限对应用程序的运行不是必须的,请防止应用它。在不必要的状况下应用权限会使应用程序裸露在商店的审查之下。此外,如果您没有正确应用这些权限,则可能进犯用户的隐衷。随着寰球范畴内的数据和隐衷政策日益严格,这一问题变得极其重大。

始终加密数据

在设施上存储数据 (如令牌或任何 PII) 时,应始终应用平台的平安存储对这些数据进行加密。一个十分有用的软件包就是 flutter_security_Storage。此包是一个简略的键 - 值对加密存储,非常适合用于存储简略数据类型。现实状况下,应该尽量减少存储在设施上的数据,然而如果因为性能进步或其余起因须要存储比键 - 值对更多的数据,那么 hive 可能十分有用。Hive 是 NoSQL,为 Dart 编写的设施上数据库,性能极佳,反对 AES-256 加密开箱即用。

import 'package:flutter_secure_storage/flutter_secure_storage.dart';

Future<void> secureStorageActions() async {
// Create storage
  const storage = FlutterSecureStorage();

// Read value
  String? value = await storage.read(key: 'key');

// Read all values
  Map<String, String> allValues = await storage.readAll();

// Delete value
  await storage.delete(key: 'key');

// Delete all
  await storage.deleteAll();

// Write value
  await storage.write(key: 'key', value: 'value');
}

Using Flutter Secure Storage

接下来是更简单的倡议。

代码混同

代码混同是将人类可读的代码转换成看似垃圾的读代码,使攻击者更难了解捆绑是否被反编译以进行反向工程。在 Flutter 2.0 + 上,本地平台默认曾经做到了这一点,对于混同 Dart 代码,咱们能够蕴含——含糊标记以及带有含糊符号地位的—— split-debug-info 标记。而后能够应用这些符号将混同后的代码转换回可读代码,以便在须要时调试问题。

flutter build appbundle --obfuscate --split-debug-info=./symbols/
Flutter build appbundle —— obfuscate —— split-debug-info = ./marks/
flutter build apk --obfuscate --split-debug-info=./symbols/
Flutter build apk —— obbuscate —— split-debug-info = ./marks/
flutter build ios --obfuscate --split-debug-info=./symbols/
Flutter build ios —— obbuscate —— split-debug-info = ./marks/

SSL Pinning

SSL 固定是一种安全措施,它将可信证书的身份固定在挪动应用程序上,并阻止来自可疑服务器的未知文档。带有固定 SSL 证书的应用程序依赖于其存储的证书,而不是依赖于证书颁发机构存储许可证。应用这种技术,您能够在开发期间将 SSL 证书主机ーー可信证书列表固定到您的应用程序,并在运行期间进一步比拟服务器证书与列表。

You can read more about SSL Pinning here: https://medium.com/@anuj.rai2489/ssl-pinning-254fa8ca2109

你能够在这里浏览更多对于 SSL 固定的内容: https://medium.com/@anuj.rai2…

SSL Pinning

因而,要实现这一点,咱们须要:

  • Pem 格局的证书
  • 预申请钩子处理程序

要取得所需格局的证书,首先须要从 Web 浏览器下载该证书,该证书将位于。Cerformat,而后应用以下命令:

openssl x509 -in cert.cer -out cert.pem
Openssl x509-in cert.cer.out cert.pem

而后在所选的 http 库中的预申请钩子处理程序中应用 verifyHandshake 函数。

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/io_client.dart';

Future<SecurityContext> get globalContext async {final sslCert = await rootBundle.load('assets/certs/ryandsilva-dev.pem');
  final sc = SecurityContext(withTrustedRoots: false);
  sc.setTrustedCertificatesBytes(sslCert.buffer.asInt8List());
  return sc;
}

Future<bool> verifyHandshake(String url) async {
  try {final client = HttpClient(context: await globalContext);
    client.badCertificateCallback = ((cert, host, port) => false);
    final ioClient = IOClient(client);
    await ioClient.get(Uri.parse(url));
    return true;
  } catch (e) {debugPrint('Could not complete SSL handshake: ${e.toString()}');
    return false;
  }
}

bool isSecureConnection = await verifyHandshake('https://ryandsilva.dev/');

SSL Pinning

网络安全配置(Android 专用)

这是本机配置,使应用程序只能与强制 HTTPS 连贯的容许域进行通信。Security_config.xml 文件应该蕴含应用程序须要与之通信的所有域的条目。Include 蕴含子域参数指定是否要蕴含主域的所有子域。如果抉择不包含所有子域,则能够在域列表中独自指定每个子域。中增加到以下地位的每个域的证书。Pem 格局: android/app/src/main/res/raw 和 security_config.xml 文件位于 android/app/src/main/res/xml 文件夹中。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="dev.ryandsilva.flutter_app">
   <application
        android:label="flutter_app"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher"
        android:networkSecurityConfig="@xml/security_config">
  ...
  ...
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="false">
        <domain includeSubdomains="true">ryandsilva.dev</domain>
        <trust-anchors>
            <certificates src="@raw/ryandsilva-dev"/>
        </trust-anchors>
    </domain-config>
</network-security-config>

平安配置 ー Android

NSAppTransportation 平安(仅限 iOS)

这是本机配置,使应用程序只能与强制 HTTPS 连贯的容许域进行通信。NSExceptionDomains 键应该蕴含应用程序须要与之通信的所有域的条目。NSPackesSubdomain 键指定是否要包含主域的所有子域。如果抉择不包含所有子域,则能够在域列表中独自指定每个子域。上面的代码片段应该附加到 IOS/Runner 下的 Info.plist 文件。

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>ryandsilva.dev</key>
        <dict>
            <!--Include to allow subdomains-->
            <key>NSIncludesSubdomains</key>
            <true/>
            <!--Include to allow HTTP requests-->
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <false/>
        </dict>
    </dict>
</dict>

NSAppTransportSecurity Config — iOS

越狱及本源侦测

依据应用程序的类型,您可能心愿限度在有根 / 破解设施上的应用。不容许您的应用程序在植根 / 破解设施上运行将阻止黑客拜访设施上的应用程序数据和其余可能危害您的应用程序的流动。为此,咱们将应用 flutter_jailbreak_check 包。

import 'dart:io';

import 'package:flutter/services.dart';
import 'package:flutter_jailbreak_detection/flutter_jailbreak_detection.dart';

Future<bool> checkJailbrokenOrRooted() async {
  bool jailbrokenOrRooted = true;
  try {if (Platform.isAndroid) {jailbrokenOrRooted = await FlutterJailbreakDetection.developerMode;} else if (Platform.isIOS) {jailbrokenOrRooted = await FlutterJailbreakDetection.jailbroken;} else {jailbrokenOrRooted = true;}
    return jailbrokenOrRooted;
  } on PlatformException {
    jailbrokenOrRooted = true;
    return jailbrokenOrRooted;
  }
}

根 / 越狱检测

谢谢!


如果本文对你有帮忙,请转发让更多的敌人浏览。

© 猫哥

  • 微信 ducafecat
  • https://wiki.ducafecat.tech
  • https://video.ducafecat.tech
正文完
 0