13

I'm experimenting with webAssembly and trying to figure out a way of validating the integrity of a JS method used by the webAssembly module.

For the purpose of the discussion, let's assume that the binary module is not hackable (I know it is not the case), but the JS side is.

Given the following C code:

#include <emscripten.h>

//js method to validate
void validateMe();

int validateMethods(){
    // check validateMe integrity.
    // return 1 if validation succeeded.
}

EMSCRIPTEN_KEEPALIVE
void doStuff(){
    if (validateMethods()){
       // do stuff
    }
}

I would like to call doStuff() from the JS side, and doStuff() will operate only if the integrity check succeeded. I thought of doing some sort of integrity check, similar to Subresource, checking the toString representation of the method. However, If I want to get the current (in-memory) JS method toString, I'll have to call JS which can be compromised.

Q: Can I somehow get the toString in a different way? Any other approach would also be appreciated.

Update: after digging a bit deeper, reading this article, it seems that there is no way to access the JS memory other than the shared array. So any validation technic would be appreciated.


Update 2 (Goal): My ultimate goal is to make sure the WASM part will only work with a specific JS, or at least make it harder to interact with manipulated JS.

Fiddle Example: The following fiddle, is a naive function validation, comparing the toString of the function char by char. If you alter the validateMe function, the validation fails. I'm trying to "bulletproof" it.

Shlomi Schwartz
  • 8,693
  • 29
  • 109
  • 186
  • This is unclear why do you mix javascript and wasm and C? So you want use wasm generate from a c file to check the integrity of a JS method? Plus, "For the purpose of the discussion, let's assume that the binary module is not hackable (I know it is not the case), but the JS side is." is unclear what do you mean by "but the JS side is" ? **Everything** in client side can't be trust. – Stargateur May 05 '18 at 21:10
  • Actually your question could be split into two one with the C part, and the other "Could WASM be used to check integrity of a JS method?". I don't understand why you add C in your question that make it broad and unclear. – Stargateur May 05 '18 at 21:13
  • 1
    Thank you for your reply. The WASM is compiled from C code. The purpose is raising the bar higher for malicious users, IE: WASM code is harder to manipulate/debug, and JS is visible to anyone with a minimum debugging knowledge. My goal is to make sure the WASM works with a specific JS. – Shlomi Schwartz May 06 '18 at 06:58
  • Please check my updates – Shlomi Schwartz May 06 '18 at 08:31

2 Answers2

7

JS is a dynamic language and you can override (almost) everything. You can get the body of the function as string and hash it to generate a "snapshot" of it and later on check against this snapshot, but one can override one of the inner functions independently.

var getA = function() { return 1; };

var myFunc = function() {
  var a = getA();
  return a * 2;
};

WebAssembly.instantiate(wasmBytes, { myFunc });

// ... later on ...
getA = function() { return 5; };
Boyan Mihaylovv
  • 338
  • 2
  • 10
4

No, it cannot. While, of course, you can verify the integrity of some source code, that is not buying you any real security. No matter what you do, you cannot prevent a third-party's computer to run, modify and do whatever they like.

Now, you can make it harder for sure (obfuscation, memory encryption, self-rewriting code, interpreters/VMs... and all those kinds of tricks), but typically, making it hard enough to be somewhat useful is non-trivial (e.g. see Denuvo and this Reddit post, VMProtect, Have you ever used code virtualizer or vmprotect to protect from reverse engineering?, etc.) and, with time or enough popularity, it would be bypassed anyway.

The only way to secure your application would be to run it server-side; which is more expensive and opens you to other issues.


Note that if your goal would have been trying to protect the source code rather than the application itself (in other words, to avoid others reading/copying the code), then compiling (with optimizations) a language like C into WebAssembly could be a fair option (and you would want to write as much as possible of your application in it). Even if the solution does not hide how the application works, it can effectively make it harder to read/reuse the original code/design -- it is just a form of obfuscation.

However, this question is focused on preventing malicious parties to bypass protections and/or manipulate behavior/data, and for that a bit of obfuscation by compiling to WebAssembly is not going to buy you any security.

Acorn
  • 24,970
  • 5
  • 40
  • 69