mirror of
https://github.com/direct-img/direct-img.link.git
synced 2026-10-19 10:54:50 +00:00
Fix: Serve bad.webp for unknown query params
Scanner probes like /userfiles?path=../../.env were treated as real searches since extra params were ignored, wasting searches and rate limit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -81,7 +81,7 @@ Literal slashes (`/`) and dots (`.`) in the URL path are **rejected** to prevent
|
|||||||
|
|
||||||
### Things to know
|
### Things to know
|
||||||
|
|
||||||
- **Query parameters (`?...`)** other than `i` (and `src` on [free.direct-img.link](#free-images)) are ignored — `/orange+cat?size=large` → `orange cat`
|
- **Query parameters (`?...`)** other than `i` (and `src` on [free.direct-img.link](#free-images)) serve `bad.webp` — `/orange+cat?size=large` ❌
|
||||||
- **Fragments (`#...`)** are never sent to the server by browsers
|
- **Fragments (`#...`)** are never sent to the server by browsers
|
||||||
- **Double-encoded values** are decoded once — `%2520` becomes `%20` (literal), not a space
|
- **Double-encoded values** are decoded once — `%2520` becomes `%20` (literal), not a space
|
||||||
- Two queries that normalize to the same string share the same cached image
|
- Two queries that normalize to the same string share the same cached image
|
||||||
|
|||||||
@@ -26,11 +26,13 @@ export async function onRequest(context) {
|
|||||||
if (!query) return jsonResponse(400, { error: "Empty query" });
|
if (!query) return jsonResponse(400, { error: "Empty query" });
|
||||||
if (query.length > 200) return jsonResponse(400, { error: "Query too long (max 200 characters)" });
|
if (query.length > 200) return jsonResponse(400, { error: "Query too long (max 200 characters)" });
|
||||||
|
|
||||||
// ?i= picks which result to serve; free.direct-img.link also takes ?src= and serves only unrestricted images
|
// ?i= picks which result to serve; free.direct-img.link also takes ?src= and serves only unrestricted images.
|
||||||
|
// Any other param (e.g. scanner probes like ?path=../../.env) is rejected before it can cost a search.
|
||||||
const free = url.hostname.startsWith("free.");
|
const free = url.hostname.startsWith("free.");
|
||||||
const i = parseIndex(url.searchParams);
|
const i = parseIndex(url.searchParams);
|
||||||
const src = free ? parseFreeSource(url.searchParams) : null;
|
const src = free ? parseFreeSource(url.searchParams) : null;
|
||||||
if (!i || (free && !src)) return asset("bad.webp");
|
const extra = [...url.searchParams.keys()].some(k => k !== "i" && !(free && k === "src"));
|
||||||
|
if (!i || (free && !src) || extra) return asset("bad.webp");
|
||||||
|
|
||||||
context.waitUntil(countHit(env, request, query, free));
|
context.waitUntil(countHit(env, request, query, free));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user