Improving Application Security with Data Flow Assertions
description
Transcript of Improving Application Security with Data Flow Assertions
Improving Application Security with Data Flow
AssertionsYip, X. Wang, N. Zeldovich, M. F. Kaashoek
MIT CSAILReading 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 hardfor programmer to correctly identify where each check needs to be
Motivation
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
Example: Hidden Data Flows
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
Ideal Solution
Motivation Resin
◦ Policy Objects◦ Filter Objects◦ Persistent Policies
Evaluation◦ Vulnerabilities Detected◦ Microkernel Overheads
Outline
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: Bird’s-eye view
Resin: Overview
Senmail pipe to user u
HTTP conn. to user w
ContextType: emailEmail: [email protected]
ContextType: HTTPhttp: user w
Language Runtime Bounds
Password Policy email:[email protected]
SecretPass
Your password is:
Password Policy email:[email protected]
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
Resin ObjectsPassword Policy
email:[email protected]
ContextType: emailEmail: [email protected]
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)
Resin Objects: Policy Objects
Password Policy email:[email protected]
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(’[email protected]’));
Policy Example
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)
Policy Objects: Merge
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
Resin Objects: Filter Objects
ContextType: emailEmail: [email protected]
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
Default Filter
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
Persistent Policies
Persistent Policy SQL Storage
Motivation Resin
◦ Policy Objects◦ Filter Objects◦ Persistent Policies
Evaluation◦ Vulnerabilities Detected◦ Microkernel Overheads
Outline
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
Implementation & Evaluation
Vulnerabilities Detected
Microkernel Overheadsas
sign
func
tion
strin
g
add
open
read
1KB
writ
e 1K
B
SELE
CT
INSE
RT
DELE
TE
variable call concat integer File SQL
0
100
200
300
400
500
600
700
800
900empty policyno policyUnmodified PHP
Microkernel
% O
verh
ead
over
bas
elin
e
Byte Level PolicyMerging Policies
Overhead due to
(de)serializing policy objects
Rewriting SQL queries to
add/get policies
Delete just drops the
line