Skip to content

Commit 0ce9556

Browse files
geroplroboquat
authored andcommitted
[server] Fix extraction of clientIp
1 parent a5a91d7 commit 0ce9556

File tree

3 files changed

+22
-6
lines changed

3 files changed

+22
-6
lines changed

components/server/src/analytics.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { Request } from "express";
88
import { IAnalyticsWriter } from "@gitpod/gitpod-protocol/lib/analytics";
99
import { SubscriptionService } from "@gitpod/gitpod-payment-endpoint/lib/accounting";
1010
import * as crypto from "crypto";
11+
import { clientIp } from "./express-util";
1112

1213
export async function trackLogin(
1314
user: User,
@@ -18,7 +19,7 @@ export async function trackLogin(
1819
) {
1920
// make new complete identify call for each login
2021
await fullIdentify(user, request, analytics, subscriptionService);
21-
const ip = request.ips[0];
22+
const ip = clientIp(request);
2223
const ua = request.headers["user-agent"];
2324

2425
// track the login
@@ -35,7 +36,7 @@ export async function trackLogin(
3536
export async function trackSignup(user: User, request: Request, analytics: IAnalyticsWriter) {
3637
// make new complete identify call for each signup
3738
await fullIdentify(user, request, analytics);
38-
const ip = request.ips[0];
39+
const ip = clientIp(request);
3940
const ua = request.headers["user-agent"];
4041

4142
// track the signup
@@ -79,7 +80,7 @@ async function fullIdentify(
7980
) {
8081
// makes a full identify call for authenticated users
8182
const coords = request.get("x-glb-client-city-lat-long")?.split(", ");
82-
const ip = request.ips[0];
83+
const ip = clientIp(request);
8384
const ua = request.headers["user-agent"];
8485
var subscriptionIDs: string[] = [];
8586
const subscriptions = await subscriptionService?.getNotYetCancelledSubscriptions(user, new Date().toISOString());

components/server/src/express-util.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export function destroySession(session: session.Session): Promise<void> {
9292
* @returns fingerprint which is a hash over (potential) client ip (or just proxy ip) and User Agent
9393
*/
9494
export function getRequestingClientInfo(req: express.Request) {
95-
const ip = req.ips[0] || req.ip; // on PROD this should be a client IP address
95+
const ip = clientIp(req);
9696
const ua = req.get("user-agent");
9797
const fingerprint = crypto.createHash("sha256").update(`${ip}${ua}`).digest("hex");
9898
return { ua, fingerprint };
@@ -170,3 +170,13 @@ export const takeFirst = (h: string | string[] | undefined): string | undefined
170170
}
171171
return h;
172172
};
173+
174+
export function clientIp(req: express.Request): string | undefined {
175+
const forwardedFor = takeFirst(req.headers["x-forwarded-for"]);
176+
if (!forwardedFor) {
177+
return undefined;
178+
}
179+
180+
// We now have a ,-separated string of IPs, where the first one is the (closest to) client IP
181+
return forwardedFor.split(",")[0];
182+
}

components/server/src/websocket/websocket-connection-manager.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import {
3535
WithResourceAccessGuard,
3636
RepositoryResourceGuard,
3737
} from "../auth/resource-access";
38-
import { takeFirst } from "../express-util";
38+
import { clientIp, takeFirst } from "../express-util";
3939
import {
4040
increaseApiCallCounter,
4141
increaseApiConnectionClosedCounter,
@@ -47,6 +47,7 @@ import { GitpodServerImpl } from "../workspace/gitpod-server-impl";
4747
import * as opentracing from "opentracing";
4848
import { TraceContext } from "@gitpod/gitpod-protocol/lib/util/tracing";
4949
import { GitpodHostUrl } from "@gitpod/gitpod-protocol/lib/util/gitpod-host-url";
50+
import { maskIp } from "../analytics";
5051

5152
export type GitpodServiceFactory = () => GitpodServerImpl;
5253

@@ -237,11 +238,15 @@ export class WebsocketConnectionManager implements ConnectionHandler {
237238
}
238239

239240
const clientHeaderFields: ClientHeaderFields = {
240-
ip: takeFirst(expressReq.ips),
241+
ip: clientIp(expressReq),
241242
userAgent: expressReq.headers["user-agent"],
242243
dnt: takeFirst(expressReq.headers.dnt),
243244
clientRegion: takeFirst(expressReq.headers["x-glb-client-region"]),
244245
};
246+
// TODO(gpl): remove once we validated the current approach works
247+
log.debug("masked wss client IP", {
248+
maskedClientIp: maskIp(clientHeaderFields.ip),
249+
});
245250

246251
gitpodServer.initialize(
247252
client,

0 commit comments

Comments
 (0)