Merge branch 'main' into feat/addProjectDeletionProtection

This commit is contained in:
carlosmonastyrski
2025-04-16 10:00:23 -03:00
54 changed files with 1707 additions and 271 deletions
+2 -1
View File
@@ -24,5 +24,6 @@ export enum PermissionConditionOperators {
$IN = "$in",
$EQ = "$eq",
$NEQ = "$ne",
$GLOB = "$glob"
$GLOB = "$glob",
$ELEMENTMATCH = "$elemMatch"
}
+1
View File
@@ -197,6 +197,7 @@ const envSchema = z
/* ----------------------------------------------------------------------------- */
/* App Connections ----------------------------------------------------------------------------- */
ALLOW_INTERNAL_IP_CONNECTIONS: zodStrBool.default("false"),
// aws
INF_APP_CONNECTION_AWS_ACCESS_KEY_ID: zpStr(z.string().optional()),
+29 -4
View File
@@ -118,7 +118,12 @@ export const signingService = (algorithm: AsymmetricKeyAlgorithm): TAsymmetricSi
}
};
const $signRsaDigest = async (digest: Buffer, privateKey: Buffer, hashAlgorithm: SupportedHashAlgorithm) => {
const $signRsaDigest = async (
digest: Buffer,
privateKey: Buffer,
hashAlgorithm: SupportedHashAlgorithm,
signingAlgorithm: SigningAlgorithm
) => {
const tempDir = await createTemporaryDirectory("kms-rsa-sign");
const digestPath = path.join(tempDir, "digest.bin");
const sigPath = path.join(tempDir, "signature.bin");
@@ -164,12 +169,22 @@ export const signingService = (algorithm: AsymmetricKeyAlgorithm): TAsymmetricSi
}
return signature;
} catch (err) {
logger.error(err, "KMS: Failed to sign RSA digest");
throw new BadRequestError({
message: `Failed to sign RSA digest with ${signingAlgorithm} due to signing error. Ensure that your digest is hashed with ${hashAlgorithm.toUpperCase()}.`
});
} finally {
await cleanTemporaryDirectory(tempDir);
}
};
const $signEccDigest = async (digest: Buffer, privateKey: Buffer, hashAlgorithm: SupportedHashAlgorithm) => {
const $signEccDigest = async (
digest: Buffer,
privateKey: Buffer,
hashAlgorithm: SupportedHashAlgorithm,
signingAlgorithm: SigningAlgorithm
) => {
const tempDir = await createTemporaryDirectory("ecc-sign");
const digestPath = path.join(tempDir, "digest.bin");
const keyPath = path.join(tempDir, "key.pem");
@@ -216,6 +231,11 @@ export const signingService = (algorithm: AsymmetricKeyAlgorithm): TAsymmetricSi
}
return signature;
} catch (err) {
logger.error(err, "KMS: Failed to sign ECC digest");
throw new BadRequestError({
message: `Failed to sign ECC digest with ${signingAlgorithm} due to signing error. Ensure that your digest is hashed with ${hashAlgorithm.toUpperCase()}.`
});
} finally {
await cleanTemporaryDirectory(tempDir);
}
@@ -329,7 +349,12 @@ export const signingService = (algorithm: AsymmetricKeyAlgorithm): TAsymmetricSi
const signDigestFunctionsMap: Record<
AsymmetricKeyAlgorithm,
(data: Buffer, privateKey: Buffer, hashAlgorithm: SupportedHashAlgorithm) => Promise<Buffer>
(
data: Buffer,
privateKey: Buffer,
hashAlgorithm: SupportedHashAlgorithm,
signingAlgorithm: SigningAlgorithm
) => Promise<Buffer>
> = {
[AsymmetricKeyAlgorithm.ECC_NIST_P256]: $signEccDigest,
[AsymmetricKeyAlgorithm.RSA_4096]: $signRsaDigest
@@ -360,7 +385,7 @@ export const signingService = (algorithm: AsymmetricKeyAlgorithm): TAsymmetricSi
});
}
const signature = await signFunction(data, privateKey, hashAlgorithm);
const signature = await signFunction(data, privateKey, hashAlgorithm, signingAlgorithm);
return signature;
}
+8 -1
View File
@@ -2,10 +2,16 @@ import dns from "node:dns/promises";
import { isIPv4 } from "net";
import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "../errors";
import { isPrivateIp } from "../ip/ipRange";
export const blockLocalAndPrivateIpAddresses = async (url: string) => {
const appCfg = getConfig();
if (appCfg.isDevelopmentMode) return;
const validUrl = new URL(url);
const inputHostIps: string[] = [];
if (isIPv4(validUrl.host)) {
@@ -18,7 +24,8 @@ export const blockLocalAndPrivateIpAddresses = async (url: string) => {
inputHostIps.push(...resolvedIps);
}
const isInternalIp = inputHostIps.some((el) => isPrivateIp(el));
if (isInternalIp) throw new BadRequestError({ message: "Local IPs not allowed as URL" });
if (isInternalIp && !appCfg.ALLOW_INTERNAL_IP_CONNECTIONS)
throw new BadRequestError({ message: "Local IPs not allowed as URL" });
};
type FQDNOptions = {