Case Study Financial Services ·Singapore · July 20, 2025

API Penetration Testing for a Fintech Startup Pre-Launch

A payments fintech startup required a comprehensive API security assessment before their PCI DSS Level 1 certification. CyberneticsPlus identified 8 critical and high findings including a JWT algorithm confusion vulnerability that allowed complete authentication bypass.

8

Critical/High Findings

100%

Fixed Pre-Launch

PCI DSS

Certification Achieved

API Penetration TestingPCI DSS SupportJWT Security Assessment

Background

A Singapore-based payments fintech preparing to launch a card-not-present payment processing API engaged CyberneticsPlus for a pre-launch security assessment. The company was targeting PCI DSS Level 1 certification — required for processing more than 6 million transactions annually — and their QSA (Qualified Security Assessor) had mandated a penetration test before the certification audit.

API scope:

  • Payment initiation API (REST, OAuth2 authentication)
  • Merchant management API (CRUD for merchant accounts and configurations)
  • Webhook delivery system (for payment status notifications)
  • Admin API (internal operations team access)

The platform was built on Node.js (Express), with PostgreSQL and Redis, deployed on AWS (EKS).

Assessment Approach

Type: Grey-box — provided with API documentation, test merchant credentials, and one standard API consumer account. Admin API was tested with a read-only admin credential.

Primary focus: OWASP API Security Top 10, PCI DSS API requirements (12.3.2), authentication and authorisation.

Critical Findings

Critical: JWT Algorithm Confusion Attack — Authentication Bypass

Finding: The payment API accepted JWTs signed with either RS256 (RSA) or HS256 (HMAC). The verification logic:

const decoded = jwt.verify(token, publicKey);  // Uses RS256

However, when an HS256 JWT was presented, the library interpreted publicKey as the HMAC secret. Since the public key is, by definition, public (available from the JWKS endpoint at /api/.well-known/jwks.json), an attacker could:

  1. Obtain the server’s RSA public key from the JWKS endpoint
  2. Sign a forged JWT with HS256, using the RSA public key as the HMAC secret
  3. Include any desired claims (merchant ID, elevated permissions)
  4. The server verifies the HS256 signature using the public key → verification succeeds
  5. Attacker has forged credentials for any merchant account

Proof of concept: CyberneticsPlus forged a JWT claiming to be merchant_id: 1 (the test environment’s highest-revenue merchant) and successfully accessed their payment history, configuration, and initiated a $1.00 test transaction.

Fix: Algorithm explicitly pinned to RS256 in the JWT verification configuration. HS256 requests rejected at middleware level.

Critical: Webhook Signature Not Validated

Finding: The webhook delivery system sent payment notifications to merchant-configured URLs. The receiving merchant’s API was expected to validate the request signature (HMAC-SHA256 using a per-merchant webhook secret). However, the platform’s internal API — used by the merchant team to manually trigger webhook re-deliveries — did not include the webhook signature header.

Impact: Any internal user with access to the re-delivery endpoint could trigger webhook deliveries to merchant URLs without a valid signature. Merchants relying on signature validation to confirm webhooks were from the platform would receive forged notifications.

In a payment context: an attacker who could access the re-delivery endpoint could trigger false “payment_completed” webhook deliveries to merchant systems, potentially triggering product fulfillment without actual payment.

Fix: Webhook signature applied consistently to all delivery paths, including re-deliveries.

High Findings

Excessive Data in API Responses (OWASP API3)

Finding: The /api/v1/merchants/{merchant_id} endpoint returned the full merchant object, including:

  • internal_risk_score — the platform’s fraud risk assessment
  • kyc_verification_status and kyc_rejection_reason
  • support_notes — internal notes added by the operations team
  • fee_discount_percentage — custom fee negotiated by the merchant (business-sensitive)

None of these fields were documented in the merchant API and all were intended for internal use only.

Fix: Response serialiser updated to explicit allowlist of fields returned to merchant API consumers.

BOLA on Payment Records

Finding: GET /api/v1/payments/{payment_id} returned payment details without verifying the requesting merchant owned the payment. Payment IDs were UUIDs (non-guessable), but the endpoint was vulnerable once a payment ID was known.

In a real attack scenario: a compromised merchant account could access payment data of other merchants if they obtained payment IDs (potentially via the platform’s reporting/export features).

Fix: Ownership check added — every payment query filtered by merchant_id derived from the authenticated JWT claim.

Medium Findings (4 Identified)

  • Rate limiting on OAuth2 token endpoint (100 requests/minute — too high; reduced to 10)
  • Admin API accessible without IP allowlisting (restricted to office IP range)
  • API documentation exposed in production without authentication (Swagger UI at /api/docs)
  • Sensitive data in CloudWatch logs (partial card numbers appearing in debug log output)

Remediation Timeline

CyberneticsPlus delivered the report 5 days after assessment completion. The client’s engineering team worked against the following remediation schedule (agreed with QSA):

FindingSeverityFixed Within
JWT algorithm confusionCritical24 hours
Webhook signature gapCritical48 hours
Excessive data exposureHigh5 days
BOLA on paymentsHigh5 days
Rate limitingMedium7 days
Admin API IP restrictionMedium2 days
Swagger UI access controlMedium3 days
Log redactionMedium7 days

All findings remediated within 2 weeks. CyberneticsPlus conducted a full retest — all critical and high findings confirmed resolved.

PCI DSS Outcome

The QSA reviewed the penetration test report and retest evidence as part of the PCI DSS Level 1 assessment:

  • Requirement 11.3.1 (external penetration testing): satisfied
  • Requirement 11.3.2 (internal penetration testing): satisfied by the API assessment scope
  • Requirement 6.4.1 (web-facing application security): pentest findings and remediation accepted as evidence

PCI DSS Level 1 certification achieved. The company launched to their first enterprise merchants 8 weeks after the assessment.

The fintech now conducts semi-annual API security assessments — increased frequency (vs. standard annual) due to the high-risk nature of payment processing and the pace of API development.

A

Anonymous

Financial Services · Singapore

Want similar results for your business?

Book a free consultation and we'll assess your current security posture.

Book a Free Consultation