[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Secure tables in Lua?
- From: Steven Johnson <temujin98007@...>
- Date: Tue, 1 Jul 2008 13:10:00 -0700 (PDT)
----- Original Message ----
From: Dr. Markus Walther <email@example.com>
Sent: Tuesday, July 1, 2008 5:30:15 AM
Subject: Secure tables in Lua?
The CTM book p.203ff (online version reachable from Wikipedia p.207ff)
defines secure values, i.e. data structures inaccessible without knowing
a special key. The goal is to create secure abstract data types (stacks,
etc.) that protect suitable parts of their internal representations
(e.g. revealing only access methods).
The CTM proposal has two parts. NewName is an operation that creates a
unique name that cannot be printed or typed in. Chunks are limited
records with only the selection operator '.' available.
Now chunks created with such a unique name as selection key can only be
accessed if you know the key, otherwise throwing an error (and not
revealing the key).
IMHO the whole CTM approach focussing on minimal extensions to a kernel
language is very compatible with Lua's philosophy, so I wondered if this
particular idea could be borrowed.
My question therefore to the list: how would one go about replicating
this in (extended?) Lua, perhaps first for tables?
My initial thoughts were to use a metatable approach with a new
write-only field mt.__secure (or perhaps __protected) guarding R/W
access to protected entries of main table t. mt.__secure would hold the
key k to unlock t[k] (perhaps generalized to a table of such keys k_i).
A new builtin name() generates fresh keys.
Rawget on t[k] must be impossible if protection is enabled. Perhaps
type(k) == "name" and print(k) == "name:suppressed" or similar. No
table-walking with next/(i)pairs etc. can discover k.
This is just to get the discussion started, ideas and feedback welcome!
A few weeks back I put together something along these lines (see attached). It's a mixin class for sealing object properties, as opposed to automating member protection. Still, it might be worth a look.
(My classes are userdata-based and the default __index/__newindex will first look in the environment table. Here I get privacy by indexing with unique identifiers local to the class definition's scope, as you can see in this class. This won't suffice in a table-based case, of course.)
My own goal was first to lock down this or that property of an object. For instance, freezing a multimethod's definitions or some of my widgets' behaviors. So you have an open phase, say at startup, where you configure these, and then to seal it you SetKey some key and never expose it (for that matter, you can "throw away the key" by using 0/0... not sure if this is a good thing).
In some cases, e.g. a multi-component widget, it might be good to have several trusted objects able to manipulate a property (analogous to your key table). For that you can make clients with AddClient and use them wherever you see "id" or "id_or_key" as parameters.
In turn, you can restrict which properties individual clients have permission to adjust. This is what the blacklist and whitelist stuff is about.
And finally you just do something like this where needed:
if object:IsAllowed("do_something") then
error("You can't do that!")
Hopefully the rest is self-explanatory.
Description: Binary data