200 likes | 294 Views
Improving Application Security with Data Flow Assertions. Yip, X. Wang, N. Zeldovich , M. F. Kaashoek MIT CSAIL Reading Group by Theo 06 Oct 2009. Motivation. High level vulnerabilities quite common Simple solution: insert necessary checks everywhere they’re needed
E N D
Improving Application Security with Data Flow Assertions Yip, X. Wang, N. Zeldovich, M. F. Kaashoek MIT CSAIL Reading Group by Theo 06 Oct 2009
Motivation • High level vulnerabilities quite common • Simple solution: insert necessary checks everywhere they’re needed • Not as easy as it seems: very hardfor programmer to correctly identify where each check needs to be
Example: Hidden Data Flows • HotCRP password leakage • Password reminder email option • Simple rule: password must be sent to owner only • But, you have email 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
Ideal Solution • 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
Outline • Motivation • Resin • Policy Objects • Filter Objects • Persistent Policies • Evaluation • Vulnerabilities Detected • Microkernel Overheads
Resin: Bird’s-eye view • 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
Resin: Overview From SQL SecretPass Senmail pipe to user u Password Policy email:u@foo.com Context Type: email Email: u@foo.com Your password is: HTTP conn. to user w SecretPass Password Policy email:u@foo.com Context Type: HTTP http: user w Associated with password characters only Language Runtime Bounds
Resin Objects Password Policy email:u@foo.com • 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 Context Type: email Email: u@foo.com
Resin Objects: Policy Objects • 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 email:u@foo.com
Policy Example class PasswordPolicy extends Policy { private $email; function __construct($email) { $this->email = $email; } function export_check($context) { if ($context[’type’] == ’email’ && $context[’email’] == $this->email) return; throw new Exception(’unauthorized disclosure’); } } policy_add($password, new PasswordPolicy(’u@foo.com’));
Policy Objects: Merge • 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)
Resin Objects: Filter Objects • 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: email Email: u@foo.com
Default Filter 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 Policies • 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
Outline • Motivation • Resin • Policy Objects • Filter Objects • Persistent Policies • Evaluation • Vulnerabilities Detected • Microkernel Overheads
Implementation & Evaluation • 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
Microkernel Overheads Rewriting SQL queries to add/get policies Delete just drops the line Overhead due to (de)serializing policy objects Merging Policies Byte Level Policy