Skip to content

Commit 2770527

Browse files
authored
Fix: Support cloudflare proxy IP (#702)
* temp: print debug headers * stringify * read cf header * Resolve Cloudflare IP * print trustproxy state * pr comments
1 parent 8992694 commit 2770527

File tree

3 files changed

+37
-18
lines changed

3 files changed

+37
-18
lines changed

src/scripts/apply-migrations.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const main = async () => {
2626

2727
logger({
2828
level: "info",
29-
message: "Completed migrations without errors.",
29+
message: "Completed migrations successfully.",
3030
service: "server",
3131
});
3232
} catch (e) {

src/server/index.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,23 @@ export const initServer = async () => {
5050
};
5151
}
5252

53+
// env.TRUST_PROXY is used to determine if the X-Forwarded-For header should be trusted.
54+
// This option is force enabled for cloud-hosted Engines.
55+
// See: https://fastify.dev/docs/latest/Reference/Server/#trustproxy
56+
const trustProxy = env.TRUST_PROXY || !!env.ENGINE_TIER;
57+
if (trustProxy) {
58+
logger({
59+
service: "server",
60+
level: "info",
61+
message: "Server is enabled with trustProxy.",
62+
});
63+
}
64+
5365
// Start the server with middleware.
5466
const server: FastifyInstance = fastify({
5567
connectionTimeout: SERVER_CONNECTION_TIMEOUT,
5668
disableRequestLogging: true,
57-
// env.TRUST_PROXY is used to determine if the X-Forwarded-For header should be trusted.
58-
// This option is force enabled for cloud-hosted Engines.
59-
// See: https://fastify.dev/docs/latest/Reference/Server/#trustproxy
60-
trustProxy: env.TRUST_PROXY || !!env.ENGINE_TIER,
69+
trustProxy,
6170
...(env.ENABLE_HTTPS ? httpsObject : {}),
6271
}).withTypeProvider<TypeBoxTypeProvider>();
6372

src/server/middleware/auth.ts

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -265,12 +265,12 @@ const handleWebsocketAuth = async (
265265
req.headers.authorization = `Bearer ${jwt}`;
266266
const user = await getUser(req);
267267

268-
const isIpInAllowlist = await checkIpInAllowlist(req);
269-
if (!isIpInAllowlist) {
268+
const { isAllowed, ip } = await checkIpInAllowlist(req);
269+
if (!isAllowed) {
270270
logger({
271271
service: "server",
272272
level: "error",
273-
message: `Unauthorized IP address: ${req.ip}`,
273+
message: `Unauthorized IP address: ${ip}`,
274274
});
275275
return {
276276
isAuthed: false,
@@ -339,12 +339,12 @@ const handleKeypairAuth = async (args: {
339339
throw error;
340340
}
341341

342-
const isIpInAllowlist = await checkIpInAllowlist(req);
343-
if (!isIpInAllowlist) {
342+
const { isAllowed, ip } = await checkIpInAllowlist(req);
343+
if (!isAllowed) {
344344
logger({
345345
service: "server",
346346
level: "error",
347-
message: `Unauthorized IP address: ${req.ip}`,
347+
message: `Unauthorized IP address: ${ip}`,
348348
});
349349
throw new Error(
350350
"Unauthorized IP address. See: https://portal.thirdweb.com/engine/features/security",
@@ -400,12 +400,12 @@ const handleAccessToken = async (
400400
return { isAuthed: false };
401401
}
402402

403-
const isIpInAllowlist = await checkIpInAllowlist(req);
404-
if (!isIpInAllowlist) {
403+
const { isAllowed, ip } = await checkIpInAllowlist(req);
404+
if (!isAllowed) {
405405
logger({
406406
service: "server",
407407
level: "error",
408-
message: `Unauthorized IP address: ${req.ip}`,
408+
message: `Unauthorized IP address: ${ip}`,
409409
});
410410
return {
411411
isAuthed: false,
@@ -523,12 +523,22 @@ const hashRequestBody = (req: FastifyRequest): string => {
523523
* @returns boolean
524524
* @async
525525
*/
526-
const checkIpInAllowlist = async (req: FastifyRequest) => {
527-
const config = await getConfig();
526+
const checkIpInAllowlist = async (
527+
req: FastifyRequest,
528+
): Promise<{ isAllowed: boolean; ip: string }> => {
529+
let ip = req.ip;
530+
const trustProxy = env.TRUST_PROXY || !!env.ENGINE_TIER;
531+
if (trustProxy && req.headers["cf-connecting-ip"]) {
532+
ip = req.headers["cf-connecting-ip"] as string;
533+
}
528534

535+
const config = await getConfig();
529536
if (config.ipAllowlist.length === 0) {
530-
return true;
537+
return { isAllowed: true, ip };
531538
}
532539

533-
return config.ipAllowlist.includes(req.ip);
540+
return {
541+
isAllowed: config.ipAllowlist.includes(ip),
542+
ip,
543+
};
534544
};

0 commit comments

Comments
 (0)