felladrin / felladrin/MiniSearch

security: audit thumbnail endpoint SSRF protection

Open
#2,524 0 comments 0 reactions 0 assignees View on GitHub
security
Dominant language
TypeScript
Stars
587
Forks
70
Avg merge
1h 3m
Merged PRs (30d)
175

Description

## Problem

The `/thumbnail` endpoint (`server/thumbnailEndpointServerHook.ts`) fetches external URLs to lazy-load image thumbnails. While it uses `server/utils/publicUrl.ts` to block private and reserved addresses, this is an active attack surface that warrants a dedicated security audit.

## Why It Matters

- **SSRF risk**: If the URL validation has gaps, an attacker could use the server to scan internal networks
- **Active attack surface**: The endpoint fetches arbitrary URLs from search results, which could be malicious
- **Rate limiting**: The endpoint should be rate-limited to prevent abuse
- **Content validation**: The endpoint should verify the fetched content is actually an image

## Current Implementation

```typescript
// server/thumbnailEndpointServerHook.ts (simplified)
const url = new URL(req.url);
const targetUrl = url.searchParams.get('url');

// Validate URL
if (!publicUrl.isPublicUrl(targetUrl)) {
return res.status(400).end('Invalid URL');
}

// Fetch thumbnail
const response = await fetch(targetUrl, { /* options */ });
```

## Audit Checklist

1. **URL validation**
- [ ] Does `publicUrl.ts` block all private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)?
- [ ] Does it block link-local addresses (169.254.0.0/16)?
- [ ] Does it block the loopback range (127.0.0.0/8, ::1)?
- [ ] Does it block the cloud metadata endpoint (169.254.169.254)?
- [ ] Does it block IPv6-mapped IPv4 addresses?
- [ ] Does it block DNS rebinding attacks (validate after DNS resolution)?

2. **Request validation**
- [ ] Is the URL length limited?
- [ ] Are only HTTP/HTTPS schemes allowed?
- [ ] Are redirects followed safely (no redirect to private IP)?

3. **Response validation**
- [ ] Is the Content-Type checked to ensure it's an image?
- [ ] Is the response size limited?
- [ ] Is the timeout configured?

4. **Rate limiting**
- [ ] Is the endpoint rate-limited per IP?
- [ ] Is there a global rate limit?

## Proposed Improvements

1. **Add DNS rebinding protection**: Resolve the DNS name and validate the IP before fetching
2. **Add redirect validation**: Follow redirects but re-validate each URL
3. **Add Content-Type validation**: Only accept image/* Content-Types
4. **Add response size limit**: Reject responses larger than a reasonable size (e.g., 5MB)
5. **Add detailed logging**: Log all thumbnail requests for audit purposes

## Files to Audit

- `server/thumbnailEndpointServerHook.ts`
- `server/utils/publicUrl.ts`

## Acceptance Criteria

- All items in the audit checklist are verified or fixed
- DNS rebinding attacks are prevented
- Redirects are validated
- Content-Type and size are validated
- Rate limiting is in place
- A security review comment is added to the endpoint code

Contributor guide

Open the contributing guide

Research direction

Read server/thumbnailEndpointServerHook.ts and server/utils/publicUrl.ts first, then trace the thumbnail request, URL validation, fetch, redirects, and response handling against the audit checklist. Done means every checklist item is verified or fixed, the stated protections are covered, rate limiting is addressed, and a security review comment is added to the endpoint code.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.