Possible to make a self-hashing app in React Native? - javascript

Let's say I wanted to make an app that handled sensitive user data, and users possibly wouldn't trust it unless they could verify for themselves that the iOS/Android app was exactly the same as the source in the GitHub repo.
Is there some way in React Native that I could have my app run an MD5 hash on the mainjs.bundle file, and display that within the app? Then, theoretically, a tech savvy user could clone the GitHub repo, build it, and run their own MD5 hash on mainjs.bundle and see that it matches.
Granted, this wouldn't be totally foolproof. A malicious developer could easily just have a private repo where they hard-code the hash, and insert malicious code, then publish to the AppStore. But this could be a decent starting point. I'm also open to other/better ideas!

Anything you show in the app is pretty much worthless because a modified version of the app can show the same thing.
What you want to do is to give people steps to execute to test if the app that they have is the right one.
Would look something like
a table with published version -> git commit
steps to extract the js bundle from the apk/ipa
steps to build the bundle from source
If you have a shrinkwrap file, then builds should be reproducible.
Note that it doesn't contains steps to compare the native code, which may also contain a malware:

Related

how to download a js file from a server and run it?

Is it possible to run a js file locally that downloads a secondary file and then run the latter?
I know the best thing would be to download the file from the server and save it locally, I would just like to understand if there is still the possibility to do the above.
Example:
Open terminal
1- node index js
2 - download scripts js in the same directory as index.js
3 - download is complete, start script js automatically.
Even if it is possible to solve it with Node.js workarounds (like requireing your puppeteer script from an url etc.) I strongly suggest to use Git with your team to share the latest version of your script. Version control is a must in modern software development, especially if you are working in a team. By learning the 6-7 most basic git commands you can solve almost everything you need for the current use case.
There are many good tutorials how to get started with git, I recommend GitHub's https://try.github.io.
Of course: you need to convince your team to embrace the change, or in better case they are already using it for version control, so it will be familiar to them.
You will need to:
Install Git locally;
Create a new repository on a server where you can store the latest stable versions of all your scripts (if it is not an open source project make sure it is private! GitLab, GitHub and Bitbucket provides/hosts free private repositories that will suit your needs);
Share the HTTPS (or SSH) URL of the repository with your team (e.g.: https://github.com/.../puppeteer-scripts.git) which they can clone;
Make sure your changes are pushed to the remote git repository;
Your team can pull the latest changes to their local computer (it will be their responsiblity to check if there were changes in the scripts, but you can notify them as well - there are automatic notifications if one starts to "watch" a git repository);
Lastly
Git can be frightening at first sight, but it can be learned in a few days and it makes code sharing smooth within your team.
One of Git's tagline describes very well why it will solve your problem:
--everything-is-local

Is it normal that a simple counter react app is more tham 100MB?

I am a newbie with React.js and just for practice i made a simple counter web app.
But i noticed that the project is more than 120MB.
Is it possible? do i need to do something to shrink it?
120mb can he huge or nothing at all depending on where you get that number. Remember, a modern web app (such as one built with React) needs build tools and often a development server and more. Also, if you are using typescript it will in itself add a compiler that is up towards 40mb.
So if we look at the source directory you'll have your own code plus some build configuration (probably in a webpack configuration file) which totals a few kilobytes. But then we have the node_modules folder which contains all the dependencies for both your own code and the build tools. This isn't a problem and since this folder won't be sent to the client and you shouldn't even commit it to your SCM since it can be restored from your packages.json file.
I did a quick check of the folder size in node_modules in a new dotnet-react project (because that was what I had handy) and this is what I got.
So here we can see that typescript is by far the largest dependency eating up almost 25% of my project and there are still quite a few other large dependencies as well. But this is till just for
If we on other hand look at what is actually delivered to the client that should be a completely different matter. This is what actually matters since this will directly impact the performance of your application. A large app here will be both more code to download and more code to parse for the client.
This same app looks like this when running the project for development and checking network traffic in Chrome Inspector.
So here we can see three script files, but even in development mode only about 520kb is sent to the client even though my node_modules was about 180mb.
If we then go one step further and build this for production we get an even better result.
Now we are down to just about 270kb for the scripts which is just a fraction of the size of the project folder.
So to summarize:
The size is very well possible and kinda expected when working with a modern client side framework such as React (or Angular, Vue, Ember, etc).
The development folder will be large due to all the dependencies needed to build your project.
The final output will be way smaller but in the end depends on what dependencies you decide to use in your own code.
You don't have to do anything to shrink, just make sure that you don't commit node_modules to your SCM.
Also remember that all modern frameworks comes with an overhead to set everything up and making it easy to work with. This is most of the 260kb that my test app is. So if you make a simple counter the overhead will be extreme in comparison and not all projects need a framework such as React.

How to perform obfuscation of source code and protect source in electron js

I recently developed an app with electron framework and am now worried about source code protection after reading security concerns related to electron javascript code.
I mean reverse engineering of the code is possible even if the app is built for production. My application contains many critical information like GitHub Private Token for AutoUpdate and much more.
I just have gone through many SO post but didn't find the perfect answer so resolve the problem. Obfuscation of javascript code or source code protection is not possible with electron? However, Obfuscation doesn't protect the code completely but it can make reverse engineering complex. if there is a workaround for doing so, let me know. I didn't find more than tl;dr in the security-related post of the electron.
I found an obfuscation method by obfuscator but seems it's gonna need manual obfuscation and nothing much about the source code protection like in NW.js Is there any better way to achieve it?
I found something helpful for obfuscation on Medium post. but didn't find anything about source protection.
tl;dr You can and it is not worth the effort. Just pack your source
into a asar file, it keeps most people away from it.
Long awnser:
Use the asar option when building your app.
Obfuscating the code with a uglyfier.
Use WASM
Language bindings to grab your data from a compiled format
neonjs for Rust
edge-js for C#
N-API, NAN for C/C++
Otherwise your files are scripts, all these steps only slow down a
attacker (Tactic of many defenses), but they will not prevent them
from accessing them. The devTools are fairly easy to get opened and
people will be able to read the code in some way, shape or form. And
if someone gets your Obfuscated code it is simple to reconstruct what
is happening (see here for reference:
https://www.youtube.com/watch?v=y6Uzinz3DRU)
If you want to protect yourself from code manipulation, there are
better ways to do it. Like Hashing, Context Isolation etc. electron
has a whole chapter on the matter.
https://github.com/electron/electron/blob/master/docs/tutorial/security.md
There is a library called bytenode which allows you to convert your Javascript files into binary files so that noone can read it.
https://www.npmjs.com/package/bytenode
First install bytenode on your server and in your folder:
>npm i -g bytenode
>npm i bytenode
Create a normal nodeJS file with the following code in it. Let's imagine we name the following code: ok.js
console.log('bytenode works');
Then, compile your javascript code. The command will create a .JSC file with the same name than your file.
user#machine:~$ bytenode -c ok.js
Then, in a main JS file, you will call your binary, let's call it test.js:
const bytenode = require('bytenode');
const myFile=require('./ok.jsc');
myFile;
Save it.
Then, you will call test.js: node test.js to test it. Do a "cat ok.jsc" to see that it is really a binary and that nobody can't see your code. You can move your original plain test js file to another location.
You can use bytenode as mentioned is Nicolas Guérinet's answer.
However, the binary generated by bytenode CLI will give you runtime error when you try to use it in your electron project. The error will say something like:
"Invalid or incompatible cached data (cachedDataRejected)"
For the binary to work with electon, it must be generated by electron itself.
Here's how to get it working:
Let's say you want to protect main.js in a typical electron project.
Install bytenode
npm i bytenode
Rename main.js to something else, say temp.js.
Create a new main.js with the following code:
const { app, BrowserWindow } = require('electron')
function createWindow() {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 400,
height: 200
})
//use bytenode to convert js files to jsc
const bytenode = require("bytenode");
let compiledFilename = bytenode.compileFile({
filename: './temp.js',
output: './main.jsc'
});
//convert other Node.js files as required
}
app.whenReady().then(() => {
createWindow()
})
Now run your electron project. When the blank window appears, look into you project directory, you will find the main.jsc file.
Change your main.js to the following three line code:
const bytenode = require('bytenode');
const myFile = require('./main.jsc');
myFile;
Remove your nodejs source file (temp.js) from your project and build your project.
You can also minify and obfuscate your code before converting it to jsc.
Credits to https://github.com/mapleby for his posts at https://github.com/bytenode/bytenode/issues/63.
I have adapted his idea to get it working.
This will make is significantly more difficult for someone to reverse engineer your code but it will still be possible.
If you're referring to code that you for some reason must have on the client-side, then obfuscation can definitely help. There's no such thing as obfuscation that's impossible to defeat; however, it can raise the cost of de-obfuscation to a point where it's just not worth it for attackers.
The OWASP Mobile Top 10 2016-M9-Reverse Engineering mentions this: "In order to prevent effective reverse engineering, you must use an obfuscation tool". Then you also may benefit from runtime self-protection, which you can also find on the OWASP list: "The mobile app must be able to detect at runtime that code has been added or changed from what it knows about its integrity at compile time. The app must be able to react appropriately at runtime to a code integrity violation".
When comparing different obfuscators, it's critical to check if they provide support and documentation and ensure that the company behind them won't add malware and hide it in the obfuscated code. Here's where free obfuscators often come short.
Check Jscrambler for an enterprise solution. They support Electron and the full list of their obfuscation transformations is available here.

Is there a thing such as "packaged web app"?

Let's say I have a HTML/JS application, which is on a website and runs without any server-side component (except the web server, of course). So it's basically just a bunch of .html, .css and .js files (and some others, like images or SQLite databases)
Someday, an user comes to me to ask me if I can make an offline version, so they can access the app when they are offline.
My first reaction would be to provide them all the files of the app in a .zip file or something, but this is not really good: it's not "clear" to an average user, and the files and code are apparent (which could be "dangerous" if the user edits or deletes them by accident).
So I was wondering: is there a kind of format that would makes me able to store the files of the app in a packaged file?
The file would be something like a .zip file, but when you click to the file, instead of opening up the archive, it opens the /index.html (or similar) which is inside.
So for the user, it would be similar to open an .exe or a single .html file, but still that's not a native app, as that's still a browser app.
Given that I know about:
Apache Cordova; but most of the time, I just use the browser functions, and I don't have a need to use advanced native functionalities;
UWP and PWA, but I don't know if it's exactly what I want (I imagine it as a mix of website and mobile app, but I'm surely wrong);
Open Web App (a standard from Mozilla), but based on what I've read about it, it seems deprecated and not used anymore. Plus, I don't really look forward to "certify" my app... I just want to package some files.
PWA I don't think is a solution to your problem as you wont be able to redistribute the code as an executable package.
UWP would be too Windows specific and might make you lose the platform independence that you already have since you are using plain HTML and JS, plus from what I understand you would need to distribute the app on Windows Store.
I believe packaging as an Electron app would be the best solution as you can provide executable files that can be executed in almost all platforms.
Electron would be the best solution for you. I had a client that first wanted to run app on php server and eventually they figured out they need it as a desktop app. It was easy to rewrite php stuff to node and package as Electron app. You have access to everything files, system etc. so you can do more if needed.
Another solution would be to just inline everything into a single html file.

How to run Webpack Hot Module Replacement (HMR) in Production

Id like to run HMR in production, using it for seamless application updates. I cannot seem to find any docs or tutorials regarding how to do this.
My setup is currently "serverless", and statics are served from AWS S3. My first thought is i would create an "Update" server of some sort, wherby the HMR clients would poll for updates, and the magic would work.
My questions:
a) How do I run this in production (optimally)
b) For this to work the "Update" server will have to know of module changes, how?
I know the json file with the updates is what HMR relies on to know of the changes, will i have to push some sort of this file to the server?
Or, Do I have the server watch S3 files somehow, and recompile, in turn triggering updates.
A complete solution would be awesome, but also just some sudo logic as to how this could work would be great.
Read this two documents to understand how it works:
https://github.com/webpack/docs/wiki/hot-module-replacement-with-webpack
https://github.com/webpack/docs/wiki/hot-module-replacement
No idea to what you mean by "serverless"... How would you serve a website without a server? You will need at least webpack or a nodejs/express instance running somewhere
This will not be optimal. This feature is thought to be used for development. HMR will add listeners to the application for file changes and add code for replacing old modules with new ones. This adds overhead to your code. Optimal would be no hmr.

Categories

Resources