Skip to content

Add request validation with Zod for all route parameters and bodies #12

Description

@prodbycorne

Overview

Incoming route parameters and query strings are currently passed directly to the oracle and cache layers without validation. Invalid inputs cause uncaught errors or unexpected behaviour rather than clear 400 responses.

Problems Found

  • GET /api/v1/prices/:assetCode — no validation on assetCode (could be empty string, 200-char garbage, or SQL/XSS payload)
  • ?issuer= query param not validated as a valid Stellar G-address
  • Future POST bodies for webhooks/airdrops need schema validation

Solution

Add Zod for schema validation with a thin Express middleware wrapper:

npm install zod

Schemas to define

// src/validation/schemas.js
const assetCodeSchema = z.string().min(1).max(12).regex(/^[A-Z0-9]+$/);
const issuerSchema = z.string().regex(/^G[A-Z2-7]{55}$/).optional();
const paginationSchema = z.object({
  page: z.coerce.number().int().min(1).default(1),
  limit: z.coerce.number().int().min(1).max(100).default(20),
});

Validation middleware

// src/middleware/validate.js
function validate(schema, source = 'body') {
  return (req, res, next) => {
    const result = schema.safeParse(req[source]);
    if (!result.success) {
      return res.status(400).json({
        error: 'Validation failed',
        details: result.error.flatten().fieldErrors,
      });
    }
    req.validated = result.data;
    next();
  };
}

Acceptance Criteria

  • Zod installed and schema file created
  • validate middleware created and exported
  • assetCode validated: 1–12 uppercase alphanumeric chars
  • issuer validated as valid Stellar public key format when present
  • Invalid requests return 400 with { error, details }
  • No validation errors propagate to the 500 handler
  • Tests for valid and invalid inputs on each route

Metadata

Metadata

Assignees

No one assigned

    Labels

    GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official CampaignapiREST API design and endpointssecuritySecurity hardening and vulnerability fixes

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions