August 24, 2026
Unauthenticated Strapi Relational-Filter Leak → Super-Admin Takeover → Server-Side Code Execution
How a seemingly harmless public API filter became a full compromise chain
By redhunter01
12 min read
How a seemingly harmless public API filter became a full compromise chain
Some of the most interesting bug bounty vulnerabilities aren't a single bug. They're chains.
This investigation started with a public Strapi content endpoint that appeared to expose only blog data. By understanding how Strapi processed relational filters, I discovered that an unauthenticated user could indirectly query private fields belonging to administrator accounts.
That created a boolean oracle.
The oracle allowed recovery of a live administrator password-reset token character by character. The token could then be used to reset the administrator's password and obtain a valid super-admin JWT.
From there, I investigated what administrative functionality could be reached. An editable email template accepted dynamic Lodash expressions, which ultimately allowed JavaScript execution inside the Strapi server process.
The complete chain was:
Unauthenticated request
↓
Public relational filter
↓
Private admin-field disclosure
↓
Boolean oracle
↓
Password-reset token recovery
↓
Super-admin password reset
↓
Valid administrator JWT
↓
Editable server-side template
↓
JavaScript execution
↓
Filesystem write/readUnauthenticated request
↓
Public relational filter
↓
Private admin-field disclosure
↓
Boolean oracle
↓
Password-reset token recovery
↓
Super-admin password reset
↓
Valid administrator JWT
↓
Editable server-side template
↓
JavaScript execution
↓
Filesystem write/readThe key lesson is that authorization bugs, information disclosure, credential-reset functionality, and server-side template injection can become dramatically more serious when chained together.
1. The Initial Attack Surface
The application was running an older Strapi 3.x deployment.
The affected content endpoint was:
GET /blog-ensGET /blog-ensThe application allowed public filtering through query parameters.
For example:
GET /blog-ens?_where[created_by.id]=2GET /blog-ens?_where[created_by.id]=2No authentication or authorization header was required.
At first glance, this doesn't necessarily look dangerous.
A public blog endpoint being filterable is common.
The interesting question was:
What relationships can these filters traverse?
That question led to the vulnerability.
2. The Important Discovery: Relational Filters
The public blog-ens content type had a relationship through:
created_bycreated_byThe filter could therefore reference properties belonging to the related administrator object.
Conceptually:
blog-ens
│
└── created_by
│
└── admin_users
│
├── email
├── isActive
├── blocked
├── role
└── resetPasswordTokenblog-ens
│
└── created_by
│
└── admin_users
│
├── email
├── isActive
├── blocked
├── role
└── resetPasswordTokenThe critical problem was that fields could be used in filtering even though they were not returned in the normal API response.
That distinction is extremely important.
An application might correctly hide:
resetPasswordTokenresetPasswordTokenfrom JSON responses while accidentally allowing:
_where[created_by.resetPasswordToken_gt]=..._where[created_by.resetPasswordToken_gt]=...to query it.
The data isn't being directly returned.
Instead, the application is unintentionally providing an oracle about the data.
3. The Security Principle: Hidden Fields Can Still Leak
This is one of the biggest lessons from the research.
Developers often think:
"The API doesn't return the private field, therefore the field is protected."
That's not necessarily true.
Consider an API returning:
{
"username": "alice"
}{
"username": "alice"
}while the backend still allows queries against a private field:
?_where[passwordResetToken_gt]=...?_where[passwordResetToken_gt]=...The attacker doesn't need the server to return:
passwordResetTokenpasswordResetTokendirectly.
They only need the server to answer questions about it.
That is an indirect information disclosure.
4. Turning Filtering Into a Boolean Oracle
The key discovery was that relational comparison operators could be used against the private field.
For example:
_where[created_by.resetPasswordToken_gt]=<PROBE>_where[created_by.resetPasswordToken_gt]=<PROBE>The number of returned blog records changed depending on whether the stored token was lexicographically greater than the supplied value.
That effectively created:
Condition TRUE
↓
17 records
Condition FALSE
↓
0 recordsCondition TRUE
↓
17 records
Condition FALSE
↓
0 recordsThe API had become a binary communication channel.
Conceptually:
Attacker
│
│ "Is token > X?"
▼
Strapi
│
▼
Database
│
├── TRUE → records returned
│
└── FALSE → no recordsAttacker
│
│ "Is token > X?"
▼
Strapi
│
▼
Database
│
├── TRUE → records returned
│
└── FALSE → no recordsThis is the same fundamental idea behind blind SQL injection:
You don't need the application to directly reveal the secret if you can repeatedly ask questions about it.
5. First Prove the Oracle
Before attempting to recover anything sensitive, I established a baseline.
The public request:
GET /blog-ens?_where[created_by.id]=2GET /blog-ens?_where[created_by.id]=2returned:
1717records.
Then I tested whether the administrator had a reset token.
The condition:
resetPasswordToken_null=falseresetPasswordToken_null=falsereturned:
1717while:
resetPasswordToken_null=trueresetPasswordToken_null=truereturned:
00That established a reliable boolean signal.
6. What the Oracle Could Tell Me
Once the comparison operator worked, the next question was:
Can I recover the actual value?
The operator:
_gt_gtallowed questions such as:
Is the token greater than A?
Is the token greater than B?
Is the token greater than C?Is the token greater than A?
Is the token greater than B?
Is the token greater than C?Instead of trying every possible character sequentially, the search space can be divided.
For example, conceptually:
A-F
G-L
M-R
S-X
Y-ZA-F
G-L
M-R
S-X
Y-ZThen narrow the range.
This is essentially binary search over the character set.
The source report used this approach against the hexadecimal token alphabet and recovered the complete 40-character value.
7. Why Binary Search Matters
This is a useful general technique for bug bounty hunters.
Suppose a secret character can be one of:
0123456789abcdef0123456789abcdefA naive approach might ask:
Is it 0?
Is it 1?
Is it 2?
...Is it 0?
Is it 1?
Is it 2?
...But a comparison oracle allows:
Is it greater than 7?Is it greater than 7?Then:
0-7
8-f0-7
8-fThen divide again.
The amount of information gained per request becomes much larger.
The important conceptual lesson is:
Whenever you have an ordered oracle, think binary search.
8. Recovering the Full Token
The token itself was deliberately omitted from the published report because it was a live credential.
The important point isn't the actual token.
It's the methodology.
For every position:
Position 1
↓
Determine character
Position 2
↓
Determine character
Position 3
↓
Determine character
...
Position 40
↓
Determine characterPosition 1
↓
Determine character
Position 2
↓
Determine character
Position 3
↓
Determine character
...
Position 40
↓
Determine characterAfter recovering the candidate value, I performed an exact-match verification.
The complete candidate returned:
1717records.
Changing one character caused:
00records.
Removing one character also caused:
00records.
That is important evidence.
It demonstrates that the oracle recovered the exact value, rather than simply producing an ambiguous partial result.
9. The Critical Pivot: What Is This Token?
At this point, I had to understand the security meaning of the recovered value.
The field was:
resetPasswordTokenresetPasswordTokenThat immediately changed the severity of the finding.
A reset token isn't merely information.
It is potentially an authentication credential.
This is where vulnerability chaining becomes important.
The chain changed from:
Information disclosureInformation disclosureto:
Information disclosure
↓
Authentication materialInformation disclosure
↓
Authentication materialThe next question became:
Does the password-reset endpoint accept the recovered token?
10. Using the Recovered Token
The administrator reset endpoint was:
POST /admin/reset-passwordPOST /admin/reset-passwordThe request supplied:
{
"resetPasswordToken": "<RECOVERED_TOKEN>",
"password": "<TEMPORARY_VERIFICATION_PASSWORD>"
}{
"resetPasswordToken": "<RECOVERED_TOKEN>",
"password": "<TEMPORARY_VERIFICATION_PASSWORD>"
}The server returned:
HTTP 200HTTP 200along with a valid administrator JWT.
The resulting identity was confirmed as:
isActive: true
role: strapi-super-adminisActive: true
role: strapi-super-adminThe JWT successfully authenticated to:
GET /admin/users/meGET /admin/users/meand returned:
200 OK200 OKAt this point, the account-takeover portion of the chain was proven.
11. Why This Was More Serious Than Token Disclosure
Imagine two findings.
Finding A
Attacker can determine whether a reset token exists.Attacker can determine whether a reset token exists.Interesting, but limited.
Finding B
Attacker can recover the complete reset token
↓
Submit it to password-reset endpoint
↓
Change administrator password
↓
Receive administrator JWTAttacker can recover the complete reset token
↓
Submit it to password-reset endpoint
↓
Change administrator password
↓
Receive administrator JWTThat's a fundamentally different impact.
The attacker has crossed the boundary from:
Information disclosureInformation disclosureto:
Account takeoverAccount takeoverThis is exactly why researchers should always ask:
"What does this leaked value actually unlock?"
12. Confirming Persistent Authentication
I didn't stop after receiving the JWT.
I also verified that the newly assigned administrator password could be used through the normal administrator login endpoint.
The login request returned another valid administrator JWT.
That eliminated another possible ambiguity:
Maybe the reset endpoint generated a temporary or unusual token.Maybe the reset endpoint generated a temporary or unusual token.No.
The password change produced a functioning administrator credential.
13. Mapping the Administrative Attack Surface
Now that I had administrator access, the next phase was:
What can a Strapi super-admin actually control?
Rather than immediately modifying application code, I looked for administrative functionality involving:
Users
Settings
Email templates
Content
Plugins
Configuration
TemplatesUsers
Settings
Email templates
Content
Plugins
Configuration
TemplatesOne particularly interesting area was:
/users-permissions/email-templates/users-permissions/email-templatesThe application allowed authenticated administrators to retrieve and modify these templates.
This became the second major pivot.
14. The Template Engine Was the Next Weak Link
The email template functionality accepted dynamic Lodash template expressions.
This created a dangerous situation:
Administrator-controlled template
↓
Template renderer
↓
JavaScript evaluation
↓
Node.js server processAdministrator-controlled template
↓
Template renderer
↓
JavaScript evaluation
↓
Node.js server processIf arbitrary expressions can execute rather than merely substitute inert variables, the template system is no longer just formatting email.
It becomes a potential code-execution primitive.
The report confirmed that the crafted template expression was evaluated during password-reset template rendering.
15. Proving Server-Side Execution Safely
This is where responsible testing becomes extremely important.
I did not attempt destructive actions.
Instead, the proof was designed around a controlled filesystem marker.
The server-side execution:
1. Write a known marker to /tmp
2. Read the marker back
3. Use that value against a researcher-owned test account1. Write a known marker to /tmp
2. Read the marker back
3. Use that value against a researcher-owned test accountThe marker was:
strapi_e2e_rce_20260619strapi_e2e_rce_20260619and was written to a temporary file.
The server then read the file and used the value to rename an account controlled by the researcher.
This is an excellent pattern for demonstrating RCE:
Controlled input
↓
Server-side evaluation
↓
Known filesystem operation
↓
Read result
↓
Controlled application-side effectControlled input
↓
Server-side evaluation
↓
Known filesystem operation
↓
Read result
↓
Controlled application-side effectThe proof establishes execution without requiring destructive exploitation.
16. Why the Filesystem Proof Is Strong
Simply saying:
"I think I have RCE."
is weak.
A stronger proof demonstrates an observable server-side side effect.
For example:
Attacker-controlled template
↓
Node.js filesystem API
↓
/tmp/test-marker
↓
Read marker
↓
Modify researcher-owned objectAttacker-controlled template
↓
Node.js filesystem API
↓
/tmp/test-marker
↓
Read marker
↓
Modify researcher-owned objectNow there are multiple independent signals:
Filesystem write
+
Filesystem read
+
Application-side effectFilesystem write
+
Filesystem read
+
Application-side effectThat makes the RCE claim extremely difficult to dispute.
17. The Complete Attack Chain
The final chain was:
UNAUTHENTICATED
│
▼
Public Strapi API
│
▼
Relational filter
│
▼
Private admin-field oracle
│
▼
resetPasswordToken recovered
│
▼
/admin/reset-password
│
▼
Super-admin JWT
│
▼
Administrator privileges
│
▼
Editable email templates
│
▼
Dynamic template evaluation
│
▼
JavaScript in Node.js process
│
┌──────┴──────┐
▼ ▼
Filesystem write Filesystem read
│ │
└──────┬──────┘
▼
Confirmed server RCEUNAUTHENTICATED
│
▼
Public Strapi API
│
▼
Relational filter
│
▼
Private admin-field oracle
│
▼
resetPasswordToken recovered
│
▼
/admin/reset-password
│
▼
Super-admin JWT
│
▼
Administrator privileges
│
▼
Editable email templates
│
▼
Dynamic template evaluation
│
▼
JavaScript in Node.js process
│
┌──────┴──────┐
▼ ▼
Filesystem write Filesystem read
│ │
└──────┬──────┘
▼
Confirmed server RCEThis is why the final severity was critical.
18. The Mindset Behind the Chain
The most valuable part of this investigation was not knowing a particular Strapi endpoint.
It was asking the right question at each stage.
Initial discovery
What can this public endpoint filter?
After discovering relational filtering
Which related objects can it reach?
After finding private fields
Can I turn this into a boolean oracle?
After finding the reset token
Is this token actually usable?
After obtaining admin access
What administrative features process attacker-controlled input?
After finding editable templates
Is this template engine performing evaluation or just interpolation?
After finding server-side execution
Can I prove execution safely with a controlled side effect?
This is the mindset I would recommend to other hunters:
Every vulnerability should lead to a new question.
19. A Repeatable Methodology for Relational-Filter Bugs
When testing APIs built on frameworks such as Strapi, don't only inspect the JSON response.
Study the query language exposed by the API.
Look for operators such as:
_where
_eq
_ne
_gt
_gte
_lt
_lte
_contains
_null
_sort_where
_eq
_ne
_gt
_gte
_lt
_lte
_contains
_null
_sortThen investigate relationships:
created_by
updated_by
author
owner
user
organization
teamcreated_by
updated_by
author
owner
user
organization
teamThe important question is:
Can a public object query properties belonging to a private related object?
20. Test Authorization at the Query Layer
An application may correctly enforce:
Do not return admin_users.passwordDo not return admin_users.passwordbut accidentally allow:
admin_users.password_gt
admin_users.resetPasswordToken_eq
admin_users.email_contains
admin_users.role_eqadmin_users.password_gt
admin_users.resetPasswordToken_eq
admin_users.email_contains
admin_users.role_eqThis creates a subtle authorization failure.
The application has protected the output field but not the query capability.
That distinction is extremely important.
21. Look for Comparison Operators
Comparison operators are particularly interesting because they can create oracles.
For example:
_gt
_lt
_eq
_contains
_null_gt
_lt
_eq
_contains
_nullIf the number of returned records depends on the value being tested, you potentially have:
Information
↓
Boolean condition
↓
Observable responseInformation
↓
Boolean condition
↓
Observable responseThat is enough to begin extracting data.
22. Look for Secrets, Not Just Usernames
Once a private field becomes queryable, prioritize fields with security significance:
resetPasswordToken
apiKey
secret
token
verificationCode
passwordResetToken
session
oauthTokenresetPasswordToken
apiKey
secret
token
verificationCode
passwordResetToken
session
oauthTokenA user's:
namenamemay be interesting.
A user's:
passwordResetTokenpasswordResetTokencan become an authentication bypass.
Always ask:
What does this field enable?
23. Don't Assume "Private" Means Unreachable
Framework metadata often contains concepts such as:
private
hidden
protected
admin-onlyprivate
hidden
protected
admin-onlyBut these controls may only affect serialization.
A field can be:
hidden from JSONhidden from JSONwhile remaining:
queryable
sortable
filterable
searchablequeryable
sortable
filterable
searchableThat is a dangerous mismatch.
The security policy must apply to all ways of interacting with the data, not only the final response.
24. Test Reset Tokens Like Credentials
Password-reset tokens should be treated as authentication credentials.
If you discover:
resetPasswordTokenresetPasswordTokenask:
Is it expired?
Is it single-use?
Is it bound to the correct account?
Does it invalidate old sessions?
Does it require another verification factor?
Can it reset an administrator?Is it expired?
Is it single-use?
Is it bound to the correct account?
Does it invalidate old sessions?
Does it require another verification factor?
Can it reset an administrator?In this case, the recovered token was accepted directly by the administrator reset endpoint.
That transformed the disclosure into account takeover.
25. After Account Takeover, Don't Immediately Chase RCE
This is another important methodology lesson.
Once administrator access is obtained, first map privileges.
Ask:
What can this role modify?
Look for:
Templates
Plugins
Configuration
Webhooks
Scripts
Uploads
Integrations
Email templates
ContentTemplates
Plugins
Configuration
Webhooks
Scripts
Uploads
Integrations
Email templates
ContentSome features are much more dangerous than others because they process administrator-controlled input through interpreters.
26. Template Engines Deserve Special Attention
Whenever you find:
Lodash templates
Handlebars
Mustache
Jinja
Twig
EJS
Pug
custom expression languagesLodash templates
Handlebars
Mustache
Jinja
Twig
EJS
Pug
custom expression languagesask:
Is this merely interpolation, or is the input actually evaluated?
There is a huge difference between:
Hello {{username}}Hello {{username}}and:
evaluate arbitrary expressionevaluate arbitrary expressionThe first is generally templating.
The second can become code execution.
27. The Difference Between Interpolation and Evaluation
A secure email system might allow:
Hello <%= username %>Hello <%= username %>where username is supplied as inert data.
A dangerous design allows administrators to provide arbitrary template logic that can access runtime objects or JavaScript APIs.
The security boundary therefore needs to be:
Explicit allowed variables
+
No arbitrary evaluationExplicit allowed variables
+
No arbitrary evaluationThe report's remediation specifically recommends removing dynamic Lodash template evaluation and allowing only inert, explicitly approved variables.
28. Proving RCE Responsibly
When you believe you have server-side code execution, don't immediately:
execute shell commands
dump environment variables
steal credentials
modify production filesexecute shell commands
dump environment variables
steal credentials
modify production filesA much better proof is:
write harmless marker
↓
read marker
↓
perform controlled change
↓
restore everythingwrite harmless marker
↓
read marker
↓
perform controlled change
↓
restore everythingThe original investigation followed this principle.
The proof:
- wrote a marker to
/tmp, - read it back,
- changed only a researcher-owned test user,
- restored the application state afterward.
That is a strong example of controlled exploitation.
29. Cleanup Matters
After demonstrating a critical vulnerability, cleanup should be part of the workflow.
The investigation restored:
- original email templates,
- the temporary filesystem marker,
- the researcher-owned test user,
- registration configuration.
It also confirmed that the old reset token had been consumed.
This is important because responsible security research isn't just:
Exploit → Screenshot → ReportExploit → Screenshot → ReportIt is:
Discover
↓
Validate
↓
Demonstrate
↓
Minimize impact
↓
Restore state
↓
Document
↓
ReportDiscover
↓
Validate
↓
Demonstrate
↓
Minimize impact
↓
Restore state
↓
Document
↓
Report30. Root Causes
The chain had multiple underlying security failures.
1. Relational authorization failure
Public filters could traverse into private administrator fields.
2. Private-field filtering was not restricted
Sensitive properties could participate in:
_gt
_lt
_eq
_contains
_null_gt
_lt
_eq
_contains
_nulland related query operations.
3. Reset tokens were indirectly exposed
A security-sensitive credential became recoverable through the public query oracle.
4. Reset tokens were sufficient for administrator password reset
The token could be exchanged for a new administrator password and JWT.
5. Dynamic server-side template evaluation
Administrator-editable email templates allowed executable expressions.
Together:
Authorization failure
+
credential disclosure
+
weak reset boundary
+
template executionAuthorization failure
+
credential disclosure
+
weak reset boundary
+
template executioncreated the full compromise chain.
31. Recommended Remediation
The remediation should happen at multiple layers.
Immediately
Rotate administrator credentials
Invalidate administrator sessions
Invalidate existing reset tokensRotate administrator credentials
Invalidate administrator sessions
Invalidate existing reset tokensSecrets
Rotate:
Database credentials
Email credentials
API keys
Cloud credentials
JWT/session secretsDatabase credentials
Email credentials
API keys
Cloud credentials
JWT/session secretsFramework
Upgrade the EOL Strapi v3 deployment to a supported version.
API authorization
Prevent public relational filters from traversing private relationships such as:
created_by
updated_by
admin_userscreated_by
updated_by
admin_usersQuery allowlisting
Explicitly allow only safe:
fields
operators
relationshipsfields
operators
relationshipsrather than allowing arbitrary relational queries.
Template security
Remove dynamic template evaluation.
Only permit predefined inert variables.
32. What Bug Bounty Hunters Can Learn From This
Lesson 1 — Public APIs can expose private data indirectly
Don't only inspect returned JSON.
Inspect what the API allows you to query.
Lesson 2 — Relationships are attack surfaces
Whenever you see:
created_by
owner
author
user
team
organizationcreated_by
owner
author
user
team
organizationask:
Can I cross this relationship into something more privileged?
Lesson 3 — Boolean oracles are powerful
You don't need a direct database dump.
If you can reliably distinguish:
TRUETRUEfrom:
FALSEFALSEyou may be able to reconstruct the underlying value.
Lesson 4 — Secrets are pivots
If you discover:
token
reset token
API key
session identifiertoken
reset token
API key
session identifierdon't treat it as just another piece of data.
Ask what authentication boundary it crosses.
Lesson 5 — Chain vulnerabilities
The initial bug was not:
"RCE.""RCE."It was:
public relational filterpublic relational filterThat led to:
private-field oracleprivate-field oraclewhich led to:
reset-token disclosurereset-token disclosurewhich led to:
account takeoveraccount takeoverwhich led to:
template injectiontemplate injectionwhich led to:
server-side code executionserver-side code executionThat's the essence of advanced bug bounty research.
33. My Checklist for Similar Targets
When testing a modern API-backed CMS:
[ ] Identify framework and version
[ ] Identify public content types
[ ] Enumerate filter operators
[ ] Enumerate relationships
[ ] Test private relationships
[ ] Test private fields
[ ] Test comparison operators
[ ] Look for boolean oracles
[ ] Identify security-sensitive fields
[ ] Test reset-token behavior
[ ] Test token invalidation
[ ] Map authenticated privileges
[ ] Enumerate administrator functionality
[ ] Identify template engines
[ ] Test interpolation vs evaluation
[ ] Use a harmless RCE proof
[ ] Restore modified state
[ ] Rotate/consume test credentials
[ ] Document exact attack chain[ ] Identify framework and version
[ ] Identify public content types
[ ] Enumerate filter operators
[ ] Enumerate relationships
[ ] Test private relationships
[ ] Test private fields
[ ] Test comparison operators
[ ] Look for boolean oracles
[ ] Identify security-sensitive fields
[ ] Test reset-token behavior
[ ] Test token invalidation
[ ] Map authenticated privileges
[ ] Enumerate administrator functionality
[ ] Identify template engines
[ ] Test interpolation vs evaluation
[ ] Use a harmless RCE proof
[ ] Restore modified state
[ ] Rotate/consume test credentials
[ ] Document exact attack chain34. The Bigger Security Lesson
The most interesting part of this vulnerability is that no single step initially looked like a guaranteed full compromise.
It was the chain that mattered.
Public API
↓
Unexpected relational capability
↓
Private-field oracle
↓
Secret recovery
↓
Authentication bypass
↓
Privilege escalation
↓
Dangerous administrative functionality
↓
Server-side executionPublic API
↓
Unexpected relational capability
↓
Private-field oracle
↓
Secret recovery
↓
Authentication bypass
↓
Privilege escalation
↓
Dangerous administrative functionality
↓
Server-side executionThis is why bug bounty hunters should avoid thinking only in terms of vulnerability categories.
Don't ask only:
"Is this an IDOR?"
or:
"Is this information disclosure?"
Instead ask:
"What can I do with this capability?"
Then:
"What new capability does that give me?"
And repeat.
35. Final Takeaway
The biggest lesson from this research is simple:
A low-level authorization mistake can become a critical vulnerability when it exposes a credential that crosses an authentication boundary.
The public endpoint didn't initially expose an administrator password.
It exposed something more subtle:
the ability to ask questions about a private administrator field.the ability to ask questions about a private administrator field.That was enough.
The oracle revealed the reset token.
The reset token produced administrator access.
Administrator access exposed a server-side template execution primitive.
And that primitive provided confirmed code execution inside the application process.
The complete chain was:
Unauthenticated
↓
Relational-filter authorization bypass
↓
Private admin-field oracle
↓
Reset-token recovery
↓
Super-admin takeover
↓
Editable template
↓
Server-side JavaScript execution
↓
Filesystem accessUnauthenticated
↓
Relational-filter authorization bypass
↓
Private admin-field oracle
↓
Reset-token recovery
↓
Super-admin takeover
↓
Editable template
↓
Server-side JavaScript execution
↓
Filesystem accessThat is the mindset I try to apply during bug bounty research:
Don't stop when you find a vulnerability. Find out what that vulnerability enables.
Final Result
The report was accepted as an incident, the severity was ultimately assessed as critical, and the organization chose immediate remediation and decommissioning of the affected product.