From a78e5e78e3f8c08a0291687e0b9463f8a5c0a950 Mon Sep 17 00:00:00 2001
From: Ulrik Sverdrup <ulrik.sverdrup@gmail.com>
Date: Wed, 24 Mar 2010 13:00:20 +0100
Subject: [PATCH] Make impossible to access operating system from Lua scripts

For security reasons, Lua scripts should not be able to read files or
run programs on the host computer; freeciv scenarios should only be
able to influence the state of the game, not the state of the server
process or computer (except through normal scenario events, such as
end of game).

For this reason, we do not load some standard lua libraries that allow
access to files or the operating system. We also disallow loading lua
libraries so that the script cannot go around this restriction.

This is the 2.1-branch version (Lua 5.0): we exclude the io library
('io' and 'os' modules) and blacklist functions dofile, loadfile and
require.

See gna bug #15624
---
 server/scripting/script.c |   27 ++++++++++++++++++++++++++-
 1 files changed, 26 insertions(+), 1 deletions(-)

diff --git a/server/scripting/script.c b/server/scripting/script.c
index 5302249..6824003 100644
--- a/server/scripting/script.c
+++ b/server/scripting/script.c
@@ -44,6 +44,16 @@ static char *script_code;
 
 
 /**************************************************************************
+  Unsafe Lua builtin symbols that we to remove access to.
+**************************************************************************/
+static const char *script_unsafe_symbols[] = {
+  "dofile",
+  "loadfile",
+  "require",
+  NULL
+};
+
+/**************************************************************************
   Report a lua error.
 **************************************************************************/
 static int script_report(lua_State *L, int status, const char *code)
@@ -361,6 +371,19 @@ static void script_code_save(struct section_file *file)
 }
 
 /**************************************************************************
+  Remove global symbols from lua state L
+**************************************************************************/
+static void script_blacklist(lua_State *L, const char *lsymbols[])
+{
+  int i;
+
+  for (i = 0; lsymbols[i] != NULL; i++) {
+    lua_pushnil(L);
+    lua_setglobal(L, lsymbols[i]);
+  }
+}
+
+/**************************************************************************
   Initialize the scripting state.
 **************************************************************************/
 bool script_init(void)
@@ -371,12 +394,14 @@ bool script_init(void)
       return FALSE;
     }
 
+    /* Open default libraries, excluding io */
     luaopen_base(state);
     luaopen_string(state);
-    luaopen_io(state);
     luaopen_debug(state);
     luaopen_table(state);
 
+    script_blacklist(state, script_unsafe_symbols);
+
     tolua_api_open(state);
 
     script_code_init();
-- 
1.7.0

