Skip to content
This repository was archived by the owner on Feb 4, 2025. It is now read-only.

Commit f938e62

Browse files
authored
Merge pull request #466 from redpwn/feat/proxy-trust-config
feat(server): add config option for proxy trust
2 parents 610e2c0 + 08b2a0c commit f938e62

File tree

4 files changed

+29
-4
lines changed

4 files changed

+29
-4
lines changed

docs/content/configuration.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ Configuration for advanced users - sane defaults are automatically set by the in
7373
YAML/JSON name|environment name|required|default value|type|description
7474
-|-|-|-|-|-
7575
`tokenKey`|`RCTF_TOKEN_KEY`|yes|_(none)_|string|base64 encoded 32 byte key used for encrypting tokens
76+
`proxy.cloudflare`|_(none)_|yes|`false`|boolean|whether or not rCTF is behind Cloudflare; if `true`, do not use `proxy.trust`
77+
`proxy.trust`|_(none)_|yes|`false`|boolean, string, string array, or integer|X-Forwarded-For trust: the trust parameter to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
7678
`loginTimeout`|`RCTF_LOGIN_TIMEOUT`|yes|3600000|integer|lifetime of registration, email update, and recovery links, in milliseconds
7779
`userMembers`|`RCTF_USER_MEMBERS`|yes|`true`|boolean|whether to allow a user to provide emails for individual members
7880
`database.migrate`|`RCTF_DATABASE_MIGRATE`|yes|`never`|`before | only | never`|how to run postgreSQL migrations. [documentation](management/migration.md)

server/app.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ import fastify from 'fastify'
33
import fastifyStatic from 'fastify-static'
44
import helmet from 'fastify-helmet'
55
import hyperid from 'hyperid'
6+
import config from './config/server'
67
import { serveIndex, getRealIp } from './util'
78
import { init as uploadProviderInit } from './uploads'
89
import api, { logSerializers as apiLogSerializers } from './api'
910

1011
const app = fastify({
12+
trustProxy: config.proxy.trust,
1113
logger: {
1214
level: process.env.NODE_ENV === 'production' ? 'info' : 'debug',
1315
serializers: {

server/config/server.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ export type ServerConfig = {
3939
tokenKey: string;
4040
origin: string;
4141

42+
// TODO: enforce `trust` is false when `cloudflare` is true
43+
proxy: {
44+
cloudflare: boolean
45+
trust: boolean | string | string[] | number
46+
}
47+
4248
ctftime?: {
4349
clientId: string;
4450
clientSecret: string;
@@ -166,6 +172,10 @@ const defaultConfig: PartialDeep<ServerConfig> = {
166172
uploadProvider: {
167173
name: 'uploads/local'
168174
},
175+
proxy: {
176+
cloudflare: false,
177+
trust: false
178+
},
169179
meta: {
170180
description: '',
171181
imageUrl: ''

server/util/index.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import config from '../config/server'
12
import clientConfig from '../config/client'
23
import { promises as fs } from 'fs'
34
import mustache from 'mustache'
@@ -39,9 +40,19 @@ export const serveIndex: FastifyPluginAsync<{ indexPath: string; }> = async (fas
3940
fastify.setNotFoundHandler(routeHandler)
4041
}
4142

43+
const getFastifyIp = (req: FastifyRequest): string =>
44+
// Use `get` on req.__proto__ since this function is used in req's getter
45+
Reflect.get(Object.getPrototypeOf(req), 'ip', req) as typeof req.ip
46+
4247
// Parse Cloudflare CF-Connecting-IP header
43-
export const getRealIp = (req: FastifyRequest): string => {
44-
// Use `get` on req.__proto__ since getRealIp is used in req's getter
45-
return req.headers['cf-connecting-ip'] as string ||
46-
Reflect.get(Object.getPrototypeOf(req), 'ip', req) as string
48+
const getCloudflareIp = (req: FastifyRequest): string | undefined =>
49+
req.headers['cf-connecting-ip'] as string | undefined
50+
51+
let getRealIp: (req: FastifyRequest) => string = getFastifyIp
52+
53+
if (config.proxy.cloudflare) {
54+
getRealIp = (req: FastifyRequest): string =>
55+
getCloudflareIp(req) || getFastifyIp(req)
4756
}
57+
58+
export { getRealIp }

0 commit comments

Comments
 (0)