Skip to content

Commit

Permalink
feat(wip): sign media proxy url
Browse files Browse the repository at this point in the history
  • Loading branch information
Candinya committed Jul 11, 2024
1 parent 5e21cd5 commit 146adfb
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export type DownloadConfig = {
httpAgent: http.Agent,
httpsAgent: https.Agent,
proxy?: boolean;
signatureKey?: string;
}

export const defaultDownloadConfig = {
Expand Down
9 changes: 9 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { StatusError } from './status-error.js';
import { DownloadConfig, defaultDownloadConfig, downloadUrl } from './download.js';
import { getAgents } from './http.js';
import _contentDisposition from 'content-disposition';
import { verifySignedProxyURL } from "@/sign-proxy-url.js";

const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename);
Expand All @@ -28,6 +29,7 @@ export type MediaProxyOptions = {
userAgent?: string;
allowedPrivateNetworks?: string[];
maxSize?: number;
signatureKey?: string;
} & ({
proxy?: string;
} | {
Expand All @@ -54,6 +56,7 @@ export function setMediaProxyConfig(setting?: MediaProxyOptions | null) {
userAgent: setting.userAgent ?? defaultDownloadConfig.userAgent,
allowedPrivateNetworks: setting.allowedPrivateNetworks ?? defaultDownloadConfig.allowedPrivateNetworks,
maxSize: setting.maxSize ?? defaultDownloadConfig.maxSize,
signatureKey: setting.signatureKey ?? undefined,
...('proxy' in setting ?
{ ...getAgents(setting.proxy), proxy: !!setting.proxy } :
'httpAgent' in setting ? {
Expand Down Expand Up @@ -124,6 +127,12 @@ async function proxyHandler(request: FastifyRequest<{ Params: { url: string; };
return;
}

// 检查签名是否符合
if (!!config.signatureKey && !verifySignedProxyURL(request.url, config.signatureKey)) {
reply.code(401);
return;
}

// Create temp file
const file = await downloadAndDetectTypeFromUrl(url);

Expand Down
49 changes: 49 additions & 0 deletions src/sign-proxy-url.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { createHmac, timingSafeEqual } from 'node:crypto';

export function verifySignedProxyURL(signedURLString: string, signatureKey: string): boolean {
const workingURL = new URL(signedURLString);

// 提取签名参数
const sig = workingURL.searchParams.get('sig');
if (sig === null) {
// 缺失签名
return false;
}

// 去掉签名参数
workingURL.searchParams.delete('sig');

// 提取过期时间
const exp = workingURL.searchParams.get('exp');
if (exp === null) {
// 缺失过期时间
return false;
}
// 检查是否已过期
const expEpochSec = parseInt(exp);
if (expEpochSec > Date.now() / 1000) {
// 无效的时间,或者已经超时
return false;
}

// 检查是否有 static 参数:因为前端可能会追加这个参数,为避免参数影响,要把它删除掉。
if (workingURL.searchParams.has('static')) {
workingURL.searchParams.delete('static');
}

// 排序查询字符串
workingURL.searchParams.sort();

// 生成正确的签名用来对照
const sigCorrect = createHmac('sha256', signatureKey).
update(workingURL.toString()).digest('hex');

// 检查签名是否匹配
if (!timingSafeEqual(Buffer.from(sigCorrect), Buffer.from(sig))) {
// 不匹配
return false;
}

// 验证通过
return true;
}

0 comments on commit 146adfb

Please sign in to comment.