We prohibit the use of well-known UserJS

Introduction


UserJS provides users with a convenient and simple mechanism for modifying web pages, which is why many users automate their actions with UserJS, and sometimes bypass weak security systems.
Most of all, browser-based online games suffer from users using UserJS, many of which have already begun the war against UserJS. For example, the Travian game uses fake hidden web forms, which sometimes appear along with regular ones, UserJS scripts written without taking into account this feature are mistaken and send data via the fake form, for which the player immediately receives a penalty.
I would like to note right away that you can fight only with well-known UserJS scripts, the solution shown is not universal and cannot protect against any script.
Today I am presenting to your court my method of dealing with user scripts - MD5 hashing followed by comparison. The main acting roles are played by JavaScript and PHP.

Legend


Suppose we have a website with a simple authorization form, but users are not used to entering their login, but use a UserJS script that adds an additional button to the form, clicking on which automatically enters their login. This example is taken just for clarity, in place of the authorization form there can be, for example, the form for sending troops in the online strategy, and the UserJS script is a bot that automatically sends troops.

Initial data


So, our form looks like this: Users use the following UserJS in the Opera browser: Or in FireFox for the GreaceMonkey extension: After enabling this script, users get this kind of authorization form: Clicking on the “AutoLogin” button, as seen from the source, leads to filling out the field "Login". Let's try to prohibit the use of this script by the user.



Copy Source | Copy HTML
  1. window.opera.addEventListener('AfterEvent.load', function (e){
  2.     if (e.event.target instanceof Document){
  3.               e.preventDefault();
  4.         document.forms[ 0].innerHTML+='';
  5.         }
  6. },false);



Copy Source | Copy HTML
  1. // ==UserScript==
  2. // @name           test1
  3. // @namespace      test
  4. // @include        http://localhost/anti-userjs/test1.php
  5. // ==/UserScript==
  6.  
  7. document.forms[ 0].innerHTML+='';








Authorization form output


We will display the authorization form from the PHP file, frame the form with the div tag, and also cache all the data inside this tag using PHP tools. The hash will be saved in the session for subsequent control:
Copy Source | Copy HTML
  1. ob_start();
  2. ?>
  3. Логин:
  4. Пароль:

  5. $data=ob_get_contents();
  6. ob_end_flush();
  7. $data=strtr($data,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz');
  8. $data=preg_replace("/[ \t\n\r]/",'',$data);
  9. $md5=md5($data);
  10. $_SESSION['md5']=$md5;
  11. ?>


A few words about the processing of content - Opera and FireFox browsers in their own way scorch HTML code, so processing it through JavaScript leads to different results. So, Opera converts all HTML tags to uppercase letters, and FireFox changes the parameters in the tags according to the standard. Therefore, it is important to write controlled HTML code validly.
To eliminate various tag register processing and line breaks, all spaces, tabs and line breaks are removed from the contents, as well as all English letters are lowercase.
Another important note - the document encoding should be UTF-8, with CP1251 JavaScript in browsers and PHP work differently.

JavaScript Control


So, the form has been deduced, its checksum has been counted, now we need to calculate it on the part of the user and make sure that there was no UserJS intervention. To do this, we add an event to onLoad and call the JS function: In it I used several ready-made functions - md5 and strtr, I will not upload them in the article, you can find them in the attached file. Java-Script on the user side performs the same actions as the PHP script above, the result - a hash of the content - is entered into the form.
Copy Source | Copy HTML
  1. >
  2. function checkuserjs(){
  3.     var data=document.getElementsByTagName('div')[ 0].innerHTML;
  4.     data=strtr(data,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz');
  5.     data=data.replace(/[ \t\n\r]/g,'');
  6.     document.forms[ 0].md5.value=md5(data);
  7. }

 





Server side processing


The only thing left is to check the received data: Thus, we catch dishonest users (pay attention to the GreaseMonkey indicator):
Copy Source | Copy HTML
  1. if ($_POST){
  2.     if ($_POST['md5']!=$_SESSION['md5'])
  3.         die ('Использование UserJS запрещено!');
  4.     echo 'Форма отправлена';
  5. }





Conclusion


The example I have indicated demonstrates the very approach to prohibiting the use of UserJS, when developing solutions based on it, you need to understand the main point - it is not possible to prohibit the use of any UserJS, so you need to monitor the laid out scripts affecting our sites and develop protection from them. Since such scripts are made with enthusiasm, there is a good chance that a new version of the script that bypasses our defense, if it comes out, will not be soon. The same Travian demonstrates this - the simplest protection with fake forms was introduced half a year ago, there is still no new version of UserJS scripts.

Application: anti-userjs.tar.gz 3708 bytes

Also popular now: