Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/agent/vision/browser_viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ const mineflayerViewer = prismarineViewer.mineflayer;

export function addBrowserViewer(bot, count_id) {
if (settings.render_bot_view)
mineflayerViewer(bot, { port: 3000+count_id, firstPerson: true, });
mineflayerViewer(bot, { host: '127.0.0.1', port: 3000+count_id, firstPerson: true });
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Binding prismarine-viewer to 127.0.0.1 will make the viewer unreachable from outside the process namespace (e.g., typical Docker -p/docker-compose port publishing won’t reach a service that only listens on loopback inside the container). Consider making the bind host configurable (e.g., default to localhost for non-container local dev, but allow 0.0.0.0 when explicitly requested) so existing container/remote viewing setups keep working while still enabling a secure default.

Copilot uses AI. Check for mistakes.
}
26 changes: 25 additions & 1 deletion src/mindcraft/mindserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,31 @@ export function logoutAgent(agentName) {
export function createMindServer(host_public = false, port = 8080) {
const app = express();
server = http.createServer(app);
io = new Server(server);

// Determine allowed origins for CORS / Socket.IO
const allowedOrigins = host_public
? undefined // allow any when explicitly public (Docker/EC2)
: [`http://localhost:${port}`, `http://127.0.0.1:${port}`];

io = new Server(server, {
cors: {
origin: allowedOrigins,
methods: ['GET', 'POST'],
},
Comment on lines +54 to +61
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allowedOrigins is set to undefined when host_public is true and then passed through as cors.origin. That relies on Socket.IO/cors default handling of an explicit origin: undefined, which is ambiguous and can be interpreted differently across versions/config. To make the public mode behavior explicit and stable, either omit the cors option entirely when host_public is true, or set origin to an explicit permissive value (e.g., '*' or true, depending on desired credentials behavior).

Suggested change
? undefined // allow any when explicitly public (Docker/EC2)
: [`http://localhost:${port}`, `http://127.0.0.1:${port}`];
io = new Server(server, {
cors: {
origin: allowedOrigins,
methods: ['GET', 'POST'],
},
? undefined // legacy behavior: previously relied on origin: undefined
: [`http://localhost:${port}`, `http://127.0.0.1:${port}`];
const corsOptions = host_public
// Explicitly allow any origin when running in public mode
? { origin: true, methods: ['GET', 'POST'] }
// Restrict origins to local development URLs when not public
: { origin: allowedOrigins, methods: ['GET', 'POST'] };
io = new Server(server, {
cors: corsOptions,

Copilot uses AI. Check for mistakes.
});

// Security headers
app.use((_req, res, next) => {
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('X-XSS-Protection', '1; mode=block');
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
res.setHeader(
'Content-Security-Policy',
"default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self' ws: wss:; font-src 'self';"
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CSP connect-src 'self' ws: wss: allows WebSocket connections to any host over ws/wss (scheme-only sources), which largely defeats the intent of restricting connections to same-origin. If the UI only needs same-origin Socket.IO/WebSockets, remove ws:/wss: and rely on 'self'; otherwise, specify explicit websocket endpoints/hosts instead of allowing all.

Suggested change
"default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self' ws: wss:; font-src 'self';"
"default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; font-src 'self';"

Copilot uses AI. Check for mistakes.
);
next();
});

// Serve static files
const __dirname = path.dirname(fileURLToPath(import.meta.url));
Expand Down
Loading