Yip, X. Wang, N. Zeldovich, M. F. Kaashoek MIT CSAIL Reading Group by Theo 06 Oct 2009
High level vulnerabilities quite common Simple solution: insert necessary checks everywhere they’re needed Not as easy as it seems: very hard for programmer to correctly identify where each check needs to be
HotCRP password leakage ◦ Password reminder option ◦ Simple rule: password must be sent to owner only ◦ But, you have preview mode Cross-site scripting ◦ Server should never send unsanitized user-supplied input as response; input must not contain valid JavaScript ◦ Simple logic: sanitize all user input You did remember to check the whois response, right? ◦ PHPMyAdmin must check input in 1,409 locations
Data are automatically assigned policy objects (metadata) ◦ E.g., trusted, user-supplied, private Policy objects are automatically propagated according to specified rules (propagation handlers) Prior to leaving the system, policy objects must pass through filter objects (syscall handlers) ◦ E.g., going to SQL, user, disk ◦ Exception thrown on disallowed actions
Motivation Resin ◦ Policy Objects ◦ Filter Objects ◦ Persistent Policies Evaluation ◦ Vulnerabilities Detected ◦ Microkernel Overheads
DIFT tool running inside high-level interpreted languages ◦ PHP, Python e.t.c. ◦ The interpreter, server, O/S are trusted Resin cannot protect against attacks targeting O/S etc. Consider Resin an object-oriented lifeguard platform ◦ Metadata are classes that carry methods on how to be propagated and checked ◦ Resin defines the interface and default actions
Senmail pipe to user u HTTP conn. to user w Context Type: Context Type: HTTP http: user w Language Runtime Bounds Password Policy SecretPass Your password is: Password Policy SecretPass From SQL Associated with password characters only
Policy Objects ◦ Marks data as private, secure, user-input etc Filter Objects ◦ Associated with runtime border objects Pipes, connections, etc ◦ Can have at function borders ◦ Automatically associated with context What kind of connection To whom Password Policy Context Type:
Associated with primitive data ◦ int, char, …, but not String, int [], … ◦ A datum may be associated with multiple Policies Implement export_check (context) ◦ Called automatically by filter object which provides context ◦ Usually do nothing (approve) or throw exception (block) Password Policy
class PasswordPolicy extends Policy { private $ ; function __construct($ ) { $this-> = $ ; } function export_check($context) { if ($context[’type’] == ’ ’ && $context[’ ’] == $this-> ) return; throw new Exception(’unauthorized disclosure’); } policy_add($password, new
What happens if at least one input of binop has a policy object? Default action union Policy that wants to change it must implement merge(policySet) ◦ Automatically called, if implemented, for each assoc. policy of each source operand ◦ Input: all the policies of the other source operand ◦ Returns the desired new policy set or throws exception ◦ Final set = union of all returns from all merges Example: trusted iff all inputs trusted (intersection)
Automatically at runtime boundaries ◦ Pipes to SQL or Sendmail, HTTP to users Manually at specific functions ◦ E.g. before signer to remove Secret policy from signature Default behavior: call every export_check it sees ◦ Pass this filter’s context ◦ If no export_check, approve data flow Default behavior override ◦ Block flow of data not associated with TrustedByRootPolicy Prevents server-side scripting Context Type:
class DefaultFilter(Filter): def __init__(self): self.context = {} def filter_write(self, buf): for p in policy_get(buf): if hasattr(p, ’export_check’): p.export_check(self.context) return buf
Persistent I/O rewritten on-the-fly by filter objects ◦ Disk, SQL ◦ Disk I/O automatically reads/writes policies in file’s extended attributes ◦ SQL queries rewritten to query/update policies Modified: create table, select, update, etc Resin only stores names of policies and private data, not binary implementation ◦ Implementation can change easily
Motivation Resin ◦ Policy Objects ◦ Filter Objects ◦ Persistent Policies Evaluation ◦ Vulnerabilities Detected ◦ Microkernel Overheads
PHP prototype: ~6000 lines of code ◦ 2600 for SQL stuff ◦ 1100 core structures ◦ 2200 propagation and merge int Added Resin to real-life apps to catch known and unknown bugs Run microkernels to get overhead Performance numbers for HotCRP (conference management app) ◦ 33% overhead (but runs in PHP interpreter, not directly C) ◦ 88ms to display a page instead of 66ms
Byte Level Policy Merging Policies Overhead due to (de)serializing policy objects Rewriting SQL queries to add/get policies Delete just drops the line