Merge pull request #1053 from bbassie/fix/instance-save-name-traversal

Check save names in instance start and create save
This commit is contained in:
Bastiaan authored and GitHub committed 2026-10-08 15:43:26 +01:00
1 parent ce6bfe282f
commit 069f537bde
2 files changed
+30

No files matched your search

+13
View File
@@ -15,6 +15,15 @@ import { exportData } from "./export.js";
import type Host from "./Host.js";
import { BaseInstancePlugin, InstanceHooks } from "./BaseInstancePlugin.js";
// Reject save names that would escape the instance's saves directory.
function checkRequestSaveName(name: string) {
try {
lib.checkFilename(name);
} catch (err: any) {
throw new lib.RequestError(`Save name ${err.message}`);
}
}
const scriptCommands = [
"/cheat", "/editor",
"/command", "/c",
@@ -1268,6 +1277,9 @@ end`.replace(/\r?\n/g, " ");
async handleInstanceStartRequest(request: lib.InstanceStartRequest) {
let saveName = request.save;
if (saveName !== undefined) {
checkRequestSaveName(saveName);
}
try {
try {
await this.prepare();
@@ -1327,6 +1339,7 @@ end`.replace(/\r?\n/g, " ");
}
async handleInstanceCreateSaveRequest(request: lib.InstanceCreateSaveRequest) {
checkRequestSaveName(request.name);
this.notifyStatus("creating_save");
try {
this.logger.verbose("Writing server-settings.json");
+17
View File
@@ -223,6 +223,23 @@ describe("class Instance", function() {
});
});
describe("save name checks", function() {
it("should reject a start save outside the saves directory", async function() {
await assert.rejects(
instance.handleInstanceStartRequest(new lib.InstanceStartRequest("../escape.zip")),
lib.RequestError,
);
});
it("should reject a created save outside the saves directory", async function() {
await assert.rejects(
instance.handleInstanceCreateSaveRequest(
new lib.InstanceCreateSaveRequest("../escape.zip"),
),
lib.RequestError,
);
});
});
describe("._recordPlayerJoin()", function() {
it("should add player to playersOnline", function() {
instance._recordPlayerJoin("player");