From JQuery to ReactJS

I have previously worked with ReactJS – most notably during my Master’s dissertation, however the main Javascript library I work with when working for clients and companies still remains the venerable JQuery. This is changing as more and more organizations I interact with move to more modern frameworks like Angular and ReactJS.

Where to start if you’re looking to upgrade your skills, or migrate a product from JQuery to ReactJS? Any tips? Here’s what we learned so far:

Be ready to change your mindset – but never give up

It’s not so much a learning curve as it is a roller coaster. Blogger Ben Nadel has an excellent drawing that I guarantee will also be your experience learning any JS framework; be it Angular or React:

Pretty much…

What makes ReactJS so powerful compared to JQuery is the fact that it’s fundamentally different. Sometimes your own prior experience with JQuery will hamper you in learning React because of pre-conceived notions on how things should be done. Power through it – through all the ups and downs, the curve still has an upwards trend. Once you get to grips with the whole idea of unidirectional data flow,  components, props and states, React makes you a lot more productive. That said, there are a few things that helped me transition easier…

Create-react-app is a must

No doubt about it, the worst part of being a newbie is getting used to the new tools, environments, moving parts and components of your new pipeline. Create-react-app is your savior here. Not only does it setup your dev environment in a few simple commands, you can rest assured that it’s doing so according to industry best practices (which eases those nagging questions at the back of your brain: “Am I doing this right?”). One very useful article I found was how to configure create-react-app to proxy through API requests directly to my back-end:

How to get “create-react-app” to work with your API

Unleash the power of reusable components

It takes banging your head with few project requirements to realize just how powerful and useful React Components are. In reality, the whole point of using React is to define a component once:

class David extends React.Component {
      render() {
                   return (<h1>David says hi...</h1>);

… and then re-using that component over and over again as a “normal” HTML attribute

 <David />

 Thing is, when clever people start publishing their own components, you can re-use these components and requirements that took days before now take you minutes. These components could be anything, my favorite so far:

Applying Google’s MDL to React JS becomes a breeze…

Redux-Saga vs Redux-Thunk

Talking about Dexie.js brings me to my next point. One of the aspects of Redux that always caught me with my pants down was the inability of reducers to process async functions (it seems logical in hindsight – an async function returns a handle to a future result such as a Promise – not the actual result). This is something you need to keep in mind since some very common requirements like fetching data from an API or indeed using libraries like Dexie require you to use async functions.

In order to tackle this, redux-thunk was born. A nice and easy blog post on how to use it can be found here:

Coming from a JQuery background, I was already used to the idea that events are used to trigger certain actions – just like in redux actions are used to trigger reducers that in turn change your state. The redux-thunk approach of defining an async function within an action ran a bit contrary to my thinking – an “action creator” as the blog above refers to it. It would be easier (to my JQuery mind) to have a function that “listens” for an async action, performs that async action, and then returns another action with the result for your dispatch to process. This thought process resonated more with me (again, coming from an event / subscription model). In other words:

Redux-Saga Workflow

As you can see, this is where Redux-Saga enters the picture. This redux middleware listens for specified actions (usually you’d specify those that need to trigger async actions like API operations or Dexie.js), runs a function to deal with the async actions (tip: definitely try stick to using the yield keyword..) and then dispatches another action with the results that your usual redux reducers can then pick up. I guess it comes down to personal preference, but this paradigm was a lot easier to deal with in my head

Always try code a simple / sample project while learning

In my case most of my learning was done through reading documentation and via code-academy. My side / sample project was to build a web app that tracks my cryptocurrency investments, incorporating features like indexeddb via Dexie.js, API calls via Saga and so on…

(Note sparklines only work if you visit the page at least twice from the same browser – the app has no server side components, it runs entirely in the browser so the sparklines represent change in crytocurrency price since your last visit)


Anomaly detection vs Ransomware

A big part of what we do at CyberSift is anomaly detection. The recent WannaCry attack highlighted the growing threat of ransomware in the security landscape. The WannaCry authors may have made amateur mistakes, and there may be more stealthy and profitable attacks than WannaCry, but the negative impact it has had on Windows users (as it turns out… especially Windows 7 users) is undeniable — even bringing UK’s NHS to a halt. Microsoft promptly issued a patch, and vendors started releasing signatures to detect WannaCry — mostly lists of file hashes or domains:

Sample WannaCry filehashes
Sample WannaCry domains

It’s still a largely a game of cat and mouse. A simple update and the above lists become invalid. CyberSift already does a pretty good job of detecting ransomware activity via it’s DNS module (one notices the domains shown above look nothing like the usual english domains the majority of users visit — a dead giveaway for CyberSift)… but we wanted to take the concept of anomaly detection further and try help block ransomware as it happens — not after the fact.

We don’t usually venture into the realm of endpoint protection, but in this particular case we did — and we’re releasing a Windows anti-ransomware tool called “RansomSift”. Ransomsift doesn’t contain any signatures — no file hashes or domains, it’s a pure anomaly-based system. In this two part blog post we’ll explore the methods we used.

First — let’s see RansomSift in action against WannaCry on a Windows XP machine:

Anomaly Indicators

How do we achieve the above? Ransomsift uses two classes of anomaly detectors:

  1. File-based statistical indicators. In this blog post we’ll highlight what exactly we use to detect when files are being encrypted — and why it doesn’t always work
  2. OS based statistical indicators. In the next part of this two part series, we’ll explore which Operating System features RansomSift monitors for anomalies to further reduce false positives and block ransomware quicker.

Note: for these tests all files were encrypted using AES 256 using the command below (this becomes important later on so keep this in mind…)

openssl enc -aes-256-cbc -a -pass pass:word

File-based statistical indicators

A couple of academic research papers deal with detecting ransomware as it encrypts files [1][2]. The basic idea is that if one where to plot the histogram of data in a “normal” file and compare it to that of an encrypted file, there are differences that can be detected. Let’s have a quick rundown of the methods used:

Shannon Entropy

A simplistic explanation of entropy is “randomness” in a file. If we compare the probability distribution of an unencrypted file (MS WORD DOCX in this particular case) and an the same file encrypted we see the following:

A Microsoft Word file (unencrypted vs encrypted)

Clearly, the unencrypted file is a lot more “random” than the encrypted file. This feature holds true across multiple file types:


Another statistical feature we can measure is “skewness”. The below diagram sums up the concept of skewness:


Since the histograms are different, the unencrypted and encrypted versions of a file have different skewness. Plotting this for different file types we get another marked difference (though it looks like HTML would give us some difficulty here):


The last measure we looked at was “kurtosis”. Again, a simple diagram explains the concept succinctly:


Again, plotting kurtosis for different file types we get quite a difference (though again had we to rely on this statistic only, we’d have problems with TXT, HTML and DOC) :

Victories and Defeats

The above results alone are quite convincing. By combining the weak models and having each of them “vote” if a file is encrypted or not, we end up with a strong model that can tell with a good deal of reliability if a file is encrypted or not. RansomSift leverages this concept by monitoring files that have been changed in the “My Documents” directory, and determines if the file has been encrypted or not.

However, depending on this file-based statistical approach alone is not enough. During testing we ran into a couple of false positives (files being marked as encrypted when they are not) and false negatives (files being marked as not encrypted when in fact they are):

  • Compressed files are extremely similar to some forms of encryption. Depending on how files are compressed, and how they are subsequently encrypted, they both look like very random byte streams so their histograms would look very similar. This becomes quite an issue when you consider that nowadays programs like MS OFFICE compresses it’s files (DOCX, XLSX, etc…). Depending on the encryption scheme used, it’s hard to tell them apart using just statistics

In this series of tests we used openssl to encrypt our files — just as a malware author might do. However, there is more than one way to encrypt a file. You could:

  • Use a popular tool like AxCrypt. The encryption and compression used by this program makes it harder to tell files apart statistically speaking. During testing we found similar behavior with some other compression / encryption programs

Since we try to make our anomaly detection systems as robust as possible, we added another layer of anomaly detection that doesn’t depend on file statistics. In the next blog post we’ll explore the operating system features that we monitor in order to detect (and block) suspect activity such as WannaCry or other ransomware.

Interested in trying out RansomSift or CyberSift for enterprise? Contact Us!


[1] Scaife, N., Carter, H., Traynor, P. and Butler, K.R., 2016, June. Cryptolock (and drop it): stopping ransomware attacks on user data. In Distributed Computing Systems (ICDCS), 2016 IEEE 36th International Conference on (pp. 303–312). IEEE.

[2] Mbol, F., Robert, J.M. and Sadighian, A., 2016, November. An efficient approach to detect torrentlocker ransomware in computer systems. In International Conference on Cryptology and Network Security (pp. 532–541). Springer International Publishing.


The code used to generate the above statistics can be found below (written in GOLANG v1.8). Please note this is not the actual RansomSift code.