maxtoyberman / react-native-ssl-pinning Goto Github PK
View Code? Open in Web Editor NEWReact Native ssl pinning and cookies handling based on okhttp3 on (Android). and AFNetworking on (iOS)
License: MIT License
React Native ssl pinning and cookies handling based on okhttp3 on (Android). and AFNetworking on (iOS)
License: MIT License
When I pin invalid/expired certificate in the fetch I see the error message as below :
'' java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. ''
which is not providing proper details on why the certificate pinning failed. It would be great if a more proper message will be shown...
Will there be support for api endpoint which is self-signed?
Hi @MaxToyberman ,
I need yor help.
I followed the guide and it works fine with android. However, it doesn't works with IOS. I tried GET and POST request, but I got this native error
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
I try to debug then it's stopped here
I don't know what's missing here
My config is RN 0.58.3 and react-native-ssl-pinning 1.4.0
How I bypass ssl pinning
I followed the guide and it works fine with android. However, it doesn't works with IOS. I tried GET and POST request, but I always get "Cancelled" as error.
I even tried to request other domains, but as said, nothing works.
My config is RN 0.61.5 and react-native-ssl-pinning ^1.4.0
Hi,
I am trying to make a secure GET request to Google Maps API but I keep getting very ambiguous error - error: cancelled.
My configuration is as follows:
fetch(URL, {
method: 'GET',
timeoutInterval: 10000,
sslPinning: {
certs: ['cert_google']
}
}
I have generated a certificate following the recommended steps and linked it to the XCode project.
Any ideas what is going wrong?
Thanks in advance.
I am using correct certificate but getting cancelled in catch of fetch as in error
Hi, I have a react native project which has API calls in React Native side and as well in native side (Java and Swift). Is it possible to support the native side?
I have successfully connected with my server with get request. But having trouble with post request with formData.
let data = new FormData()
let words = (image["uri"].split("/"))
data.append('sampleFile',
{
name: words[words.length - 1],
type: image["type"],
uri: image["uri"]
})
let url = 'https://mydomain.com/upload/'
fetch(url, {
method: "POST",
body: data,
sslPinning: {
certs: ["mycert"]
}
})
.then(res => console.log(res))
.catch(err => console.log(err))
I need a little bit help. I installed this module with yarn add.
my Code:
import {fetch} from 'react-native-ssl-pinning';
fetch(initUrl, {
method: 'GET',
headers: {
'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
},
pkPinning: true,
sslPinning: {
certs: [
"sha256//L6faGsvPmuZvEhlP7GBcnLzLxqd+mxAh27mePzm5H0M="
]
}
})
TypeError: Cannot read property 'fetch' of undefined
at fetch (index.js:8)
at _callee3$ (index.js:166)
at tryCatch (runtime.js:45)
at Generator.invoke [as _invoke] (runtime.js:274)
at Generator.prototype.<computed> [as next] (runtime.js:97)
at tryCatch (runtime.js:45)
at invoke (runtime.js:135)
at runtime.js:170
at tryCallTwo (core.js:45)
at doResolve (core.js:200)
--> at fetch(index.js:8):
1 import { NativeModules } from 'react-native';
2 import Q from 'q'
3
4 const { RNSslPinning } = NativeModules;
5
6 const fetch = (url, obj, callback) => {
7 let deferred = Q.defer();
8 RNSslPinning.fetch(url, obj, (err, res) => {
9 if (err && typeof err != 'object') {
10 deferred.reject(err);
11 }
I followed the guide and added the solution for iOS app. How do I test the solution to make sure it works? I tried to replace the certificate with a different one and that does not seem to make any difference.
Our server is a virtual host and I had to use "openssl s_client -showcerts -servername <server_hostname> -connect <server_hostname>:443" to get the certificate. Does the solution works for vhost?
Hello,
I've just started a new react native project from scratch and just added this library regarding to the readme. Unfortunately it won't build now anymore because of following error:
BUILD FAILED in 4s
Error: Command failed: ./gradlew app:installDebug -PreactNativeDevServerPort=8081
.../poc/node_modules/react-native-ssl-pinning/android/src/main/java/com/toyberman/RNSslPinningModule.java:3: error: package android.support.annotation does not exist
import android.support.annotation.NonNull;
^
.../poc/node_modules/react-native-ssl-pinning/android/src/main/java/com/toyberman/RNSslPinningModule.java:221: error: cannot find symbol
@NonNull
^
symbol: class NonNull
location: class RNSslPinningModule
Note: .../poc/node_modules/react-native-ssl-pinning/android/src/main/java/com/toyberman/Utils/OkHttpUtils.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
My package.json:
{
"name": "poc",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"react": "16.8.6",
"react-native": "0.60.0",
"react-native-ssl-pinning": "^1.2.0"
},
"devDependencies": {
"@babel/core": "^7.5.4",
"@babel/runtime": "^7.5.4",
"@react-native-community/eslint-config": "^0.0.5",
"babel-jest": "^24.8.0",
"eslint": "^6.0.1",
"jest": "^24.8.0",
"metro-react-native-babel-preset": "^0.55.0",
"react-test-renderer": "16.8.6"
},
"jest": {
"preset": "react-native"
}
}
settings.gradle:
rootProject.name = 'poc'
include ':react-native-ssl-pinning'
project(':react-native-ssl-pinning').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-ssl-pinning/android')
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
android/build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
buildToolsVersion = "28.0.3"
minSdkVersion = 16
compileSdkVersion = 28
targetSdkVersion = 28
supportLibVersion = "28.0.0"
}
repositories {
google()
jcenter()
}
dependencies {
classpath("com.android.tools.build:gradle:3.4.1")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenLocal()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("$rootDir/../node_modules/react-native/android")
}
maven {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
}
google()
jcenter()
maven { url "https://jitpack.io" }
}
}
My android/app/build.gradle is the default generated one as well. Just added the library depencdency declaration:
...
dependencies {
implementation project(':react-native-ssl-pinning')
...
}
gradle.properties
android.useAndroidX=true
android.enableJetifier=true
I've found other threads with similar errors which suggested changing useAndroidX and enableJetifier to false: unfortunately this won't help here.
Any help is appreciated.
BR
Does this library currently have support for websockets? If so how would I use ir
Any plans to support public key pinning in addition to cert pinning?
Thanks
In android, request data is passing as blank for react version 0.61.5
Hello,
I'm facing with issue which was already mention here #46 #19, it is failing on :
Cannot read property 'fetch' of undefined node_modules/react-native-ssl-pinning/index.js:8:17 in fetch
On line where is loading NativeModules => const { RNSslPinning } = NativeModules;
The main concern from me is next:
Is it possible to this library working with expo project ? because of that linking and those stuff ?
NOTE:
I'm using Expo SDK 37.0.1 which is using RN 0.61
Thanks in advice!
In the objective C code, headers are only applied if the body field exists:
if ([obj objectForKey:@"body"]) {
NSDictionary * body = obj[@"body"];
// this is a multipart form data request
if([body isKindOfClass:[NSDictionary class]] && [body objectForKey:@"formData"]){
// post multipart
NSDictionary * formData = body[@"formData"];
[self performMultipartRequest:manager obj:obj url:url request:request callback:callback formData:formData];
}
else {
[self setHeaders:obj request:request];
// post a string
NSData *data = [obj[@"body"] dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:data];
//TODO: if no body
}
}
[self performRequest:manager request:request callback:callback ];
This means for GET requests, you have to explicitly set body: ''
. Took me a few hours to figure out what was going on - our API throwing back auth errors because the Authorization header was left off the request. Headers should still be applied if body field is omitted. Or this should at least be documented.
Edit: never mind
in iOS I am getting this issue and app crashed due to this thread
Fatal Exception: java.lang.NoClassDefFoundError: java.nio.charset.StandardCharsets
at com.toyberman.RNSslPinningModule$2.onResponse(RNSslPinningModule.java:211)
at com.google.firebase.perf.network.zzg.onResponse()
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:206)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:856)
"version": "1.4.5"
How to use react native ssl pinning with axios library
Currently the library throws an unhandled exception for attempting to assign properties to an error string returned from native modules.
When I patched for my own use, I simply wrapped the assignments in a conditional checking the typeof data
:
But allowing the function to return the error string directly violates the TypeScript response type
interface Response {
bodyString: string;
headers: Header;
status: number;
url: string;
json: () => Promise<{ [key: string]: any}>;
text: () => Promise<string>;
}
export declare function fetch(url: string, options: ReactNativeSSLPinning.Options): Promise<ReactNativeSSLPinning.Response>;
Would you prefer that the native module error string be incorporated into the existing expected response object, or that the types be modified to conditionally return a Promise-wrapped error string instead?
I follow the steps for ios key pinning as they are listed and i keep getting error cancelled in catch of react native code. I should put the .cer file in root folder of app right?
RNSslPinning.m
/node_modules/react-native/React/Base/RCTBridgeModule.h:10:9: 'React/RCTDefines.h' file not found
In IOS platform getting Cancelled error while calling post api :
My Code :
fetch(apiUrl,
{
method: "POST",
sslPinning: {
certs: ["mycert"]
},
timeoutInterval: 100000,
headers: {
"Content-Type": "application/json"
},
body: body
}
)
.then(response => response.json())
.then(response => {
}).catch(error => {
// getting error : Cancelled here
})
.done();
Error log
> Task :react-native-ssl-pinning:compileDebugJavaWithJavac FAILED
-path-redacted-\node_modules\react-native-ssl-pinning\android\src\main\java\com\toyberman\RNSslPinningModule.java:25: error: cannot find symbol
import java.util.Base64;
^
symbol: class Base64
location: package java.util
-path-redacted-\node_modules\react-native-ssl-pinning\android\src\main\java\com\toyberman\RNSslPinningModule.java:219: error: cannot find symbol
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
^
symbol: variable O
location: class VERSION_CODES
-path-redacted-\node_modules\react-native-ssl-pinning\android\src\main\java\com\toyberman\RNSslPinningModule.java:222: error: cannot find symbol
base64 = Base64.getEncoder().encodeToString(bytes);
^
symbol: variable Base64
Note: -path-redacted-\node_modules\react-native-ssl-pinning\android\src\main\java\com\toyberman\Utils\OkHttpUtils.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
3 errors
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':react-native-ssl-pinning:compileDebugJavaWithJavac'.
> Compilation failed; see the compiler error output for details.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.4.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD FAILED in 5s
77 actionable tasks: 69 executed, 8 up-to-date
error Could not install the app on the device, read the error above for details.
Make sure you have an Android emulator running or a device connected and have
set up your Android development environment:
https://facebook.github.io/react-native/docs/getting-started.html
error Command failed: gradlew.bat app:installDebug. Run CLI with --verbose flag for more details.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
my android/build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
buildToolsVersion = "28.0.3"
minSdkVersion = 16
compileSdkVersion = 28
targetSdkVersion = 28
supportLibVersion = "28.0.0"
}
repositories {
google()
jcenter()
}
dependencies {
classpath("com.android.tools.build:gradle:3.4.0")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
mavenLocal()
jcenter()
maven { url "https://jitpack.io" }
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
}
}
$ java -version
java version "1.8.0_221"
Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)
$ javac -version
javac 1.8.0_221
$ ./gradlew -v
------------------------------------------------------------
Gradle 5.4.1
------------------------------------------------------------
Build time: 2019-04-26 08:14:42 UTC
Revision: 261d171646b36a6a28d5a19a69676cd098a4c19d
Kotlin: 1.3.21
Groovy: 2.5.4
Ant: Apache Ant(TM) version 1.9.13 compiled on July 10 2018
JVM: 1.8.0_221 (Oracle Corporation 25.221-b11)
OS: Windows 7 6.1 amd64
Hello,
Using RN 0.60.3, I am seeing the below error:
TypeError: Cannot read property 'fetch' of undefined
Contained within index.js:8:17
Examining the index.js for this library and troubleshooting, it appears the object RNSslPinning is null:
`import { NativeModules } from 'react-native';
import Q from 'q'
const { RNSslPinning } = NativeModules;
`
Linking of libraries is now handled by default in RN 0.60.+, could this be related to that?
allprojects {
repositories {
maven { url "https://jitpack.io" }
}
}
I already have a url in maven. If I remove it then build gets failed. I have this as a url "url "$rootDir/../node_modules/react-native/android""
I am using public key pinning in my project
RN: 0.61.5
react-native-ssl-pinning: "^1.4.0",
Response:
failed to connect to ext-qamobile3-aws1.freecharge.in/54.208.151.241 (port 443) from /192.168.232.2 (port 59100) after 15000ms
@MaxToyberman , i am using version 1.4.0
my post request is cancelled with sslPinning. i am using certificate in .der
format.
Has someone encountered this error? Error undefined is not a function (near '...(0, _reactNativeSslPinning.default)...')
Hi MaxToyberman, i really need your help how to use formData in your library. when im having a request theres an error with ios when using formData
var photo = {
uri: Platform.OS == "android" ? response.uri : response.uri.replace("file://", ""),
type: "image/png",
name: response.name
}
var data = new FormData();
data.append('token', this.props.token);
data.append('id', this.props.Credentials.id);
data.append('image', photo);
body = {
formData: JSON.stringy(data)
}
is there any wrong with these?
During a local build on ios I have this error:
/react-native/React/Base/RCTBridgeModule.h:10:9: 'React/RCTDefines.h' file not found
/node_modules/react-native-ssl-pinning/ios/RNSslPinning/RNSslPinning.m:6:9: In file included node_modules/react-native-ssl-pinning/ios/RNSslPinning/RNSslPinning.m:6:
In file included from /node_modules/react-native-ssl-pinning/ios/RNSslPinning/RNSslPinning.h:4:
I added the library to xcode as requested.
Let me know.
Regards.
fetch isn't run when POST method passed with body parameter. See my request below, if body is included I get the output:
here-----------------------------
here4-----------------------------
when body isn't passed we enter the catch as my server responds with a 400 (missing the parameters. Output:
here-----------------------------
here4-----------------------------
here2------------------------------
My fetch request:
let bodyObject = {
uid: uid,
fieldsToUpdate: fieldsToUpdate
}
console.log("here-----------------------------")
fetch(`${Config.API_URL}/users/update`, {
method: "POST" ,
timeoutInterval: 10000, // millisecondsbody:
body: bodyObject,
headers: {
Accept: "application/json; charset=utf-8", "Access-Control-Allow-Origin": "*", "e_platform": "mobile",
},
})
.then(res => {
console.log("here1-----------------------------")
})
.catch(function (error) {
console.log("here2-----------------------------")
});
console.log("here4-----------------------------")
HI @MaxToyberman thanks for build this repo and sharing with the community can you please confirm license grants? Hopefully MIT?
with Android it's working perfectly, i don't understand why it's not working in iOS (all ios version), don't have any parameters transfer to the API server:
Files: "" ; group receipents: "" ; User receipients: ""
const localUploadAttachment = async (url, a, message) => {
let formData = new FormData();
let dataObj = {
name: a.name,
type: 'image/jpg',
uri: a.uri
};
formData.append('files', dataObj); // i tested with "file" parametter but its still not work
formData.append('groupRecipients', JSON.stringify(message.GroupRecipients));
formData.append('userRecipients', JSON.stringify(message.UserRecipients));
let response = fetch(url, {
method: "POST" ,
timeoutInterval: 30000,
body: {
formData: formData,
},
sslPinning: {
certs: ["mycert1"]
},
headers: {
'content-type': 'multipart/form-data; charset=UTF-8',
accept: 'application/json, text/plain, /',
}
})
return response;
}
Please take a look and let me know if you have anything solution for that. Thanks :)
i get this after install:
Could not find com.github.franmontiel:PersistentCookieJar:v1.0.1.
Searched in the following locations:
file:/Users/davidbiller/Library/Android/sdk/extras/m2repository/com/github/franmontiel/PersistentCookieJar/v1.0.1/PersistentCookieJar-v1.0.1.pom
....
Required by:
project :app > project :react-native-ssl-pinning
Library linked correctly.
Working on Android, but on iOS is still get cancelled even if I use the same certificates used in Android.
"react-native-ssl-pinning": "^1.4.1",
System:
OS: macOS 10.15.4
CPU: (8) x64 Intel(R) Core(TM) i7-6920HQ CPU @ 2.90GHz
Memory: 694.13 MB / 16.00 GB
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 12.15.0 - ~/.nvm/versions/node/v12.15.0/bin/node
Yarn: 1.22.4 - /usr/local/bin/yarn
npm: 6.13.4 - ~/.nvm/versions/node/v12.15.0/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 13.4, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
Android SDK:
API Levels: 26, 28, 29
Build Tools: 28.0.3, 29.0.2
System Images: android-28 | Intel x86 Atom_64, android-28 | Google APIs Intel x86 Atom_64, android-28 | Google Play Intel x86 Atom_64, android-29 | Intel x86 Atom_64, android-29 | Google APIs Intel x86 Atom, android-29 | Google APIs Intel x86 Atom_64, android-R | Google APIs Intel x86 Atom_64, android-R | Google Play Intel x86 Atom
IDEs:
Android Studio: 3.5 AI-191.8026.42.35.6010548
Xcode: 11.4.1/11E503a - /usr/bin/xcodebuild
npmPackages:
react: ^16.9.0 => 16.13.0
react-native: 0.61.5 => 0.61.5
npmGlobalPackages:
react-native-create-library: 3.1.2
timeoutInterval is not working in fetch.
automatically timeout after 15 seconds.
My Code :
fetch(apiUrl,
{
method: "POST",
sslPinning: {
certs: ["mycert"]
},
timeoutInterval: 100000,
headers: {
"Content-Type": "application/json"
},
body: body
}
)
.then(response => response.json())
.then(response => {
}).catch(error => {
alert(error);
})
.done();
I tried using FormData given in repository but did not worked for me. I was not getting any response , means no call in then or catch .
I want to use
const data = new FormData();
data.append("query", queryString);
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
Thanks for open sourcing your library! :)
Blob-support for react-native's fetch was introduced in 0.54:
facebook/react-native#11417
facebook/react-native#11573
Blobs doesn't seem to work with your library though:
var blob = new Blob();
pinnedFetch('https://jsonplaceholder.typicode.com/posts/1', {
method: 'PUT',
body: blob,
headers: {
'Content-Type': 'application/octet-stream',
},
sslPinning: {[
"my.certificate"
]},
})
.then(response => response.json())
.then(json => console.warn(json));
Leads to:
Exception '-[__NSDictionaryM dataUsingEncoding:]: unrecognized selector sent to instance 0x1c4239de0' was thrown while invoking fetch on target RNSslPinning with params (
"https://jsonplaceholder.typicode.com/posts/1",
{
body = {
"_data" = {
blobId = "cc129bc0-f470-405f-80f8-2c115b404e76";
lastModified = 1535620344891;
offset = 0;
size = 0;
type = "";
};
};
headers = {
"Content-Type" = "application/octet-stream";
};
method = PUT;
sslPinning = {
certs = (
"my.certificate"
);
};
},
137
)
I need ssl pinning for all my request but haven't found a library featuring blob PUTs.
Any thoughts on how to support this?
When using react-native link the project cannot sync successfully because a maven dependency is missing from project level gradle:
Dependency needed by com.github.franmontiel:PersistentCookieJar:v1.0.1
repositories { maven { url "https://jitpack.io" } }
Needs fixing.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.