Cybersecurity blog header

How to automate JavaScript challenges with NodeJS and Python

In order to prevent brute force attacks, some pages are implementing a hybrid protection system including JavaScript challenges. This protection is based on the idea of using a browser with deactivated JavaScript to carry out brute force attacks. Therefore, automatic tests fulfillment in brute force attacks as well as web security audits using tools such as Burp Suite are limited.

By using JavaScript challenges, a JavaScript logic is added to the client who should run a function which result will be sent as an additional parameter and which validity in the server will also be checked. The current date, random numbers, the data which is supposed to be sent or any other value could be included as function entry. Besides, if this is also obfuscated, analyzing this function becomes a headache for the attacker since understanding and replicating the functioning will be much more difficult.

This does not mean that we should rely blindly on this security method. It concerns better a deterrent measure since this logic is still replicable. The issue is that it only requires more resources.

javascript challenges

Browser with activated JavaScript using Node and Python sample.

At this point is where NodeJS execution environment can be useful saving the time we might use in order to understand and replicate the JavaScript challenge logic in any other language. Besides, it is possible to execute JavaScript code directly without being modified and obtaining a correct answer using NodeJS. Likewise, this JavaScript code could be called using any programming language by the system call (or equivalent) as if it was any other command. As a result, it is easily integrated.

For example, supposing that a user’s message and a validation string obtained as a result of executing the following JavaScript code in the user’s browser are sent in a call:

eval(function(p,a,c,k,e,d){e=function(c){returnc};if(!''.replace(/^/,String)){while(c--){d[c]=k[c]||c}k=[function(e){returnd[e]}];e=function(){return'w+'};c=1};while(c--){if(k[c]){p=p.replace(newRegExp('b'+e(c)+'b','g'),k[c])}}returnp}('5 12=18(4,3){7(3<0)13 12(4,3+10);5 8='';16(5 2=0;2<4.17;2++){5 6=4[2];7(6.19(/[20-24]/2)){5 1=4.25(2);7((1>=9)&&(1<=23))6=14.15(((1-9+3)%10)+9);21 7((1>=11)&&(1<=22))6=14.15(((1-11+3)%10)+11)}8+=6}13 8};',10,26,'|code|i|amount|str|var|c|if|output|65|26|97|caesarShift|return|String|fromCharCode|for|length|function|match|a|else|122|90|z|charCodeAt'.split('|'),0,{}))

In order to run the function, the following script could be created in NodeJS:

functiondoit(str,n){eval(function(p,a,c,k,e,d){e=function(c){returnc};if(!''.replace(/^/,String)){while(c--){d[c]=k[c]||c}k=[function(e){returnd[e]}];e=function(){return'w+'};c=1};while(c--){if(k[c]){p=p.replace(newRegExp('b'+e(c)+'b','g'),k[c])}}returnp}('5 12=18(4,3){7(3<0)13 12(4,3+10);5 8='';16(5 2=0;2<4.17;2++){5 6=4[2]; 7(6.19(/[20-24]/2)){5 1=4.25(2);7((1>=9)&&(1<=23))6=14.15(((1-9+3)%10)+9);21 7((1>=11)&&(1<=22))6=14.15(((1-11+3)%10)+11)}8+=6}13 8}; ',10,26,'|code|i|amount|str|var|c|if|output|65|26|97|caesarShift|return|String|fromCharCode|for|length|function|match|a|else|122|90|z|charCodeAt'.split('|'),0,{}))returncaesarShift(str,n);}console.log(doit(process.argv[2],process.argv[3]));

And this JavaScript challenge could be executed as follows:

$ node token-gen.js abcdefghijk 4 eoyiscmwgqa

Using this technique, our script in Perl/python/ruby could invoke the JavaScript code avoiding understanding all the complex logic appearing in an encoded or hashing algorithm. Caesar cipher implementation has been used in the example. Nevertheless, it could be much more complex in a real environment.

Therefore, JavaScript challenge and tokens could be quickly automated in a web security check avoiding the analysis of the protection algorithm implementation used.

Discover our work and cyber security services at