In this post you can find out why even with JavaScript turned off and without plugins, you can still send behavioral data to a third-party server.
Also here we will look at the method of how to get behavioral information from users using only HTML and CSS.
Perhaps, after reading the post, it will seem to you that I "invented the wheel." Indeed, the methods described in this post are not new, and use specifications that are supported by almost all browsers.
Anyway, this information will help you understand one nonstandard method of tracking user behavior, which at the moment cannot be “disabled” (in settings) or blocked (with plug-ins like AdBlock or Ghostery).
Imagine for a moment that you have:
Before trying to find a solution for this problem, let's consider what methods of tracking we have at the moment:
JavaScript bugs are not suitable for the requirements. Except for those that come with a static counter . For example, a bug for Yandex.Metrica downloads an image of the following form:
<noscript><div><img src="//mc.yandex.ru/watch/XXXXXXXX" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
If the client does not execute JavaScript, this approach will allow you to get information such as:
But there is one problem: all information is static, that is, we do not receive information about how the user behaved on the page.
In CSS, we can load an external resource via the url (resource-address) instruction. Usually this resource is loaded only when it becomes necessary to render the page. Why not use this feature in order to collect information about user behavior? We may well write a special CSS that will:
So, our task is to form HTML + CSS code that will force the browser, when interacting with the user, to make a request to our server.
For example, we want to track clicks on links. For this, we can use the : active pseudo- class , namely this pattern ( jsfiddle )
/* <a class="spycss" href="https://google.com">spycss</a>*/ .spycss:active::after { content: url("/backend/click-google"); }
When clicking on such a link, we will get GET on / backend / click-google.
Similarly, we can use other pseudo-classes:
.spycss1:hover::after { content: url("/backend/hover"); } .spycss2:focus::after { content: url("/backend/hover"); }
In both cases we accept GET on our server.
Writing such CSS manually and tracking every link is quite problematic and unproductive. It is for these purposes that I have written a small SpyCss library. With it, you can generate tracking HTML + CSS without any problems. For example, you can use this code to generate a tracked link:
<?php // , State-less $userId = 'get_from_cookie--OR--fetch_from_db'; // , GET . $backendUrl = 'https://spy-css-backend/'; $s = new \SpyCss\SpyCss($userId, $backendUrl); // // <a class="scsssXXXX" href="https://hcbogdan.com">hcbogdan.com</a> echo $s->builder() ->tag('a') ->content('hcbogdan.com') ->attribute('href', 'https://hcbogdan.com') ->interactions([ new SpyCss\Interaction\Active('click_on_hcbogdan_com') ]) ->get(); // CSS echo '<style>'.$s->extractStyles().'</style>';
Now we can track clicks on links and mouse hovering on DOM elements. Let's look at HTML5 forms. Namely on validation ( jsfiddle ):
<form> <input type="text" name="name" required /> </form> <style> .field:valid { background: red; } </style>
It turns out in exactly the same way we can use the pseudo-class: valid to keep track of form filling:
// <input type="text" class="scsssXXXX" required /> echo $s->builder() ->tag('input') ->attributes([ 'name' => 'you_name', 'value' => '', 'required' => true, 'placeholder' => ' ', ]) ->interactions([ new \SpyCss\Interaction\Valid('you_fill_input'), ]) ->get(); echo '<style>'.$s->extractStyles().'</style>';
When the user fills the field - we will receive your GET request.
We can also track how long the user has been hovering over the DOM element (which received a hover state) using css-animations. For example:
@keyframes spycss { 0% {background-image: url("/backend/0")} 100% {background-image: url("/backend/100")} } .spycss:hover::after { animation: spycss 20s infinite; }
A similar example using the SpyCss library (it will add the prefixes -webkit, -moz):
echo $s->builder() ->tag('a') ->content('hcbogdan.com') ->attributes([ 'href' => 'https://hcbogdan.com', 'target' => '_blank' ]) ->interactions([ new \SpyCss\Interaction\Online('view_on_hcbogdan_com'), ]) ->get(); echo '<style>'.$s->extractStyles().'</style>';
Even with the bug disabled or inaccessible to JavaScript, we have using CSS:
This post has reviewed some of the most essential tracking mechanisms. A full example of where all the approaches described above are used can be found here .
Source: https://habr.com/ru/post/348196/
All Articles