Unlimited Store Credit: Finding an Economy-Breaking Bug in a Digital Storefront’s Discord Bot
A Case Study on Bypassing Admin Permissions by Exploiting a Bot’s Global State
TL;DR
I discovered a series of critical vulnerabilities in an e-commerce Discord bot, RGS | Assistant
. The bot correctly hid admin commands from regular users in its home server. However, by inviting the bot to a personal server where I was an administrator, the commands became visible. I found that the bot failed to validate which server the commands were being run in, allowing me to pass the permission check and manipulate my global user data (like store credits). This allowed for unlimited currency generation and posed a direct financial risk to the RGS | regameshop
digital storefront. The vulnerabilities were responsibly disclosed and promptly patched.
Discord bots are the automated heart of countless online communities. For an e-commerce server like RGS | regameshop, its official bot, RGS | Assistant, is more than just a utility; it’s a core part of its business operations, handling everything from user engagement to its vital store credit system.
But what happens when the keys to that system can be legitimately obtained, just in the wrong place?
My investigation began with a simple curiosity, sparked by a server announcement about a small bug bounty. I knew that as a regular user, I wouldn’t be able to see the bot’s administrative commands in the RGS | regameshop
server—Discord's permission system correctly hid them from me.
This led to a critical “what if?” moment: What if I observed the bot in an environment where I did have full control? I created a private Discord server and invited RGS | Assistant
to join.
Instantly, my hypothesis was confirmed. Inside my own server, where I was the administrator, the bot’s full suite of commands became visible, including the highly sensitive /donate
command. This immediately posed a security question: Does the bot differentiate between an administrator on its official home server and an administrator on any random server? I decided to find out.
The Critical Flaw: A Problem of Trust and Global State
This wasn’t just a simple missing check. It was a more subtle and dangerous architectural flaw rooted in two combined factors: Incorrect Authorization Scope and Global State Management.
- Incorrect Authorization Scope: The bot diligently checked if a user had the
Administrator
permission in the server where a command was executed. However, it failed to validate which server it was in. It blindly trusted that an "Administrator" anywhere was an administrator everywhere, never checking if the command was being run from the officialRGS | regameshop
server. - Global State Management: This trust issue was combined with a critical architectural choice. A user’s data — their RGSPOINTS balance, invites, etc. — was tied to their global Discord ID, not their per-server profile.
This created a devastating loophole: by inviting the bot to a personal server where the user is an administrator, they could legitimately pass the permission check and then manipulate their global balance, with the changes carrying over instantly to the official store.
The following commands were vulnerable to this exploit:
- /donate: Added unlimited store credits (RGSPOINTS) to any user’s global balance.
- /remove: Forcefully removed credits from any user’s global balance.
- /addinvite & /removeinvite: Manipulated a user’s global invite stats.
- /restock: When run from any server, would send the
@everyone
ping to the#restock
channel specifically in the mainRGS | regameshop
server.
Proof of Concept: The “Rogue Server” Exploit
This demonstrates how to gain administrative access to the bot’s functions.
Steps to Reproduce:
- Create a New Server: Create your own private Discord server. As the owner, you automatically have the
Administrator
permission. - Invite the Bot: Use the public* invite link for
RGS | Assistant
to add the bot to your new, personal server. - Execute Command as Admin: Inside your own server, execute a privileged command. For example:
/donate user:@Yourself amount:10
. - Bot Validates Permissions: The bot performs its check: “Does this user have the
Administrator
permission in this server?" The answer is YES. The command is successfully executed. - Verify Global Impact: Navigate back to the official
RGS | regameshop
server and check your balance. You will find that the 10 RGSPOINTS have been added to your account, ready to be spent.
Analyzing the Domino Effect: Covert Exploitation and Persistent Threat
The ability to exploit these commands from a different server created a covert and persistent threat.
Unlike commands run in the main server, these actions would not appear in any logs visible to the RGS | regameshop
moderators, making the exploitation difficult to detect in real-time. Crucially, an administrator could identify a user with a suspicious balance and ban them from the main server, but this would be an ineffective solution. The banned user could simply continue to generate credits from their own private server.
While the fraudulent activity would eventually be traceable when a user attempts to purchase an item with a massive, un-granted balance, the act of exploitation could continue indefinitely.
Responsible Disclosure & Remediation
Upon discovering these vulnerabilities, I compiled a detailed report for the developer which included not just the flaws but also the exact solution required to fix the root cause.
The recommended remediation was to move away from role-based checks (which are server-dependent) and implement a global, ID-based permission system for these global commands.
The proposed fix consisted of the following steps:
- Create an Admin Whitelist: Store the unique Discord User IDs of all authorized administrators in a secure configuration file (e.g.,
.env
orconfig.json
). - Implement an ID Check: For every privileged command, the bot must first retrieve the User ID of the person executing the command.
- Validate Against Whitelist: Before running any other logic, the bot must check if the user’s ID exists in the authorized admin list.
- Enforce a ‘Default Deny’ Policy: If the user’s ID is on the list, the command proceeds. If it is not, the command is immediately halted and a “Permission Denied” error is sent.
This approach is highly effective because it is completely independent of the context (server or DMs) where the command is run, ensuring only true administrators can ever access these sensitive functions.
Disclosure Timeline:
- Vulnerabilities Discovered: June 12, 2025
- Detailed Report Sent to Developer: June 12, 2025
- Report Acknowledged: June 12, 2025
- Vulnerabilities Patched & Confirmed: June 13, 2025
- Bounty Awarded: June 12, 2025
The developer was responsive and cooperative. After confirming the patch was in place, they awarded the bounty of 25,000 IDR in store credit for the consolidated report.
Conclusion
This experience highlights that security flaws are often found in the assumptions developers make — in this case, assuming that a permission check in one context is valid for all contexts. It underscores the importance of validating not just a user’s role, but also the scope in which they hold that role. For any application with a financial component, every potential entry point must be secured with a robust, context-aware permission system.
For me, it was a fantastic learning experience that reinforced the importance of thinking outside the box and testing the logic, not just the features.
Connect With Me
Thanks for reading! If you’re interested in security, development, or just want to connect, you can find me here:
- LinkedIn:
https://linkedin.com/in/vankevindo
- GitHub:
https://github.com/vankevindo
- GitLab:
https://gitlab.com/vankevindo