diff --git a/aws_sigma_service/api/src/app.module.ts b/aws_sigma_service/api/src/app.module.ts index 05ddb20..651a249 100644 --- a/aws_sigma_service/api/src/app.module.ts +++ b/aws_sigma_service/api/src/app.module.ts @@ -9,7 +9,7 @@ import { Project, ProjectSchema } from "./schemas/project.schema.js"; import { Function, FunctionSchema } from "./schemas/function.schema.js"; import { JwtModule } from "@nestjs/jwt"; import { BcryptService } from "./services/bcrypt.service.js"; -import { JWT_SECRET } from "./auth/const.js"; +import { JWT_SECRET, MONGO_URL } from "./auth/const.js"; import { AuthController } from "./controllers/auth.controller.js"; import { JwtStrategy } from "./auth/jwt.strategy.js"; import { LocalStrategy } from "./auth/local.strategy.js"; @@ -33,9 +33,7 @@ import { HealthController } from "./controllers/health.controller.js"; secret: JWT_SECRET, signOptions: { expiresIn: "3600s" }, }), - MongooseModule.forRoot( - process.env.MONGO_URL ?? "mongodb://sigma:supersecret@localhost:27017" - ), + MongooseModule.forRoot(MONGO_URL), MongooseModule.forFeature([ { name: User.name, diff --git a/aws_sigma_service/api/src/auth/const.ts b/aws_sigma_service/api/src/auth/const.ts index 283bbd2..b3303ea 100644 --- a/aws_sigma_service/api/src/auth/const.ts +++ b/aws_sigma_service/api/src/auth/const.ts @@ -1 +1,11 @@ -export const JWT_SECRET = process.env["JWT_SECRET"] ?? "supersecret"; +function getRequiredEnv(name: string): string { + const value = process.env[name]; + if (!value) { + throw new Error(`${name} environment variable must be set`); + } + + return value; +} + +export const JWT_SECRET = getRequiredEnv("JWT_SECRET"); +export const MONGO_URL = getRequiredEnv("MONGO_URL"); diff --git a/aws_sigma_service/api/src/functions/functions.service.ts b/aws_sigma_service/api/src/functions/functions.service.ts index a99cebd..b3d7cec 100644 --- a/aws_sigma_service/api/src/functions/functions.service.ts +++ b/aws_sigma_service/api/src/functions/functions.service.ts @@ -86,7 +86,7 @@ export class FunctionsService { }); if (func) { - await this.projectModel.findByIdAndUpdate(func._id, { + await this.projectModel.findByIdAndUpdate(func.project, { $inc: { functionsInvocationCount: 1, functionsErrorCount: successful ? 0 : 1, diff --git a/aws_sigma_service/api/src/main.ts b/aws_sigma_service/api/src/main.ts index 2b3053e..1abcb18 100644 --- a/aws_sigma_service/api/src/main.ts +++ b/aws_sigma_service/api/src/main.ts @@ -15,7 +15,9 @@ async function bootstrap() { app.set("query parser", "extended"); app.useGlobalPipes( new ValidationPipe({ - whitelist: false, + whitelist: true, + forbidNonWhitelisted: true, + transform: true, }) ); diff --git a/grob/docker-entrypoint.sh b/grob/docker-entrypoint.sh index 5831cae..87fdb50 100755 --- a/grob/docker-entrypoint.sh +++ b/grob/docker-entrypoint.sh @@ -1,9 +1,14 @@ #!/bin/sh +set -euo pipefail + +# Ensure the ctf user exists (defensive in case the base image changes) +if ! id ctf >/dev/null 2>&1; then + useradd -m -u 1001 ctf +fi # Ensure the history directory exists and has correct ownership mkdir -p /app/history chown -R ctf:ctf /app/history # Run the grob service as ctf user -exec runuser -u ctf /app/grob - +exec runuser -u ctf -- /app/grob diff --git a/sonobank/crates/lua-sandbox/src/lib.rs b/sonobank/crates/lua-sandbox/src/lib.rs index 8b5f779..61e81d4 100644 --- a/sonobank/crates/lua-sandbox/src/lib.rs +++ b/sonobank/crates/lua-sandbox/src/lib.rs @@ -42,14 +42,6 @@ pub fn render_hash(lua_src: &str, note: u32, velocity: u32) -> anyhow::Result<[u let v: f64 = func .call((i as f64 / 44_100.0, note, velocity)) .context(ScriptError)?; - #[allow(dead_code)] - fn vulnerable(buf: &mut [u8], idx: isize, value: u8) { - unsafe { - /* MANUAL pointer arithmetic (dangerous) */ - let ptr = buf.as_mut_ptr().offset(idx); /* Write without bounds check */ - std::ptr::write(ptr, value); - } - } let normalized_v = v.clamp(-1.0, 1.0); hasher.update(normalized_v.to_le_bytes()); } diff --git a/sonobank/crates/server/src/main.rs b/sonobank/crates/server/src/main.rs index c17add7..2a34d63 100644 --- a/sonobank/crates/server/src/main.rs +++ b/sonobank/crates/server/src/main.rs @@ -3,6 +3,7 @@ use std::time::Duration; use tokio::{task, time}; const UDP_PORT: u16 = 5004; +const MAX_PATCH_SIZE: usize = 8 * 1024; const PATCH_MAX_AGE: Duration = Duration::from_secs(30 * 60); const CLEAN_INTERVAL: Duration = Duration::from_secs(10 * 60); const SYSEX_TIMEOUT: Duration = Duration::from_millis(50); @@ -56,6 +57,15 @@ async fn handle_sysex( let response = match msg { sysex::Request::Diag => sysex::Response::Diag, sysex::Request::Put { data } => { + if data.len() > MAX_PATCH_SIZE { + let response = sysex::Response::Error(format!( + "Patch too large ({} bytes > {MAX_PATCH_SIZE})", + data.len() + )); + state.udp_sock.send_to(&response.encode(), addr).await?; + return Ok(()); + } + let lua_dsp = String::from_utf8_lossy(&data).to_string(); if let Err(error) = run_blocking_with_timeout(SYSEX_TIMEOUT, move || lua_sandbox::validate(&lua_dsp)) diff --git a/sonobank/crates/storage/src/lib.rs b/sonobank/crates/storage/src/lib.rs index 71022c9..91f1651 100644 --- a/sonobank/crates/storage/src/lib.rs +++ b/sonobank/crates/storage/src/lib.rs @@ -93,7 +93,7 @@ impl BankStorage { write_tlv(&mut file, TlvTag::EncryptedDataIv, &patch.encrypted_code.iv)?; file.write_all(&[TlvTag::End as u8])?; } - let permissions = std::fs::Permissions::from_mode(0o444); + let permissions = std::fs::Permissions::from_mode(0o600); std::fs::set_permissions(path, permissions)?; Ok(()) }