Skip to content
KitploitKITPLOIT
OutilsBlog
Log in
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
POC-CVE-2026-65971 — Preuve de concept et analyse technique pour CVE-2026-65971 — injection SQL via la propriété Livewire sortDirection dans power-components/livewire-powergrid (< 6.10.4) | Kitploit
Outils/GitHubGitHub/biitts/poc-cve-2026-65971
Analyse des VulnérabilitésExploitationExploitation d'Applications WebTests d'IntrusionArticles et RechercheApprentissage et Éducation
GitHubbiitts/poc-cve-2026-65971

POC-CVE-2026-65971

Preuve de concept et analyse technique pour CVE-2026-65971 — injection SQL via la propriété Livewire sortDirection dans power-components/livewire-powergrid (< 6.10.4)

Voir le dépôt
110il y a 2 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2026-65971 — Injection SQL dans Livewire PowerGrid via sortDirection

Preuve de concept et analyse technique complète pour CVE-2026-65971 / GHSA-7fgc-3h6c-698r, une injection SQL dans power-components/livewire-powergrid accessible via la propriété Livewire publique sortDirection.

CVECVE-2026-65971
GHSAGHSA-7fgc-3h6c-698r
Paquetpower-components/livewire-powergrid (Composer / Packagist)
Versions affectées>= 6.0.0, < 6.10.4
Version corrigée6.10.4
FaiblesseCWE-89 — Neutralisation incorrecte des éléments spéciaux utilisés dans une commande SQL
Sévérité7.6 Élevée — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L
Signalé parCaio Fabrício (@BiiTts)
DivulgationCoordonnée, via un avis de sécurité privé GitHub
├── poc/exploit_powergrid_sqli.py working exploit — confirm + blind extraction
├── lab/ build the vulnerable app to reproduce it yourself
├── evidence/EVIDENCE.txt raw lab notes from confirmation
├── patch/security-fix-v6.10.4.diff the security-relevant portion of the official fix
└── detection/ Sigma rules + Nuclei template for defenders
---

## 🧠 Résumé

PowerGrid est un composant de datatable pour Laravel + Livewire (~2k étoiles, largement utilisé dans
les panneaux d'administration Laravel). Son état de tri réside dans deux **propriétés Livewire publiques**:```php
public string $sortField = 'id';
public string $sortDirection = 'asc';

Dans Livewire, une propriété publique fait partie du format wire du composant — tout client qui peut atteindre le composant peut la définir via POST /livewire/update. C'est voulu ; la frontière de sécurité réside dans ce que le serveur fait de la valeur.

La fonctionnalité naturalSort() de PowerGrid construit une expression ORDER BY brute contenant le littéral placeholder {sortDirection}, et un pipeline substitue ce placeholder par la valeur de propriété brute, non validée avant de passer la chaîne à orderByRaw(). Le mot-clé de direction se retrouve donc tel quel dans le SQL.

La méthode orderBy() de Laravel rejette tout ce qui n'est pas asc/desc, et c'est cette validation qui rend le chemin de tri ordinaire sûr. Le bug est qu'un second chemin, non validé, mène à la même clause — et qu'un attaquant peut l'emprunter en contournant entièrement le chemin validant (voir Le contournement).

Résultat : du SQL arbitraire dans la clause ORDER BY, exploitable comme oracle aveugle booléen/temporel pour lire toutes les données que l'utilisateur de la base peut lire.


🔥 Impact

Toute personne pouvant atteindre une table PowerGrid qui utilise naturalSort peut lire des données arbitraires depuis la base de données — autres tables, hachages de mots de passe, jetons de session, clés API, enregistrements multi-tenant — en utilisant un oracle temporel / booléen.

  • Confidentialité : Élevée. Lecture complète de tout ce que l'utilisateur de la base peut SELECT.
  • Intégrité : Faible. Les requêtes empilées sont bloquées par la configuration par défaut de PDO MySQL, donc ; UPDATE ... ne s'exécute pas. L'impact en écriture se limite à ce qu'une sous-requête peut déclencher.
  • Disponibilité : Faible. La même primitive donne à un attaquant SLEEP() et des sous-requêtes lourdes — trivialement abusables pour bloquer les threads de la base.
  • Le placement typique est le facteur aggravant. Les tables PowerGrid se trouvent dans les panneaux d'administration et les back-offices multi-tenant — exactement là où se trouvent les données intéressantes. Un utilisateur locataire à faibles privilèges atteignant une telle table peut exfiltrer toute la base de données.

Les privilèges requis sont PR:L car une datatable se trouve normalement derrière l'authentification de l'application. Si la table affectée est rendue sur une page non authentifiée, recalculez avec PR:N → 8.2 Élevé.


🧩 Cause racine — la chaîne de contamination complète

Trois fichiers, trois étapes. Toutes les références concernent le tag vulnérable v6.10.3.

Étape 1 — Source : une propriété publique contrôlée par l'attaquant

`src/Concerns/Sorting.php````php public string $sortField = 'id'; // line 11 public string $sortDirection = 'asc'; // line 13

Aucune des deux propriétés n'a de liste blanche, de règle de validation ou de setter de normalisation. `sortDirection` est uniquement affectée ou inversée :```php
public function reverseSort(): string    // line 37
{
    return $this->sortDirection === 'asc' ? 'desc' : 'asc';
}

updatedSortDirection() (ligne 103) existe — l'endroit naturel pour la validation — mais dans v6.10.3 il ne gère que la comptabilité du chargement paresseux. Il n'inspecte jamais la valeur.

Parce que Livewire hydrate les propriétés publiques directement à partir de la requête, sortDirection est totalement contrôlée par l'attaquant, comme une chaîne arbitraire, à ce stade.

Étape 2 — La clause brute : naturalSort() insère un espace réservé

src/Providers/Macros.php, lignes 102–116 — la macro de colonne naturalSort :```php Column::macro('naturalSort', function (bool $when = false, ?string $tableName = null): Column { $this->enableSort();

if ($when) {
    $this->rawQueries[] = [
        'method'   => 'orderByRaw',                          // <-- raw sink
        'sql'      => Sql::sortStringAsNumber($this->dataField),
        'bindings' => [],
    ];
}

return $this;

});

`Sql::sortStringAsNumber()` se résout en une expression propre à chaque pilote construite par
`getSortSqlByDriver()` dans `src/DataSource/Support/Sql.php` (lignes 60–100). Chaque variante de pilote
se termine par le même placeholder littéral :```php
$default = "$sortField+0 {sortDirection}";                                                          // line 76
'8.0.4'  => "CAST(NULLIF(REGEXP_REPLACE($sortField, '[[:alpha:]]+', ''), '') AS SIGNED INTEGER) {sortDirection}",  // MySQL, line 81
'0'      => "CAST($sortField AS INTEGER) {sortDirection}",                                          // SQLite, line 84
'0'      => "CAST(NULLIF(REGEXP_REPLACE($sortField, '\D', '', 'g'), '') AS INTEGER) {sortDirection}", // PgSQL, line 87
'0'      => "CAST(SUBSTRING(...) AS INT) {sortDirection}",                                          // SQL Server, line 90

La vulnérabilité est indépendante du driver — chaque branche interpole {sortDirection}.

Étape 3 — Sink: le placeholder est résolu avec la valeur brute de la propriété

`src/DataSource/Processors/Database/Pipelines/ColumnRawQueries.php````php private function resolvePlaceholders(?string $sql): ?string // line 56 { if (is_null($sql)) { return null; }

return preg_replace_callback('/\{(\w+)\}/', function ($matches) {
    $property = trim($matches[1]);

    return data_get($this->component, $property, '');   // line 65 — raw property, no escaping
}, $sql);

}

et l'exécution, ligne 52:```php
$query->{$method}($resolvedSql, $resolvedBindings);   // $method === 'orderByRaw'

data_get($this->component, 'sortDirection') renvoie la chaîne de l'attaquant, preg_replace_callback l'insère dans le texte SQL, et orderByRaw() — qui, par contrat, n'échappe pas son argument — la transmet à la base de données.

Télécharger l’outil