Skip to main content

How to protect your WebRTC app code?

I have spent some time analyzing which could be the best way to protect a privative version of a webphone based on QoffeeSIP that we are developing now at Quobis. I have seen this same question on different sites with quite confusing responses. So I'm going to share what I learned just in case it could help to anybody.

Well, I'm not going to define what is WebRTC because Internet is full of it this year (only overtaken by cats ;). For our purposes we have to consider that our app is a Javascript library. Really there is also HTML/CSS code but what I think that is important is Javascript, but HTML/CSS can also be protected in the same way but with other tools.

First of all I want to remark that protect your code in the sense of anybody could copy/modify and redistribute it is impossible since Javascript is only text. If anybody had enough time (or money) this code could be reversed. But, as always, we can do things trying to avoid it as far as possible.

In general, I found that there is a bit confusion between minimize and obfuscate terms so we're going to speak a bit about these techniques.

Minimization

The target is to get the code as small as possible. Obviously generated code is more difficult to understand, but it could be easily reversed with tools like JSbeautifier. (really not as easy depending of the minimizing tool)

Some common possible options at this point are:

  • UglifyJS: The coolest thing right now xD. It is a Node.js package so it's easy to include. Some days ago version 2 was published. We will see that it's fast, really fast.
  • Google Closure Compiler which uses Google to its apps. It is availiable a Java command line tool but there are node modules which use the online API.
  • YUI Compressor from Yahoo, it was the facto standard but now last alternatives are beating it.
A little comparison: I can't find original link, sorry :(
  • Average time: (lower is better)
    • UglifyJS: 0.11554 seconds
    • Closure: 1.41037 seconds
  • Average reducction: (higher is better)
    •  UglifyJS: 45.6%
    • Closure: 51.5%
NOTE: Another one (more complete) with YUI included too.

In my experience Google Closure generated code is better because besides minimization tasks it includes code checking too. It provides warnings for dangerous or illegal Javascript. Moreover I like that you can use this online service to check your code while developing.



Obfuscation

It is defined as "the hiding of intended meaning in communication, making communication confusing, wilfully ambiguous, and harder to interpret." (Wikipedia).

We have some options here when we are working with a web app:
  • Encrypt the transport layer: needed to avoid sniffing to another users of the same LAN. So using HTTPS to serving the application is a must.
  • Encryption: Encrypt application data and decrypt it on the fly via your own javascript enccryption library.
  • Move functions to the server side, which it's not possible in the case of WebRTC because we want end to end media.
  • Use a browser plugin, it has no sense since one of the advantages of WebRTC is that the user doesn't have to install anything.
  • Implement the code in native client for Chrome browser. The advantaje is that common C code protections can be used and the app runs sandboxed. But it is not our case because we need multi-platform support.
  • To avoid legal issues you should incude a note (a Javascript comment) referencing the copyright in each copy of the .js library. Something similar to Free Software Foundation recommendations for free Javascript code. An example could be:
NOTE: Really @source tag is proposed by FSF to include a link to source code of the app. But I think that it could be a good idea to use it because browser plugins that follow the recommendations should "understand" it.

// @source: https://qoffeesip.quobis.com
// Copyright (C) Quobis
// Licensed under Quobis Commercial license
// (http://www.quobis.com/licenses/commercial-1.0.html)

I also want to point out some common obfuscation/encryption problems:
  • Performance decrement, specially speed.
  • Increase troubleshooting difficult.
  • Compatibility problems (IE!!).
  • Size increase.
  • As it was said, a skilled expert could always reverse it and get a code equivalent to ours.
All these problems are more important on the case of encryption, except the last one logically. So at this point we have some options, but I've reduced them to these ones:
  • A paid option like JsCrambler: This is the reference tool, generated code seems to be really dificult to recover and it supports an important number of encryption algorithms.
  • A free solution provided by my colleague DamiánHorrible.js. It implements obfuscation and a kind of simple (so light) optional (through "factor" parameter) encryption. Next picture shows an example using it with the three different factors.

Finally, if you don't like the ugly generated code you can always use Nice.js to get something like this example: xD



In conclusion, I like Horrible.js with factor 3. In my opinion, it has no sense to paid for mitigating a risk impossible to solve completely.

Popular posts from this blog

ISO 27001: Inventario de los activos de información

Uno de los primeros pasos que debe seguir la entidad para adaptarse a la norma ISO 27001 es realizar el inventario de activos que contendrá todos aquellos activos de información que tienen algún valor para la organización y que quedan dentro del alcance del SGSI . En un principio puede parecer un poco abrumador para un principiante(como yo) por la enorme cantidad de activos que se te van ocurriendo por eso decidí empezar por clasificarlos de alguna forma, de entre las múltiples maneras que me encontré elijo la definida por los expertos del foro ISO27k ya que me parece la más completa, mostrando ejemplos de cada tipo y es válida para entidades de muy distinta naturaleza. Éste podría ser un buen punto para comenzar siempre teniendo en cuenta lo que nos aconsejan también en ese foro: "Debido a que los activos son algo cambiante, incluso si pudieras cubrir absolutamente todo lo que hay hoy, mañana la situación sería un poco diferente y más en unas semanas, meses o años. Así que

Flooding Asterisk, Freeswitch and Kamailio with Metasploit

Hi, it has been a long time since my last post because of my new job and my final year project ("VoIP denegation of service attacks" for curious) but there is something I found during my tests with  Freeswitch ,  Kamailio  and  Asterisk  that I want to share. NOTE: Really, guys of  Security By Default  blog published us (my good friend Roi Mallo and me) two articles about how to develop modules for Metasploit framework, another two are coming.  ;) During my project, among others, I developed a Metasploit module which can flood SIP protocol with common frames (INVITE, OPTIONS, REGISTER, BYE), I wrote it at Quobis (nice job ;) in order to use it for some private tests because actual software didn´t fit our needs, so we are going to probe how is the behavior of different GPL VoIP servers against this kind of attacks: - Asterisk: I think it needs no introduction, the famous softswitch/PBX software. - Freeswitch: It´s a newer softswitch that seems to be Asterisk replacement

Another simple Metasploit module: ICMP Flooder

Hi again!, I said I was going to develope VoIP related Metasploit modules but I was reading PacketFu documentation and I found that wrinting an ICMP flooder couldn´t be too complicated at this point. So I share this code too, I decided to include SHOST and SIZE options too trying to get a more flexible module able to make different flavors of this attack as Ping flood , Smurf or Ping of death . Next pictures show the module in  the same way of last post. Code: ------------------------------------------------------------------------- require 'msf/core' class Metasploit3 < Msf::Auxiliary include Msf::Auxiliary::Dos include Msf::Exploit::Capture def initialize super( 'Name' => 'ICMP Flooder', 'Description' => 'A simple ICMP flooder', 'Author' => 'Jesus Perez', 'License'     => MSF_LICENSE, 'Version' => '$Revision: 0 $' ) register_opt