mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Add default rely on Cloudflare for IP addresses
This commit is contained in:
1657
backend/package-lock.json
generated
1657
backend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -31,15 +31,14 @@
|
||||
"libsodium-wrappers": "^0.7.10",
|
||||
"lodash": "^4.17.21",
|
||||
"mongoose": "^6.10.5",
|
||||
"node-cache": "^5.1.2",
|
||||
"nanoid": "^3.3.6",
|
||||
"node-cache": "^5.1.2",
|
||||
"nodemailer": "^6.8.0",
|
||||
"passport": "^0.6.0",
|
||||
"passport-google-oauth20": "^2.0.0",
|
||||
"posthog-node": "^2.6.0",
|
||||
"query-string": "^7.1.3",
|
||||
"rate-limit-mongo": "^2.3.2",
|
||||
"request-ip": "^3.3.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"stripe": "^10.7.0",
|
||||
"swagger-autogen": "^2.22.0",
|
||||
|
||||
@@ -126,13 +126,13 @@ export const login2 = async (req: Request, res: Response) => {
|
||||
|
||||
await checkUserDevice({
|
||||
user,
|
||||
ip: req.ip,
|
||||
ip: req.realIP,
|
||||
userAgent: req.headers['user-agent'] ?? ''
|
||||
});
|
||||
|
||||
const tokens = await issueAuthTokens({
|
||||
userId: user._id,
|
||||
ip: req.ip,
|
||||
ip: req.realIP,
|
||||
userAgent: req.headers['user-agent'] ?? ''
|
||||
});
|
||||
|
||||
@@ -153,7 +153,7 @@ export const login2 = async (req: Request, res: Response) => {
|
||||
userId: user._id,
|
||||
actions: [loginAction],
|
||||
channel: getChannelFromUserAgent(req.headers['user-agent']),
|
||||
ipAddress: req.ip
|
||||
ipAddress: req.realIP
|
||||
});
|
||||
|
||||
// return (access) token in response
|
||||
@@ -210,7 +210,7 @@ export const logout = async (req: Request, res: Response) => {
|
||||
userId: req.user._id,
|
||||
actions: [logoutAction],
|
||||
channel: getChannelFromUserAgent(req.headers['user-agent']),
|
||||
ipAddress: req.ip
|
||||
ipAddress: req.realIP
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
|
||||
@@ -130,7 +130,7 @@ export const pullSecrets = async (req: Request, res: Response) => {
|
||||
workspaceId,
|
||||
environment,
|
||||
channel: channel ? channel : 'cli',
|
||||
ipAddress: req.ip
|
||||
ipAddress: req.realIP
|
||||
});
|
||||
|
||||
key = await Key.findOne({
|
||||
@@ -199,7 +199,7 @@ export const pullSecretsServiceToken = async (req: Request, res: Response) => {
|
||||
workspaceId,
|
||||
environment,
|
||||
channel: 'cli',
|
||||
ipAddress: req.ip
|
||||
ipAddress: req.realIP
|
||||
});
|
||||
|
||||
key = {
|
||||
|
||||
@@ -151,14 +151,14 @@ export const login2 = async (req: Request, res: Response) => {
|
||||
|
||||
await checkUserDevice({
|
||||
user,
|
||||
ip: req.ip,
|
||||
ip: req.realIP,
|
||||
userAgent: req.headers['user-agent'] ?? ''
|
||||
});
|
||||
|
||||
// issue tokens
|
||||
const tokens = await issueAuthTokens({
|
||||
userId: user._id,
|
||||
ip: req.ip,
|
||||
ip: req.realIP,
|
||||
userAgent: req.headers['user-agent'] ?? ''
|
||||
});
|
||||
|
||||
@@ -215,7 +215,7 @@ export const login2 = async (req: Request, res: Response) => {
|
||||
userId: user._id,
|
||||
actions: [loginAction],
|
||||
channel: getChannelFromUserAgent(req.headers['user-agent']),
|
||||
ipAddress: req.ip
|
||||
ipAddress: req.realIP
|
||||
});
|
||||
|
||||
return res.status(200).send(response);
|
||||
@@ -296,14 +296,14 @@ export const verifyMfaToken = async (req: Request, res: Response) => {
|
||||
|
||||
await checkUserDevice({
|
||||
user,
|
||||
ip: req.ip,
|
||||
ip: req.realIP,
|
||||
userAgent: req.headers['user-agent'] ?? ''
|
||||
});
|
||||
|
||||
// issue tokens
|
||||
const tokens = await issueAuthTokens({
|
||||
userId: user._id,
|
||||
ip: req.ip,
|
||||
ip: req.realIP,
|
||||
userAgent: req.headers['user-agent'] ?? ''
|
||||
});
|
||||
|
||||
@@ -363,7 +363,7 @@ export const verifyMfaToken = async (req: Request, res: Response) => {
|
||||
userId: user._id,
|
||||
actions: [loginAction],
|
||||
channel: getChannelFromUserAgent(req.headers['user-agent']),
|
||||
ipAddress: req.ip
|
||||
ipAddress: req.realIP
|
||||
});
|
||||
|
||||
return res.status(200).send(resObj);
|
||||
|
||||
@@ -296,7 +296,7 @@ export const batchSecrets = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
actions,
|
||||
channel,
|
||||
ipAddress: req.ip,
|
||||
ipAddress: req.realIP,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -562,7 +562,7 @@ export const createSecrets = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
actions: [addAction],
|
||||
channel,
|
||||
ipAddress: req.ip,
|
||||
ipAddress: req.realIP,
|
||||
}));
|
||||
|
||||
// (EE) take a secret snapshot
|
||||
@@ -784,7 +784,7 @@ export const getSecrets = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(workspaceId as string),
|
||||
actions: [readAction],
|
||||
channel,
|
||||
ipAddress: req.ip,
|
||||
ipAddress: req.realIP,
|
||||
}));
|
||||
|
||||
const postHogClient = await TelemetryService.getPostHogClient();
|
||||
@@ -1019,7 +1019,7 @@ export const updateSecrets = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(key),
|
||||
actions: [updateAction],
|
||||
channel,
|
||||
ipAddress: req.ip,
|
||||
ipAddress: req.realIP,
|
||||
}));
|
||||
|
||||
// (EE) take a secret snapshot
|
||||
@@ -1157,7 +1157,7 @@ export const deleteSecrets = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(key),
|
||||
actions: [deleteAction],
|
||||
channel,
|
||||
ipAddress: req.ip,
|
||||
ipAddress: req.realIP,
|
||||
}));
|
||||
|
||||
// (EE) take a secret snapshot
|
||||
|
||||
@@ -117,7 +117,7 @@ export const completeAccountSignup = async (req: Request, res: Response) => {
|
||||
// issue tokens
|
||||
const tokens = await issueAuthTokens({
|
||||
userId: user._id,
|
||||
ip: req.ip,
|
||||
ip: req.realIP,
|
||||
userAgent: req.headers['user-agent'] ?? ''
|
||||
});
|
||||
|
||||
@@ -250,7 +250,7 @@ export const completeAccountInvite = async (req: Request, res: Response) => {
|
||||
// issue tokens
|
||||
const tokens = await issueAuthTokens({
|
||||
userId: user._id,
|
||||
ip: req.ip,
|
||||
ip: req.realIP,
|
||||
userAgent: req.headers['user-agent'] ?? ''
|
||||
});
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ export const pushWorkspaceSecrets = async (req: Request, res: Response) => {
|
||||
environment,
|
||||
secrets,
|
||||
channel: channel ? channel : 'cli',
|
||||
ipAddress: req.ip
|
||||
ipAddress: req.realIP
|
||||
});
|
||||
|
||||
await pushKeys({
|
||||
@@ -145,7 +145,7 @@ export const pullSecrets = async (req: Request, res: Response) => {
|
||||
workspaceId,
|
||||
environment,
|
||||
channel: channel ? channel : 'cli',
|
||||
ipAddress: req.ip
|
||||
ipAddress: req.realIP
|
||||
});
|
||||
|
||||
if (channel !== 'cli') {
|
||||
|
||||
@@ -179,14 +179,14 @@ export const login2 = async (req: Request, res: Response) => {
|
||||
|
||||
await checkUserDevice({
|
||||
user,
|
||||
ip: req.ip,
|
||||
ip: req.realIP,
|
||||
userAgent: req.headers['user-agent'] ?? ''
|
||||
});
|
||||
|
||||
// issue tokens
|
||||
const tokens = await issueAuthTokens({
|
||||
userId: user._id,
|
||||
ip: req.ip,
|
||||
ip: req.realIP,
|
||||
userAgent: req.headers['user-agent'] ?? ''
|
||||
});
|
||||
|
||||
@@ -243,7 +243,7 @@ export const login2 = async (req: Request, res: Response) => {
|
||||
userId: user._id,
|
||||
actions: [loginAction],
|
||||
channel: getChannelFromUserAgent(req.headers['user-agent']),
|
||||
ipAddress: req.ip
|
||||
ipAddress: req.realIP
|
||||
});
|
||||
|
||||
return res.status(200).send(response);
|
||||
|
||||
@@ -138,7 +138,7 @@ export const completeAccountSignup = async (req: Request, res: Response) => {
|
||||
// issue tokens
|
||||
const tokens = await issueAuthTokens({
|
||||
userId: user._id,
|
||||
ip: req.ip,
|
||||
ip: req.realIP,
|
||||
userAgent: req.headers['user-agent'] ?? ''
|
||||
});
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@ export const apiLimiter = rateLimit({
|
||||
legacyHeaders: false,
|
||||
skip: (request) => {
|
||||
return request.path === '/healthcheck' || request.path === '/api/status'
|
||||
},
|
||||
keyGenerator: (req, res) => {
|
||||
return req.realIP
|
||||
}
|
||||
});
|
||||
|
||||
@@ -29,7 +32,10 @@ const authLimit = rateLimit({
|
||||
windowMs: 1000 * 60 * 60,
|
||||
max: 50,
|
||||
standardHeaders: true,
|
||||
legacyHeaders: false
|
||||
legacyHeaders: false,
|
||||
keyGenerator: (req, res) => {
|
||||
return req.realIP
|
||||
}
|
||||
});
|
||||
|
||||
// 50 requests per 1 hour
|
||||
@@ -43,7 +49,10 @@ export const passwordLimiter = rateLimit({
|
||||
windowMs: 1000 * 60 * 60,
|
||||
max: 50,
|
||||
standardHeaders: true,
|
||||
legacyHeaders: false
|
||||
legacyHeaders: false,
|
||||
keyGenerator: (req, res) => {
|
||||
return req.realIP
|
||||
}
|
||||
});
|
||||
|
||||
export const authLimiter = (req: any, res: any, next: any) => {
|
||||
|
||||
@@ -11,7 +11,6 @@ import swaggerUi = require("swagger-ui-express");
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const swaggerFile = require("../spec.json");
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const requestIp = require("request-ip");
|
||||
import { apiLimiter } from "./helpers/rateLimiter";
|
||||
import {
|
||||
workspace as eeWorkspaceRouter,
|
||||
@@ -84,8 +83,6 @@ const main = async () => {
|
||||
})
|
||||
);
|
||||
|
||||
app.use(requestIp.mw());
|
||||
|
||||
if ((await getNodeEnv()) === "production") {
|
||||
// enable app-wide rate-limiting + helmet security
|
||||
// in production
|
||||
@@ -94,6 +91,13 @@ const main = async () => {
|
||||
app.use(helmet());
|
||||
}
|
||||
|
||||
app.use((req, res, next) => {
|
||||
// default to IP address provided by Cloudflare
|
||||
const cfIp = req.headers['cf-connecting-ip'];
|
||||
req.realIP = Array.isArray(cfIp) ? cfIp[0] : (cfIp as string) || req.ip;
|
||||
next();
|
||||
});
|
||||
|
||||
// (EE) routes
|
||||
app.use("/api/v1/secret", eeSecretRouter);
|
||||
app.use("/api/v1/secret-snapshot", eeSecretSnapshotRouter);
|
||||
|
||||
@@ -90,7 +90,7 @@ const requireAuth = ({
|
||||
authMode,
|
||||
authPayload, // User, ServiceAccount, ServiceTokenData
|
||||
authChannel: getChannelFromUserAgent(req.headers['user-agent']),
|
||||
authIP: req.ip,
|
||||
authIP: req.realIP,
|
||||
authUserAgent: req.headers['user-agent'] ?? 'other',
|
||||
tokenVersionId: req.tokenVersionId
|
||||
}
|
||||
|
||||
1
backend/src/types/express/index.d.ts
vendored
1
backend/src/types/express/index.d.ts
vendored
@@ -42,6 +42,7 @@ declare global {
|
||||
query?: any;
|
||||
tokenVersionId?: Types.ObjectId;
|
||||
authData: AuthData;
|
||||
realIP: string;
|
||||
requestData: {
|
||||
[key: string]: string
|
||||
};
|
||||
|
||||
@@ -262,6 +262,7 @@ export default function UserInfoStep({
|
||||
setPassword(pass);
|
||||
checkPassword({
|
||||
password: pass,
|
||||
commonPasswords,
|
||||
setErrors
|
||||
});
|
||||
}}
|
||||
@@ -278,7 +279,10 @@ export default function UserInfoStep({
|
||||
{Object.keys(errors).map((key) => {
|
||||
if (errors[key as keyof Errors]) {
|
||||
return (
|
||||
<div className="ml-1 flex flex-row items-top justify-start">
|
||||
<div
|
||||
className="ml-1 flex flex-row items-top justify-start"
|
||||
key={key}
|
||||
>
|
||||
<div>
|
||||
<FontAwesomeIcon
|
||||
icon={faXmark}
|
||||
|
||||
@@ -188,7 +188,7 @@ export default function PersonalSettings() {
|
||||
{Object.keys(errors).map((key) => {
|
||||
if (errors[key as keyof Errors]) {
|
||||
return (
|
||||
<div className="ml-1 flex flex-row items-top justify-start">
|
||||
<div className="ml-1 flex flex-row items-top justify-start" key={key}>
|
||||
<div>
|
||||
<FontAwesomeIcon
|
||||
icon={faXmark}
|
||||
@@ -212,6 +212,7 @@ export default function PersonalSettings() {
|
||||
onButtonPressed={() => {
|
||||
const errorCheck = checkPassword({
|
||||
password: newPassword,
|
||||
commonPasswords,
|
||||
setErrors
|
||||
});
|
||||
if (!errorCheck) {
|
||||
|
||||
@@ -263,6 +263,7 @@ export default function SignupInvite() {
|
||||
setPassword(pass);
|
||||
checkPassword({
|
||||
password: pass,
|
||||
commonPasswords,
|
||||
setErrors
|
||||
});
|
||||
}}
|
||||
@@ -279,7 +280,7 @@ export default function SignupInvite() {
|
||||
{Object.keys(errors).map((key) => {
|
||||
if (errors[key as keyof Errors]) {
|
||||
return (
|
||||
<div className="ml-1 flex flex-row items-top justify-start">
|
||||
<div className="ml-1 flex flex-row items-top justify-start" key={key}>
|
||||
<div>
|
||||
<FontAwesomeIcon
|
||||
icon={faXmark}
|
||||
|
||||
Reference in New Issue
Block a user