Un chercheur trouve une méthode CSS pour suivre les mouvements de la souris
Qui pourrait servir à pister les internautes avec JS désactivé

100PARTAGES

24  0 
Alors que les utilisateurs sont de plus en plus préoccupés par la qualité de la protection de leur vie privée et le pistage en ligne, ils ont commencé à utiliser des bloqueurs de publicité et des bloqueurs de script afin de bloquer les scripts de suivi JavaScript. Une nouvelle méthode a été découverte qui permet à un site de suivre les mouvements de la souris de ses visiteurs en utilisant uniquement HTML et CSS, ce qui peut contourner la protection érigée contre le pistage en ligne.

La plupart des suivis en ligne sont effectués à l'aide de scripts JavaScript chargés dans des sites Web et des publicités. Cela permet aux annonceurs et aux sites de savoir où vous allez sur le Web, comment vous utilisez un site ou tout autre comportement en ligne.

Ces scripts peuvent être bloqués à l'aide de bloqueurs de publicité, de l’activation de protection du suivi du navigateur comme Content Blocking de Firefox ou même le blocage de JavaScript.

Un chercheur a trouvé une nouvelle méthode permettant de suivre les mouvements de la souris d'un visiteur d'un site Web sur une page sans utiliser de code JavaScript, mais en utilisant uniquement le langage HTML et CSS. Cela rend très difficile le blocage du suivi effectué de cette manière.

Le chercheur en sécurité Davy Wybiral a récemment montré sur Twitter comment les sites Web peuvent utiliser HTML et CSS pour surveiller les mouvements de la souris se produisant dans une fenêtre du navigateur à partir d'une autre fenêtre du navigateur.

Wybiral a pu le faire en créant une grille de DIV HTML utilisant des sélecteurs CSS :hover pour demander une nouvelle image d’arrière-plan lorsque votre souris passe au-dessus d’un champ de la grille. Comme les demandes d'images sont effectuées en arrière-plan, le navigateur n'indique pas qu'ils sont en train d'établir une connexion. Par conséquent, toutes les demandes sont masquées à l'utilisateur.

Lorsqu'un utilisateur survole une boîte et qu'une nouvelle image d'arrière-plan est demandée, le script enregistre l'emplacement sur la grille survolé. Un utilisateur d'un autre navigateur peut ensuite utiliser l'URL /watch pour surveiller en temps réel la zone survolée.

« Il m'est apparu que vous pouviez surveiller à distance la position du curseur sans JS en utilisant des sélecteurs CSS :hover pour modifier les images d'arrière-plan masquées (provoquant une demande GET).

« Cela devrait également fonctionner sur Tor et pourrait constituer une approche intéressante pour suivre les visiteurs ». .


Pour mémoire, la pseudo-classe :hover permet de spécifier l'apparence d'un élément au moment où l'utilisateur le survole avec le pointeur, sans nécessairement l'activer.

Code CSS : Sélectionner tout
1
2
3
4
5
/* Cible n'importe quel élément <a> lorsque  */
/* celui-ci est survolé */
a:hover {
  background-color: gold;
}

La mise en forme ciblée par cette pseudo-classe peut être surchargée par d'autres pseudo-classes relatives aux liens hypertextes comme :link, :visited, et :active, apparaissant dans des règles subséquentes. Pour décorer les liens sans effet de bord problématique, on placera la règle :hover après les règles :link et :visited mais avant la règle :active (l'ordre est :link — :visited — :hover — :active – un moyen mnémotechnique est de se souvenir des initiales LVHA) tandis que l'ordre de la règle :focus est indifférent.

La pseudo-classe :hover peut être appliquée à n'importe quel pseudo-élément.

La technique décrite par le chercheur peut être utilisée pour diverses raisons, notamment la détermination des zones qui suscitent le plus d’intérêts sur un site ou pour des études d'interface utilisateur.

Selon Wybiral, cette méthode peut être utile pour les tâches suivantes:
  • l'analyse du mouvement, qui est un domaine de recherche actif
  • déterminer les différentes positions de repos pour le curseur
  • identifier le mouvement de la souris par rapport au touchpad devrait être possible
  • peut donner un aperçu d'autres traits de comportement des visiteurs

Le chercheur a également indiqué que le sélecteur de survol n’est pas le seul à pouvoir être utilisé pour suivre le comportement du navigateur.

« En plus du suivi de la souris, de nombreux autres sélecteurs CSS pourraient donner des analyses pour le comportement de navigation. :focus, par exemple, devrait pouvoir contrôler les éléments sur lesquels l'utilisateur a le focus actif, et le sélecteur [value] est connu depuis un certain temps pour pouvoir interroger efficacement un élément d'entrée. Les règles autour de [value] ont été modifiées pour le rendre moins puissant, mais elles peuvent probablement toujours être utilisées simplement pour indiquer si l'utilisateur a commencé à taper ou si quelque chose a changé (je n’ai pas encore fait de PoC dessus, mais cela devrait être possible) ».

Pour rappel, la pseudo-classe :focus permet de cibler un élément lorsque celui-ci reçoit le focus (soit il est sélectionné à l'aide du clavier, soit il est activé avec la souris comme par exemple le champ d'un formulaire).

Code CSS : Sélectionner tout
1
2
3
4
5
/* Cible n'importe quel élément <input> */
/* uniquement lorsqu'il a le focus */
input:focus {
  color: red;
}

Cette pseudo-classe ne s'applique qu'aux éléments avec le focus, elle ne s'applique pas à ses parents (comme :checked, :enabled mais pas comme :active ou :hover).

La méthode de Wybiral n’est pas la seule à montrer comment CSS et HTML peuvent être utilisés pour suivre les utilisateurs sur des sites Web.

L'année dernière, un projet intitulé CrookedStyleSheets a été publié. Il permet aux sites de rassembler des informations telles que la résolution de l'écran, le navigateur utilisé, lorsqu'un utilisateur clique sur un lien et éventuellement le système d'exploitation utilisé en fonction des polices prises en charge.

Tout comme la méthode de Wybiral, tout est fait avec HTML et CSS. Elle n’utilise pas de JavaScript.

Pour ceux qui sont intéressés par le code du script de Wybiral, le voici

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Tracking cursor position in real-time without JavaScript

package main

import (
	"fmt"
	"net/http"
	"strings"
)

const W = 50
const H = 50

var ch chan string

const head = `<head>
<style>
*{margin:0;padding:0}
html,body{width:100%;height:100%}
p{
width:10px;
height:10px;
display:inline-block;
border-right:1px solid #666;
border-bottom:1px solid #666
}
</style>
</head>`

func main() {
	ch = make(chan string)
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
	p := r.URL.Path
	if p == "/" {
		index(w, r)
		return
	} else if p == "/watch" {
		watch(w, r)
		return
	} else {
		if strings.HasPrefix(p, "/c") && strings.HasSuffix(p, ".png") {
			ch <- p[1 : len(p)-4]
		}
	}
}

func index(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	flusher, ok := w.(http.Flusher)
	if !ok {
		return
	}
	w.Write([]byte(head))
	flusher.Flush()
	// Send <p> grid
	w.Write([]byte("<body>\n"))
	for i := 0; i < H; i++ {
		w.Write([]byte("<div>"))
		for j := 0; j < W; j++ {
			w.Write([]byte(fmt.Sprintf("<p id=\"c%dx%d\"></p>", i, j)))
		}
		w.Write([]byte("</div>\n"))
	}
	w.Write([]byte("</body>\n"))
	flusher.Flush()
	// Send CSS
	w.Write([]byte("<style>"))
	for i := 0; i < H; i++ {
		for j := 0; j < W; j++ {
			id := fmt.Sprintf("c%dx%d", i, j)
			s := fmt.Sprintf("#%s:hover{background:url(\"%s.png\")}", id, id)
			w.Write([]byte(s))
		}
	}
	w.Write([]byte("</style>"))
	flusher.Flush()
}

func watch(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	flusher, ok := w.(http.Flusher)
	if !ok {
		return
	}
	w.Write([]byte(head))
	flusher.Flush()
	// Send <p> grid
	w.Write([]byte("<body>\n"))
	for i := 0; i < H; i++ {
		w.Write([]byte("<div>"))
		for j := 0; j < W; j++ {
			w.Write([]byte(fmt.Sprintf("<p id=\"c%dx%d\"></p>", i, j)))
		}
		w.Write([]byte("</div>\n"))
	}
	w.Write([]byte("</body>\n"))
	flusher.Flush()
	// Listen to ch for updates and write to response
	for p := range ch {
		s := fmt.Sprintf("<style>#%s{background:#000}</style>\n", p)
		_, err := w.Write([]byte(s))
		if err != nil {
			return
		}
		flusher.Flush()
	}
}
Regarder la vidéo de démonstration

Source : twitter, GitHub

Et vous ?

Que pensez-vous de sa méthode ?

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de melka one
Membre éprouvé https://www.developpez.com
Le 10/05/2019 à 9:33
bonjour

il y a rien de nouveau en soit ce que je comprend pas c'est comment les donnés de coordonné peuvent être envoyé sans passer par ajax qui fonction avec javascript

l'info fait un peut newbie.
Avatar de Doksuri
Membre émérite https://www.developpez.com
Le 10/05/2019 à 9:43
Citation Envoyé par melka one Voir le message
ce que je comprend pas c'est comment les donnés de coordonné peuvent être envoyé sans passer par ajax qui fonction avec javascript
c'est parce que tu n'as pas lu l'article...
quand tu hover un element, en css tu lui fou un background-image, ce qui va lancer un telechargement d'image, ce qui est "catchable" cote serveur
comme le gars a fait un genre de grille. il peut savoir sur quelle cellule tu as la souris
=> plus ta maille est petite, plus tu seras precis dans le positionnement

l'info parait newbie car c'est une technique bidon qui existe depuis la nuit des temps... mais personne n'avait encore eu l'idee d'en faire du tracking... (en tout cas, ca ne m'etais jamais venu a l'esprit)
Avatar de strato35
Membre habitué https://www.developpez.com
Le 10/05/2019 à 9:53
Rien de nouveau en effet, c'est marrant car quelques heures avant de lire l'article je suis tombé sur ça https://github.com/kkuchta/css-only-chat
Comme quoi ...
Avatar de Doksuri
Membre émérite https://www.developpez.com
Le 10/05/2019 à 9:59
Citation Envoyé par strato35 Voir le message
c'est marrant car quelques heures avant de lire l'article je suis tombé sur ça https://github.com/kkuchta/css-only-chat
moi aussi ^^

je n'y avais pas prete attention, car je trouvait le concept un peut "overkill"
Avatar de transgohan
Expert éminent https://www.developpez.com
Le 10/05/2019 à 11:17
Citation Envoyé par strato35 Voir le message
Rien de nouveau en effet, c'est marrant car quelques heures avant de lire l'article je suis tombé sur ça https://github.com/kkuchta/css-only-chat
Comme quoi ...
Si on regarde ses sources d'inspiration on pointe justement sur le tweet ... twit ? twite ? message ! du chercheur.
Avatar de strato35
Membre habitué https://www.developpez.com
Le 10/05/2019 à 12:17
Citation Envoyé par transgohan Voir le message
Si on regarde ses sources d'inspiration on pointe justement sur le tweet ... twit ? twite ? message ! du chercheur.
La boucle est bouclée
Avatar de Dasoft
Membre habitué https://www.developpez.com
Le 10/05/2019 à 12:53
quand tu hover un element, en css tu lui fou un background-image, ce qui va lancer un telechargement d'image, ce qui est "catchable" cote serveur
comme le gars a fait un genre de grille. il peut savoir sur quelle cellule tu as la souris
L'image aura bien été chargée côté serveur et gérée par un handler mais l'information sera inutile vu que l'appel ne se fera qu'une seule fois pour cette zone (car en cache navigateur) donc l'intérêt est quasi nul, à moins que quelque chose m’échappe
Avatar de Sodium
Membre extrêmement actif https://www.developpez.com
Le 10/05/2019 à 13:18
Ce n'est pas très compliqué à bloquer, il suffit d'empêcher le chargement d'images au hover. Ce ne sera pas une grande perte car quand cela arrive c'est en général que le développeur n'a pas fait son job correctement.
Avatar de melka one
Membre éprouvé https://www.developpez.com
Le 10/05/2019 à 18:53
quand tu hover un element, en css tu lui fou un background-image, ce qui va lancer un telechargement d'image, ce qui est "catchable" cote serveur
bien reçu mais ça reste simple et évident
Avatar de transgohan
Expert éminent https://www.developpez.com
Le 10/05/2019 à 19:32
Citation Envoyé par Dasoft Voir le message
L'image aura bien été chargée côté serveur et gérée par un handler mais l'information sera inutile vu que l'appel ne se fera qu'une seule fois pour cette zone (car en cache navigateur) donc l'intérêt est quasi nul, à moins que quelque chose m’échappe
Va voir le détail du chat pur CSS linké par strato35.
Tu auras une explication du comment faire pour ne pas avoir ce problème, c'est ce qui lui posait problème pour ses boutons.
Contacter le responsable de la rubrique Développement Web

Partenaire : Hébergement Web