Implement basic ingress filtering on controller

Validate messages received on the controller from hosts and control
nodes before handling or forwarding them.  This should prevent
performing actions that are not allowed by the role system and block
simple attacks such as spoofing the source address of a message.
This commit is contained in:
Hornwitser committed 2023-07-25 17:21:44 +02:00
1 parent 7a9aec74b5
commit 87172dfb8d
8 files changed
+339 -52

No files matched your search

+30
View File
@@ -1,6 +1,7 @@
"use strict";
const libData = require("@clusterio/lib/data");
const libConfig = require("@clusterio/lib/config");
const libErrors = require("@clusterio/lib/errors");
const { logger } = require("@clusterio/lib/logging");
const libPlugin = require("@clusterio/lib/plugin");
const PlayerStats = require("@clusterio/lib/PlayerStats");
@@ -65,6 +66,35 @@ class HostConnection extends BaseConnection {
this.handle(libData.InstancePlayerUpdateEvent, this.handleInstancePlayerUpdateEvent.bind(this));
}
validateIngress(message) {
let origin = this.connector.dst;
switch (message.src.type) {
case libData.Address.control:
case libData.Address.controller:
throw new libErrors.InvalidMessage(`Received message with invalid src ${message.src} from ${origin}`);
case libData.Address.host:
if (message.src.id !== origin.id) {
throw new libErrors.InvalidMessage(
`Received message with invalid src ${message.src} from ${origin}`
);
}
break;
case libData.Address.instance:
let instance = this._controller.instances.get(message.src.id);
if (!instance || instance.config.get("instance.assigned_host") !== this._id) {
throw new libErrors.InvalidMessage(
`Received message with invalid src ${message.src} from ${origin}`
);
}
break;
default:
throw new Error("Should be unreachable");
}
}
_checkPluginVersions() {
let pluginInfos = new Map(this._controller.pluginInfos.map(i => [i.name, i]));
for (let [name, version] of this.plugins) {