diff --git a/siro_admin/lib/controller/functions/crud.dart b/siro_admin/lib/controller/functions/crud.dart index d80b5d8..da7c85c 100644 --- a/siro_admin/lib/controller/functions/crud.dart +++ b/siro_admin/lib/controller/functions/crud.dart @@ -17,9 +17,11 @@ import '../../print.dart'; import 'device_info.dart'; import 'encrypt_decrypt.dart'; import 'security_checks.dart'; +import 'ssl_pinning.dart'; class CRUD { var dev = ''; + final _client = SslPinning.createPinnedClient(); getJWT() async { // إذا كان الأدمن مسجل دخوله بالفعل، لا تقم بتوليد توكن "ضيف" قديم if (box.read(BoxName.driverID) != null) { @@ -35,7 +37,7 @@ class CRUD { 'aud': '${AK.allowed}$dev', }; Log.print('payload: ${payload}'); - var response1 = await http.post( + var response1 = await _client.post( Uri.parse(AppLink.loginJwtDriver), body: payload, ); @@ -85,7 +87,7 @@ class CRUD { Log.print('URL: $link'); Log.print('Payload: $payload'); - var response = await http.post( + var response = await _client.post( url, body: payload, headers: { @@ -142,7 +144,7 @@ class CRUD { Log.print('URL: $link'); Log.print('Payload: $payload'); - var response = await http.post( + var response = await _client.post( url, body: payload, headers: { @@ -210,7 +212,7 @@ class CRUD { 'Wallet SSO token starts with: ${mainToken.substring(0, mainToken.length > 10 ? 10 : mainToken.length)}'); // استخدام الـ SSO للسيرفر الرئيسي إذا كان الأدمن مسجل دخوله - var response1 = await http.post( + var response1 = await _client.post( Uri.parse(AppLink.loginWalletAdminV3), headers: { 'Authorization': 'Bearer $mainToken', @@ -254,7 +256,7 @@ class CRUD { 'aud': '${Env.allowedWallet}${Platform.isAndroid ? 'android' : 'ios'}', 'fingerPrint': fingerPrint }; - var fallbackRes = await http.post( + var fallbackRes = await _client.post( Uri.parse(AppLink.loginWalletAdmin), body: payload, ); @@ -287,7 +289,7 @@ class CRUD { } try { - var response = await http.post( + var response = await _client.post( url, body: payload, headers: { @@ -345,7 +347,7 @@ class CRUD { try { // await LoginDriverController().getJWT(); - var response = await http.post( + var response = await _client.post( url, body: payload, headers: { @@ -397,7 +399,7 @@ class CRUD { required String uid, }) async { var uid = box.read(BoxName.phone) ?? box.read(BoxName.phoneDriver); - var res = await http.get( + var res = await _client.get( Uri.parse( 'https://repulsive-pig-rugby-shirt.cyclic.app/token?channelName=$channelName'), headers: {'Authorization': 'Bearer ${AK.agoraAppCertificate}'}); @@ -434,7 +436,7 @@ class CRUD { ], "temperature": 0.9 }); - var response = await http.post( + var response = await _client.post( url, body: data, headers: headers, @@ -564,7 +566,7 @@ class CRUD { ], "temperature": 0.9 }); - var response = await http.post( + var response = await _client.post( url, body: data, headers: headers, @@ -613,7 +615,7 @@ class CRUD { "receiver": phone }); - var res = await http.post( + var res = await _client.post( Uri.parse(AppLink.sendSms), body: body, headers: headers, @@ -629,7 +631,7 @@ class CRUD { var url = Uri.parse( link, ); - var response = await http.post(url, + var response = await _client.post(url, body: payload, headers: {'Content-Type': 'application/json'}); var jsonData = jsonDecode(response.body); @@ -671,7 +673,7 @@ class CRUD { var url = Uri.parse( link, ); - var response = await http.post( + var response = await _client.post( url, body: payload, headers: { @@ -707,7 +709,7 @@ class CRUD { 'https://verify.twilio.com/v2/Services/$verifySid/Verifications'); // Send the verification request - final response = await http.post( + final response = await _client.post( verificationUri, headers: { 'Authorization': @@ -730,7 +732,7 @@ class CRUD { final checkUri = Uri.parse( 'https://verify.twilio.com/v2/Services/$verifySid/VerificationCheck'); - final checkResponse = await http.post( + final checkResponse = await _client.post( checkUri, headers: { 'Authorization': @@ -754,7 +756,7 @@ class CRUD { var url = Uri.parse( link, ); - var response = await http.post( + var response = await _client.post( url, body: payload, ); diff --git a/siro_admin/lib/controller/functions/ssl_pinning.dart b/siro_admin/lib/controller/functions/ssl_pinning.dart new file mode 100644 index 0000000..e571778 --- /dev/null +++ b/siro_admin/lib/controller/functions/ssl_pinning.dart @@ -0,0 +1,41 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:crypto/crypto.dart'; +import 'package:http/http.dart' as http; + +class SslPinning { + SslPinning._(); + + static final Map> _pins = { + 'intaleq.xyz': [ + '/tNRUeeLxUhQU5gbgdpVWC6QBGAqc/ujg8Kcf0wQiAM=', + 'Hlx/0EWNDH5Xkt2KzvqxUzbw0vvEsyZSlibialSyGqI=', + ], + 'siromove.com': [ + 'C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHESsl=', + 'diGVwiVYbubAI3RW4hB9xU8e/CH2GnkuvVFZE8zmgzI=', + ], + }; + + static final List _globalPins = [ + 'Ex/Od4QBaJmloAIDqe/IDxjrvXVYBxftwVU1gJMINuw=', + 'lrzsBiZJdvN0YHeazyjFp8/oo8Cq4RqP/O4FwL3fCMY=', + 'aXKbjhWobvwXelevtxcd/GSt0owvyozxUH40RTzLFHA=', + ]; + + static http.Client createPinnedClient() { + final httpClient = HttpClient() + ..badCertificateCallback = + (X509Certificate cert, String host, int port) { + final derHash = base64.encode(sha256.convert(cert.der).bytes); + for (final entry in _pins.entries) { + if (host.endsWith(entry.key)) { + if (entry.value.contains(derHash)) return true; + } + } + if (_globalPins.contains(derHash)) return true; + return false; + }; + return http.IOClient(httpClient); + } +} diff --git a/siro_admin/pubspec.yaml b/siro_admin/pubspec.yaml index dbe95fb..ad43727 100644 --- a/siro_admin/pubspec.yaml +++ b/siro_admin/pubspec.yaml @@ -49,6 +49,7 @@ dependencies: flutter_map: ^7.0.0 # مكتبة OpenStreetMap للفلاتر latlong2: ^0.9.1 http: ^1.0.0 + crypto: ^3.0.3 # image: ^4.1.7 image_cropper: ^8.0.2 image_picker: ^1.1.1 diff --git a/siro_driver/lib/controller/functions/crud.dart b/siro_driver/lib/controller/functions/crud.dart index 677f522..fe9714a 100755 --- a/siro_driver/lib/controller/functions/crud.dart +++ b/siro_driver/lib/controller/functions/crud.dart @@ -16,9 +16,11 @@ import '../../constant/api_key.dart'; import '../../views/widgets/error_snakbar.dart'; import 'gemeni.dart'; import 'upload_image.dart'; +import 'ssl_pinning.dart'; class CRUD { final NetGuard _netGuard = NetGuard(); + final _client = SslPinning.createPinnedClient(); static bool _isRefreshingJWT = false; static String _lastErrorSignature = ''; @@ -251,7 +253,7 @@ class CRUD { } var url = Uri.parse(link); - var response = await http.post( + var response = await _client.post( url, body: payload, headers: { @@ -327,7 +329,7 @@ class CRUD { final hmac = box.read(BoxName.hmac); var url = Uri.parse(link); - var response = await http.post( + var response = await _client.post( url, body: payload, headers: { @@ -371,7 +373,7 @@ class CRUD { final url = Uri.parse(link); try { - final response = await http.post( + final response = await _client.post( url, body: payload, headers: { @@ -437,7 +439,7 @@ class CRUD { required String uid, }) async { var uid = box.read(BoxName.phone) ?? box.read(BoxName.phoneDriver); - var res = await http.get( + var res = await _client.get( Uri.parse( 'https://orca-app-b2i85.ondigitalocean.app/token?channelName=$channelName'), headers: {'Authorization': 'Bearer ${AK.agoraAppCertificate}'}, @@ -470,7 +472,7 @@ class CRUD { ], 'temperature': 0.9, }); - var response = await http.post(url, body: data, headers: headers); + var response = await _client.post(url, body: data, headers: headers); if (response.statusCode == 200) return response.body; return response.statusCode; } @@ -536,7 +538,7 @@ class CRUD { ], 'temperature': 0.9, }); - var response = await http.post(url, body: data, headers: headers); + var response = await _client.post(url, body: data, headers: headers); if (response.statusCode == 200) return response.body; return response.statusCode; } @@ -544,7 +546,7 @@ class CRUD { Future postPayMob( {required String link, Map? payload}) async { var url = Uri.parse(link); - var response = await http.post(url, + var response = await _client.post(url, body: payload, headers: {'Content-Type': 'application/json'}); var jsonData = jsonDecode(response.body); if (response.statusCode == 200) { @@ -585,7 +587,7 @@ class CRUD { Future postFromDialogue( {required String link, Map? payload}) async { var url = Uri.parse(link); - var response = await http.post( + var response = await _client.post( url, body: payload, headers: { @@ -609,7 +611,7 @@ class CRUD { final authToken = AK.authTokenTwillo; final verifySid = AK.twilloRecoveryCode; - await http.post( + await _client.post( Uri.parse( 'https://verify.twilio.com/v2/Services/$verifySid/Verifications'), headers: { @@ -624,7 +626,7 @@ class CRUD { Future getGoogleApi( {required String link, Map? payload}) async { var url = Uri.parse(link); - var response = await http.post(url, body: payload); + var response = await _client.post(url, body: payload); var jsonData = jsonDecode(response.body); if (jsonData['status'] == 'OK') return jsonData; return jsonData['status']; @@ -664,7 +666,7 @@ class CRUD { }) async { var url = Uri.parse(link); try { - var response = await http.get( + var response = await _client.get( url, headers: { 'Content-Type': 'application/json', @@ -690,7 +692,7 @@ class CRUD { }) async { var url = Uri.parse(link); try { - var response = await http.post( + var response = await _client.post( url, body: jsonEncode(payload), headers: { diff --git a/siro_driver/lib/controller/functions/ssl_pinning.dart b/siro_driver/lib/controller/functions/ssl_pinning.dart new file mode 100644 index 0000000..e571778 --- /dev/null +++ b/siro_driver/lib/controller/functions/ssl_pinning.dart @@ -0,0 +1,41 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:crypto/crypto.dart'; +import 'package:http/http.dart' as http; + +class SslPinning { + SslPinning._(); + + static final Map> _pins = { + 'intaleq.xyz': [ + '/tNRUeeLxUhQU5gbgdpVWC6QBGAqc/ujg8Kcf0wQiAM=', + 'Hlx/0EWNDH5Xkt2KzvqxUzbw0vvEsyZSlibialSyGqI=', + ], + 'siromove.com': [ + 'C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHESsl=', + 'diGVwiVYbubAI3RW4hB9xU8e/CH2GnkuvVFZE8zmgzI=', + ], + }; + + static final List _globalPins = [ + 'Ex/Od4QBaJmloAIDqe/IDxjrvXVYBxftwVU1gJMINuw=', + 'lrzsBiZJdvN0YHeazyjFp8/oo8Cq4RqP/O4FwL3fCMY=', + 'aXKbjhWobvwXelevtxcd/GSt0owvyozxUH40RTzLFHA=', + ]; + + static http.Client createPinnedClient() { + final httpClient = HttpClient() + ..badCertificateCallback = + (X509Certificate cert, String host, int port) { + final derHash = base64.encode(sha256.convert(cert.der).bytes); + for (final entry in _pins.entries) { + if (host.endsWith(entry.key)) { + if (entry.value.contains(derHash)) return true; + } + } + if (_globalPins.contains(derHash)) return true; + return false; + }; + return http.IOClient(httpClient); + } +} diff --git a/siro_driver/pubspec.yaml b/siro_driver/pubspec.yaml index aca3265..bf978d6 100644 --- a/siro_driver/pubspec.yaml +++ b/siro_driver/pubspec.yaml @@ -45,6 +45,7 @@ dependencies: # Services & Hardware battery_plus: ^7.0.0 connectivity_plus: ^6.1.5 + crypto: ^3.0.3 device_info_plus: 11.2.2 envied: ^1.0.0 firebase_auth: ^6.3.0 diff --git a/siro_rider/lib/controller/functions/crud.dart b/siro_rider/lib/controller/functions/crud.dart index 41ee99a..15778a5 100644 --- a/siro_rider/lib/controller/functions/crud.dart +++ b/siro_rider/lib/controller/functions/crud.dart @@ -18,10 +18,11 @@ import 'upload_image.dart'; import 'dart:io'; import 'network/net_guard.dart'; +import 'ssl_pinning.dart'; class CRUD { final NetGuard _netGuard = NetGuard(); - final _client = http.Client(); + final _client = SslPinning.createPinnedClient(); /// Stores the signature of the last logged error to prevent duplicates. static String _lastErrorSignature = ''; @@ -220,7 +221,7 @@ class CRUD { }) async { final token = await _getJwt(); var url = Uri.parse(link); - var response = await http.post( + var response = await _client.post( url, body: payload, headers: { @@ -243,7 +244,7 @@ class CRUD { await Get.put(LoginController()).getJWT(); // إعادة المحاولة مرة واحدة فقط بتوكن جديد - var retryResponse = await http.post( + var retryResponse = await _client.post( url, body: payload, headers: { @@ -316,7 +317,7 @@ class CRUD { final hmac = box.read(BoxName.hmac); var url = Uri.parse(link); - var response = await http.post( + var response = await _client.post( url, body: payload, headers: { @@ -363,7 +364,7 @@ class CRUD { final url = Uri.parse(link); try { - final response = await http.post( + final response = await _client.post( url, body: payload, headers: { @@ -479,7 +480,7 @@ class CRUD { required String uid, }) async { var uid = box.read(BoxName.phone) ?? box.read(BoxName.phoneDriver); - var res = await http.get( + var res = await _client.get( Uri.parse( 'https://orca-app-b2i85.ondigitalocean.app/token?channelName=$channelName'), headers: {'Authorization': 'Bearer ${AK.agoraAppCertificate}'}, @@ -513,7 +514,7 @@ class CRUD { ], "temperature": 0.9 }); - var response = await http.post(url, body: data, headers: headers); + var response = await _client.post(url, body: data, headers: headers); if (response.statusCode == 200) return response.body; return response.statusCode; } @@ -539,7 +540,7 @@ class CRUD { var requestBody = {"url": imagePathFull}; var response = - await http.post(url, body: jsonEncode(requestBody), headers: headers); + await _client.post(url, body: jsonEncode(requestBody), headers: headers); if (response.statusCode == 200) { var responseBody = jsonDecode(response.body); @@ -568,7 +569,7 @@ class CRUD { ], "temperature": 0.9 }); - var response = await http.post(url, body: data, headers: headers); + var response = await _client.post(url, body: data, headers: headers); if (response.statusCode == 200) return response.body; return response.statusCode; } @@ -578,7 +579,7 @@ class CRUD { Map? payload, }) async { var url = Uri.parse(link); - var response = await http.post(url, + var response = await _client.post(url, body: payload, headers: {'Content-Type': 'application/json'}); var jsonData = jsonDecode(response.body); @@ -607,7 +608,7 @@ class CRUD { Map? payload, }) async { var url = Uri.parse(link); - var response = await http.post( + var response = await _client.post( url, body: payload, headers: { @@ -637,7 +638,7 @@ class CRUD { final Uri verificationUri = Uri.parse( 'https://verify.twilio.com/v2/Services/$verifySid/Verifications'); - await http.post( + await _client.post( verificationUri, headers: { 'Authorization': @@ -652,7 +653,7 @@ class CRUD { final checkUri = Uri.parse( 'https://verify.twilio.com/v2/Services/$verifySid/VerificationCheck'); - final checkResponse = await http.post( + final checkResponse = await _client.post( checkUri, headers: { 'Authorization': @@ -668,7 +669,7 @@ class CRUD { Map? payload, }) async { var url = Uri.parse(link); - var response = await http.post(url, body: payload); + var response = await _client.post(url, body: payload); var jsonData = jsonDecode(response.body); if (jsonData['status'] == 'OK') return jsonData; return jsonData['status']; @@ -677,7 +678,7 @@ class CRUD { Future getHereMap({required String link}) async { var url = Uri.parse(link); try { - var response = await http.get(url); + var response = await _client.get(url); if (response.statusCode == 200) { var decodedBody = utf8.decode(response.bodyBytes); return jsonDecode(decodedBody); @@ -693,7 +694,7 @@ class CRUD { }) async { var url = Uri.parse(link); try { - var response = await http.get( + var response = await _client.get( url, headers: { 'Content-Type': 'application/json', @@ -719,7 +720,7 @@ class CRUD { }) async { var url = Uri.parse(link); try { - var response = await http.post( + var response = await _client.post( url, body: jsonEncode(payload), headers: { diff --git a/siro_rider/lib/controller/functions/ssl_pinning.dart b/siro_rider/lib/controller/functions/ssl_pinning.dart new file mode 100644 index 0000000..e571778 --- /dev/null +++ b/siro_rider/lib/controller/functions/ssl_pinning.dart @@ -0,0 +1,41 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:crypto/crypto.dart'; +import 'package:http/http.dart' as http; + +class SslPinning { + SslPinning._(); + + static final Map> _pins = { + 'intaleq.xyz': [ + '/tNRUeeLxUhQU5gbgdpVWC6QBGAqc/ujg8Kcf0wQiAM=', + 'Hlx/0EWNDH5Xkt2KzvqxUzbw0vvEsyZSlibialSyGqI=', + ], + 'siromove.com': [ + 'C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHESsl=', + 'diGVwiVYbubAI3RW4hB9xU8e/CH2GnkuvVFZE8zmgzI=', + ], + }; + + static final List _globalPins = [ + 'Ex/Od4QBaJmloAIDqe/IDxjrvXVYBxftwVU1gJMINuw=', + 'lrzsBiZJdvN0YHeazyjFp8/oo8Cq4RqP/O4FwL3fCMY=', + 'aXKbjhWobvwXelevtxcd/GSt0owvyozxUH40RTzLFHA=', + ]; + + static http.Client createPinnedClient() { + final httpClient = HttpClient() + ..badCertificateCallback = + (X509Certificate cert, String host, int port) { + final derHash = base64.encode(sha256.convert(cert.der).bytes); + for (final entry in _pins.entries) { + if (host.endsWith(entry.key)) { + if (entry.value.contains(derHash)) return true; + } + } + if (_globalPins.contains(derHash)) return true; + return false; + }; + return http.IOClient(httpClient); + } +} diff --git a/siro_service/lib/controller/functions/crud.dart b/siro_service/lib/controller/functions/crud.dart index 82561c2..bf9b828 100644 --- a/siro_service/lib/controller/functions/crud.dart +++ b/siro_service/lib/controller/functions/crud.dart @@ -15,9 +15,11 @@ import 'package:siro_service/main.dart'; import 'package:siro_service/print.dart'; import '../../constant/api_key.dart'; +import 'ssl_pinning.dart'; class CRUD { static String? _appSignature; + final _client = SslPinning.createPinnedClient(); static String _lastErrorSignature = ''; static DateTime _lastErrorTimestamp = DateTime(2000); @@ -337,7 +339,7 @@ class CRUD { required String channelName, required String uid, }) async { - var res = await http.get( + var res = await _client.get( Uri.parse( 'https://orca-app-b2i85.ondigitalocean.app/token?channelName=$channelName'), headers: {'Authorization': 'Bearer '}); @@ -371,7 +373,7 @@ class CRUD { ], "temperature": 0.9 }); - var response = await http.post(url, body: data, headers: headers); + var response = await _client.post(url, body: data, headers: headers); if (response.statusCode == 200) { return response.body; diff --git a/siro_service/lib/controller/functions/ssl_pinning.dart b/siro_service/lib/controller/functions/ssl_pinning.dart new file mode 100644 index 0000000..e571778 --- /dev/null +++ b/siro_service/lib/controller/functions/ssl_pinning.dart @@ -0,0 +1,41 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:crypto/crypto.dart'; +import 'package:http/http.dart' as http; + +class SslPinning { + SslPinning._(); + + static final Map> _pins = { + 'intaleq.xyz': [ + '/tNRUeeLxUhQU5gbgdpVWC6QBGAqc/ujg8Kcf0wQiAM=', + 'Hlx/0EWNDH5Xkt2KzvqxUzbw0vvEsyZSlibialSyGqI=', + ], + 'siromove.com': [ + 'C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHESsl=', + 'diGVwiVYbubAI3RW4hB9xU8e/CH2GnkuvVFZE8zmgzI=', + ], + }; + + static final List _globalPins = [ + 'Ex/Od4QBaJmloAIDqe/IDxjrvXVYBxftwVU1gJMINuw=', + 'lrzsBiZJdvN0YHeazyjFp8/oo8Cq4RqP/O4FwL3fCMY=', + 'aXKbjhWobvwXelevtxcd/GSt0owvyozxUH40RTzLFHA=', + ]; + + static http.Client createPinnedClient() { + final httpClient = HttpClient() + ..badCertificateCallback = + (X509Certificate cert, String host, int port) { + final derHash = base64.encode(sha256.convert(cert.der).bytes); + for (final entry in _pins.entries) { + if (host.endsWith(entry.key)) { + if (entry.value.contains(derHash)) return true; + } + } + if (_globalPins.contains(derHash)) return true; + return false; + }; + return http.IOClient(httpClient); + } +}