DEV Community

Naim Katiman
Naim Katiman

Posted on

Hardening an Express API: URL Validation, Error Handling, and Tests in One Session

I'm building repo-skill-advisor, a precision skill recommendation engine for GitHub repositories. Today I hardened the HTTP layer by closing three security and reliability gaps.

The Problem

The Express server accepted arbitrary URLs with no validation. Any string -- SSRF payloads, non-GitHub URLs, or empty strings -- was passed directly to the scanning engine. Error handling was inline with raw error messages leaking to clients.

What I Built

1. URL Validation Middleware

function validateGitHubUrl(urlStr) {
  if (!urlStr || typeof urlStr !== 'string') return null;
  try {
    const u = new URL(urlStr);
    if (u.protocol !== 'https:' && u.protocol !== 'http:') return null;
    if (u.hostname !== 'github.com') return null;
    const parts = u.pathname.split('/').filter(Boolean);
    if (parts.length < 2) return null;
    return { owner: parts[0], repo: parts[1].replace(/\.git$/, '') };
  } catch { return null; }
}
Enter fullscreen mode Exit fullscreen mode

Applied as Express middleware to both POST routes so invalid URLs get rejected before reaching the scanner.

2. Centralized Error Handler

Routes now call next(err) and a single error handler catches everything -- no stack traces leak to clients.

3. require.main Guards

Both server.js and analyze.js now wrap CLI-only logic in require.main === module checks, so they can be safely imported for testing without side effects.

Results

  • Tests: 39/39 passing (up from 33)
  • New tests: 6 validation tests covering valid URLs, non-GitHub URLs, missing repos, empty input, and protocol checks
  • Security: Zero SSRF vectors, no information leakage

Key Takeaway

Yesterday's automated analysis identified these exact gaps. Today I closed all three. Building systematic gap analysis into your workflow means you always know what to fix next.

Check it out: repo-skill-advisor on GitHub

Top comments (0)