45
Preventing Security Bugs Through Software Design Christoph Kern, Google

Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Preventing Security BugsThrough Software DesignChristoph Kern, Google

Page 2: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

If I had a dollar for every time someone writes an XSS…

Page 3: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Why so Many Bugs?

● Developer education doesn't solve the problem○ Very large number of potentially vulnerable code sites○ Security concerns orthogonal to primary developer focus○ Sometimes quite subtle

● Bugs are hard to find after the fact○ Complex, whole-system data-flows

● Low confidence in security assessment

Page 4: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Don't Blame the Dev,Blame the API

Page 5: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Preventing SQL Injection

Page 6: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

SQL Injection

String getAlbumsQuery = "SELECT … WHERE " + " album_owner = " + session.getUserId() + " AND album_id = " + servletReq.getParameter("album_id");ResultSet res = db.executeQuery(getAlbumsQuery);

Page 7: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

● Prepared Statements○ Developers forget → potential bug

○ dbConn.prepareStatement(

"... WHERE foo = " + req.getParameter("foo"));○ (yes, not making this up)

● Structural Query Builders○ Cumbersome for complex statements

Existing Best Practices

Page 8: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

A Simple, Safe Query API

● Desired: Query has no data-flow dependency on untrusted input● Implied by: Query is concatenation of application-controlled strings

Page 9: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

QueryBuilder

public class QueryBuilder { private StringBuilder query; /** ... Only call with compile-time-constant arg!!! ... */ public QueryBuilder append( @CompileTimeConstant String sqlFragment) {...}

public String getQuery() { return query.build(); }}

Page 10: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Preventing API Misuse

● Developers don't always read documentation○ qb.append(

"WHERE album_id = " + req.getParameter("album_id"));

● Enforce @CompileTimeConstant annotation via javac-integrated checker [github.com/google/error-prone, Aftandilian et al, SCAM '12]

● java/com/google/.../Queries.java:194: error: [CompileTimeConstant]

Non-compile-time constant expression passed to parameter with @CompileTimeConstant type annotation. "WHERE album_id = " + req.getParameter("album_id")); ^

Page 11: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Code Refactoring

// BeforeString sql = "SELECT ... FROM ...";sql += "WHERE A.sharee = :user_id";

if (req.getParam("rating")!=null) { sql += " AND A.rating >= " + req.getParam("rating");}

Query q = sess.createQuery(sql);q.setParameter("user_id", ...);

// AfterQueryBuilder qb = new QueryBuilder( "SELECT ... FROM ...");qb.append("WHERE A.sharee = :user_id");qb.setParameter("album_id", ...);

if (req.getParam("rating")!=null) { qb.append(" AND A.rating >= :rating"); qb.setParameter("rating", ...);}

Query q = qb.build(sess);

Page 12: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Practice

● Implemented inherently-safe Builder APIs for F1 [SIGMOD '12, VLDB '13] (C++, Java), Spanner [OSDI '12] (C++, Go, Java), and Hibernate.

● Refactored all existing call-sites across Google○ Few person-quarters effort

● Removed executeQuery(String) methods○ Hibernate: Errorprone checker to constrain Hibernate API use

● No more SQL injection!

Page 13: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Exceptional Use Cases

● E.g.: Command-line query tool● Provide potentially-unsafe, unconstrained API

○ Subject to security review,

○ enforced using visibility whitelists [bazel.io/docs/build-encyclopedia.html#common.visibility]

○ Needed rarely (1-2% of call sites)

Page 14: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Preventing XSS

Page 15: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Ad-Hoc HTML Markup Creation

var escapedCat = goog.string.htmlEscape(category);var jsEscapedCat = goog.string.escapeString(escapedCat);catElem.innerHTML = '<a onclick="createCategoryList(\'' + jsEscapedCat + '\')">' + escapedCat + '</a>';

What if category == "');xssPlayload();//"

Page 16: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Missing/Incorrect HTML Template Directives

{template .profilePage} … <div class="name">{$profile.name}</div> <div class="bloglink"> <a href="{$profile.blogUrl}">... <div class="about"> {$profile.aboutHtml |noAutoescape} …{/template}

Page 17: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Missing/Incorrect HTML Template Directives

{template .profilePage} … <div class="name">{$profile.name}</div> <div class="bloglink"> <a href="{$profile.blogUrl |sanitizeUrl}">... <div class="about"> {$profile.aboutHtml |noAutoescape} …{/template}

Page 18: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Complex, Whole-System Dataflows

{template .profilePage} ... <div class="name">{$profile.name}</div> <div class="bloglink"> <a href="{$profile.blogUrl}">... <div class="about"> {$profile.aboutHtml |noAutoescape } ...{/template}

...profileElem.innerHTML = templates.profilePage({ profile: rpcResponse.getProfile() });...

...profile = profileBackend.getProfile( currentUser);...rpcReponse.setProfile( profile);

...profileStore->QueryByUser( user, &profile);...

Profile Store

Browser Web-App Frontend

Application Backends

(1)

Page 19: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Strictly Contextually Autoescaping Template Systems

● Template system infers correct context-sensitive sanitization/escaping [Samuel et al, CCS '13]

● No escaping directives/modifiers (the strict part)● Recursive

Page 20: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Strict Contextual Template

{template .profilePage autoescape="strict"} … <div class="name">{$profile.name}</div> <div class="bloglink"> <a href="{$profile.blogUrl}">... <div class="about"> {$profile.aboutHtml} …{/template}

Page 21: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Strict Contextual Template

{template .profilePage autoescape="strict"} … <div class="name">{$profile.name |escapeHtml}</div> <div class="bloglink"> <a href="{$profile.blogUrl |sanitizeUrl|escapeHtml}">... <div class="about"> {$profile.aboutHtml |escapeHtml} …{/template}

Page 22: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Types to Designate Safe Content

● Simple wrappers for string● Context-specific type contracts

○ SafeHtml○ SafeUrl○ TrustedResourceUrl○ SafeStyle○ SafeStyleSheet○ SafeScript

● Similar types in Google Web Toolkit, ca 2009.

Page 23: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

● Inherently-Safe Builders/Producers○ Structural builders○ Strict template evaluation

● Unchecked Conversions○ Subject to security review (BUILD-visibility)○ Guidelines on appropriate use -- reviewability & local reasoning

Creating Safe-Content-Typed Values

Page 24: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Disallow Injection-Prone Sinks

● .innerHTML, server-side responses, etc.● Static enforcement

○ Javascript conformance pass in Closure Compiler○ Errorprone○ Reviewed white-lists

Page 25: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Putting it all Together

{template .profilePage autoescape="strict"} ... <div class="name">{$profile.name}</div> <div class="bloglink"> <a href="{$profile.blogUrl}">... <div class="about"> {$profile. aboutHtml} ... {/template}

...renderer.renderElement( profileElem, templates.profilePage, { profile: rpcResponse.getProfile() });...

...profile = profileBackend.getProfile(currentUser);...rpcReponse.setProfile(profile);

Browser Web-App Frontend Application Backends

...profileStore->QueryByUser( user, &lookup_result);...SafeHtml about_html = html_sanitizer->sanitize( lookup_result.about_html_unsafe())profile.set_about_html(about_html);

Profile Store

HtmlSanitizer

...return UncheckedConversions ::SafeHtml(sanitized);

Page 26: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Practical Application

● Strict contextual escaping in Closure Templates et al.● Adopted in several flagship Google applications● Drastic reduction in bugs

○ One case: ~30 XSS in 2011, None (*) since Sep 2013

● More background: [Kern, CACM 9/'14]

Page 27: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Caveats/Limitations

● Type system○ Reflection, casts, loose visibility○ But: Idiomatic usage patterns matter!

● No formal guarantees○ Correctness properties ultimately based on human reasoning○ But: By design, local reasoning, and drastically reduced scope○ But: In practice, most bugs found in application code

● Pathological uses: Control-flow dep. effectively implies Data-flow dep.○ But: Threat model -- Non-malicious programmer

Page 28: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Lessons Learnt

Page 29: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

It's OK to change code!

Page 30: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Strings are Bad

Page 31: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Unless Proven Otherwise

Page 32: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Types

Page 33: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Simple Static Checks

Page 34: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Don't Track "Taint",Make or Track "Safe"

Page 35: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Simple, Safe, Familiar-ishAPIs (>98%)

Page 36: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Review-Gated Unsafe API (<2%)

Page 37: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Build on Existing Tooling

Page 38: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Benefits

Page 39: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

(Potentially) Vulnerable Code never even Written/Checked-in

Page 40: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Confines Bug Potential into Very Small Portion of Codebase

Page 41: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Drastic Reduction inBugs Observed

Page 42: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Drastic Reduction inReview Burden

Page 43: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Increased Confidence in Correctness

Page 44: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

It's all about API Design

Page 45: Through Software Design Preventing Security Bugs · 2019. 12. 18. · profileStore->QueryByUser(user, &profile);... Profile Store Browser Web-App Frontend Application Backends (1)

Questions?