Skip to main content

Block deceptive look-alike usernames (admin/support impersonation, brand homoglyphs, leet, typosquatting) at registration time.

Project description

django-username-guard

PyPI version Python versions Django versions License: MIT CI

Bloque la création de comptes Django avec des noms d'utilisateur trompeurs : mots réservés (admin, support, noreply...), et leurs variantes typosquattées : admin1strateur, adminiistrateur, admlnistrateur, аdmin (cyrillique), 4dmin, etc. — et l'imitation de marques (leboncoin-support, lebоncoin, service_leboncoin...).

Pourquoi ?

Sur les places de marché type Leboncoin / Vinted, une partie des arnaques (exemple Numerama : « arnaque à l'IBAN ») repose sur des comptes qui se font passer pour le support officiel de la plateforme — souvent en exploitant des homoglyphes Unicode, du leet, ou des fautes de frappe sur la marque. Cet addon empêche la création initiale de tels comptes.

⚠️ Ce n'est pas une solution complète anti-phishing — c'est une couche parmi d'autres (badges officiels, vérification d'identité, détection de comportement, modération…). Mais bloquer ces noms à l'inscription élimine un vecteur d'ingénierie sociale très bon marché pour l'attaquant.

Comment ça marche

Trois couches de défense, toutes appliquées sur la forme normalisée du username :

  1. Normalisation — NFKC → casefold → mappage des homoglyphes (cyrillique, grec, IPA) → suppression des accents → dé-leet (4→a, 1→i, 0→o, @→a...) → suppression des non-alphanumériques → collapse des lettres répétées (admiiinadmin).
  2. Match exact / sous-chaîne / fuzzy contre la blocklist (admin, support...) : Damerau-Levenshtein ≤ 1, sous-chaîne avec budget de longueur (admin42 bloqué, adminlovesmusic autorisé).
  3. Protection de marque — pour les noms que tu déclares dans BRANDS, match plus strict : toute sous-chaîne ou variante fuzzy est bloquée (pas de budget de longueur). leboncoin_helper, support-leboncoin, lebоncoin (cyrillique), leb0ncoin, tous bloqués.

Installation

pip install django-username-guard
# settings.py
INSTALLED_APPS = [
    ...,
    "username_guard",
]

Utilisation

Sur ton modèle User personnalisé

# accounts/models.py
from django.contrib.auth.models import AbstractUser
from username_guard import DeceptiveUsernameValidator


class User(AbstractUser):
    username_validators = [
        *AbstractUser.username_validators,
        DeceptiveUsernameValidator(),
    ]

Sur ton formulaire d'inscription

from username_guard.forms import GuardedUserCreationForm
# Drop-in replacement de UserCreationForm

Manuel

from django.core.exceptions import ValidationError
from username_guard import DeceptiveUsernameValidator

validate = DeceptiveUsernameValidator()
try:
    validate("admin1strateur")
except ValidationError as e:
    print(e.code, e.message)  # deceptive_username | brand_impersonation

CLI (auditer une base existante)

python manage.py check_username admin1strateur leboncoin-support alice --show-normalized

Configuration

Tout est optionnel (settings.py) :

USERNAME_GUARD = {
    # Termes réservés. Override complet :
    # "BLOCKLIST": ("admin", "support", ...),

    # Plus simple — ajouter à la liste par défaut EN/FR :
    "EXTRA_BLOCKLIST": ("ceo", "founder", "monequipe"),

    # Marques que tu veux protéger d'usurpation. RÈGLE STRICTE :
    # toute sous-chaîne ou typo proche est rejetée.
    "BRANDS": ("leboncoin", "monsite", "monapp"),

    # Distance d'édition tolérée (0 = match exact uniquement)
    "MAX_DISTANCE": 1,

    # Rejeter les sous-chaînes (admin1, admin_, xadmin) ?
    "REJECT_SUBSTRING": True,

    # Budget de longueur pour la règle sous-chaîne (BLOCKLIST uniquement)
    # admin (5) + 3 = 8 caractères max -> "admin42" bloqué, "adminlover" non
    "SUBSTRING_PADDING": 3,

    # Taille minimale d'un terme blocklist pour activer la règle sous-chaîne
    "MIN_TERM_LEN_FOR_SUBSTRING": 4,
}

Exemples couverts

Username Bloqué ? Code Pourquoi
admin deceptive_username match exact
Administrateur deceptive_username casefold
admin1strateur deceptive_username leet 1→i
adminiistrateur deceptive_username ii→i
admlnistrateur deceptive_username DL=1
аdmin (cyrillique) deceptive_username homoglyphe
4dmin deceptive_username leet 4→a
r00t deceptive_username leet 0→o
support1 deceptive_username sous-chaîne bornée
leboncoin (BRANDS) brand_impersonation match exact
leboncoin-support brand_impersonation sous-chaîne marque
lebоncoin (cyrillique) brand_impersonation homoglyphe о→o
leb0ncoin brand_impersonation leet sur la marque
service_leboncoin brand_impersonation sous-chaîne marque
adminlovesmusic trop long, plausible
vivien, alice légitime

Threat model

Couvert :

  • Imitation de comptes admin / support génériques
  • Imitation de marque via homoglyphes Unicode (cyrillique, grec, IPA)
  • Leet-speak (4, 1, 0, @, $...)
  • Lettres dupliquées (adminiistrateur)
  • Fautes de frappe à 1 édition (admlnistrateur)
  • Bruit de ponctuation (ad-min_42)

Non couvert (par design) :

  • Les noms parfaitement légitimes qui contiennent un mot-clé en sous-chaîne longue (adminlovesmusic). Active MIN_TERM_LEN_FOR_SUBSTRING plus bas ou ajoute le terme dans BRANDS si ton domaine l'exige.
  • Les attaques runtime (account takeover, changement de pseudo après vérification, badge officiel falsifié dans l'UI) — c'est hors-scope d'un validateur de création.
  • La couverture complète d'UTS #39. Branche confusable_homoglyphs si tu en as besoin (PR bienvenue pour rendre ça optionnel).

Performance

DL distance pure-Python lancée contre chaque terme : O(n × m) par username. Avec une blocklist de < 200 termes c'est négligeable (< 0.5 ms). Si tu pousses au-delà, on peut ajouter un index BK-tree — ouvre une issue.

Développement

git clone https://github.com/viviengiraud/django-username-guard
cd django-username-guard
uv sync --all-extras
uv run pytest

Voir CONTRIBUTING.md.

Licence

MIT.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_username_guard-0.2.0.tar.gz (11.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_username_guard-0.2.0-py3-none-any.whl (12.5 kB view details)

Uploaded Python 3

File details

Details for the file django_username_guard-0.2.0.tar.gz.

File metadata

  • Download URL: django_username_guard-0.2.0.tar.gz
  • Upload date:
  • Size: 11.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.9 {"installer":{"name":"uv","version":"0.11.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for django_username_guard-0.2.0.tar.gz
Algorithm Hash digest
SHA256 344d152a8613dc2a550b392808188e93d88e58c8c4d27307c95bd68f3ab98dbb
MD5 f8b277f4348bae0f32a2310955ae9156
BLAKE2b-256 475c2ffaae56e356c7dcf4c77b4d450f64991e29e84ef5da5bbe950082b0086a

See more details on using hashes here.

File details

Details for the file django_username_guard-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: django_username_guard-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 12.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.9 {"installer":{"name":"uv","version":"0.11.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for django_username_guard-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5a941189dacbf15fd712e95de5c72b15c424179d5fa4f37b9e31166ea3638c80
MD5 98be4d6437e6590c48108804d557e832
BLAKE2b-256 89953a97a31389ab49936b1759bdfec527310547c717eb582e68083fd6054858

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page