Skip to content

Tesseract.js OCR Missing File Type Validation - #915

Closed
Kirtan-pc wants to merge 1 commit into
knoxiboy:mainfrom
Kirtan-pc:filetype-validation
Closed

Tesseract.js OCR Missing File Type Validation#915
Kirtan-pc wants to merge 1 commit into
knoxiboy:mainfrom
Kirtan-pc:filetype-validation

Conversation

@Kirtan-pc

@Kirtan-pc Kirtan-pc commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

User description

Description

Add server-side magic byte verification to the image upload validation in the AI chat endpoint. Previously, only the client-supplied Content-Type / data URI prefix was checked, which can be trivially spoofed. Now the actual decoded file bytes are compared against known image signatures using the file-type package.

Related Issue

Closes #873

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Documentation update (README, guides, comments)
  • Style / UI change (no logic change)
  • Code refactor (no behavior change)
  • Test addition or update
  • Breaking change (fix or feature that would cause existing functionality to change)

Problem

The validateAiImageDataUrl function in src/lib/ai/ai-image-validation.ts only validated the client-supplied data URI prefix:

const validMime = /^data:image\/(png|jpe?g|webp);base64,/.test(img);

A malicious client could send:

data:image/png;base64,<crafted TIFF/WebP/binary payload>

This spoofed data URI would pass validation, and the payload would be forwarded to Groq's vision API. While the primary risk here is resource waste and potential parser crashes rather than code execution, the lack of content verification violates defense-in-depth principles.

Fix

1. Magic byte verification (src/lib/ai/ai-image-validation.ts)

  • Added validateMagicBytes() function that decodes the base64 payload and runs fileTypeFromBuffer() from the file-type package
  • file-type reads the file's magic bytes (first 2-8 bytes) to determine the actual format:
    • PNG: 89 50 4E 47 0D 0A 1A 0A
    • JPEG: FF D8 FF
    • WebP: 52 49 46 46 xx xx xx xx 57 45 42 50 (RIFF....WEBP)
  • Returns 422 IMAGE_MIME_MISMATCH if the declared MIME doesn't match the detected format
  • Returns 422 INVALID_IMAGE_PAYLOAD if the bytes don't match any known format

2. validateAiImageDataUrl is now async

The function signature changed from:

export function validateAiImageDataUrl(imageBase64: unknown): AiImageValidationResult

to:

export async function validateAiImageDataUrl(imageBase64: unknown): Promise<AiImageValidationResult>

This is necessary because fileTypeFromBuffer returns a Promise.

3. Updated caller (src/app/api/ask-ai/route.ts)

The ask-ai route's inline regex check was replaced with a call to the shared validateAiImageDataUrl() function, so all validation (format, MIME, size, magic bytes) happens in one place.

Before (ask-ai route — inline regex only)

if (body.imageBase64 !== undefined) {
    const img = body.imageBase64 as string;
    const validMime = /^data:image\/(png|jpe?g|webp);base64,/.test(img);
    if (!validMime) {
        return NextResponse.json({ error: "..." }, { status: 422 });
    }
}

After (ask-ai route — full validation)

if (body.imageBase64 !== undefined) {
    const result = await validateAiImageDataUrl(body.imageBase64);
    if (!result.ok) {
        return NextResponse.json(
            { error: result.error, code: result.code },
            { status: result.status }
        );
    }
}

Files Changed

File Change
src/lib/ai/ai-image-validation.ts Added validateMagicBytes() using file-type package; validateAiImageDataUrl is now async
src/app/api/ask-ai/route.ts Replaced inline regex validation with validateAiImageDataUrl() call
package.json Added file-type dependency

How Has This Been Tested?

  • Tested locally with npm run dev
  • Verified TypeScript compilation (npx tsc --noEmit passes)
  • Verified on mobile viewport (375px)
  • Verified on desktop viewport (1440px)

Checklist

  • I have tested my changes locally (npx tsc --noEmit)
  • My code follows the existing code style (TypeScript, no any types)
  • I have not introduced unrelated changes (each PR should address one issue)
  • I have added comments where necessary
  • My branch is up to date with main
  • I have linked the related issue above
  • Screenshots are included (if this is a UI change)

CodeAnt-AI Description

Reject spoofed image uploads in AI chat

What Changed

  • Image uploads are now checked against their actual file contents, not just the file name or declared image type
  • Uploads with mismatched or unrecognizable image data now fail with a clear error instead of being forwarded
  • The AI chat endpoint now returns the specific validation error and status for invalid images

Impact

✅ Fewer rejected AI image requests later in the flow
✅ Clearer image upload errors
✅ Less chance of malformed files reaching vision requests

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@vercel

vercel Bot commented Jul 13, 2026

Copy link
Copy Markdown

@Kirtan-pc is attempting to deploy a commit to the Karan Mani Tripathi 's projects Team on Vercel.

A member of the Team first needs to authorize it.

@codeant-ai

codeant-ai Bot commented Jul 13, 2026

Copy link
Copy Markdown

CodeAnt AI is reviewing your PR.

@codeant-ai

codeant-ai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@Kirtan-pc, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 19 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ddf7d19a-9053-4b1e-b25c-39589a6b01dd

📥 Commits

Reviewing files that changed from the base of the PR and between 6f882a2 and 2250eec.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • package.json
  • src/app/api/ask-ai/route.ts
  • src/lib/ai/ai-image-validation.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added gssoc'26 GSSoC program issue level:critical Critical level task type:bug Bug fix type:docs Documentation update review-needed labels Jul 13, 2026
@github-actions
github-actions Bot requested a review from knoxiboy July 13, 2026 11:53
@codeant-ai codeant-ai Bot added the size:L label Jul 13, 2026
@codeant-ai

codeant-ai Bot commented Jul 13, 2026

Copy link
Copy Markdown

CodeAnt AI finished reviewing your PR.

@knoxiboy

Copy link
Copy Markdown
Owner

Closing because this issue is already implemented by PR #778

@knoxiboy knoxiboy closed this Jul 15, 2026
@knoxiboy knoxiboy added the already-implemented This has already been implemented by another PR/commit label Jul 15, 2026
@github-actions github-actions Bot removed gssoc'26 GSSoC program issue level:critical Critical level task type:bug Bug fix type:docs Documentation update size/l review-needed labels Jul 15, 2026
@github-actions

Copy link
Copy Markdown

This pull request has been closed because the requested features or bug fixes are already implemented in the repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

already-implemented This has already been implemented by another PR/commit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Tesseract.js OCR Missing File Type Validation

2 participants