something died inside your git repo

34
Something Died Inside Your Git Repo: Recognizing the Smell of Insecure Code Cliff Smith, Parameter Security BSides Huntsville February 4, 2017

Upload: cliff-smith

Post on 18-Feb-2017

41 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: Something Died Inside Your Git Repo

Something Died Inside Your Git Repo:Recognizing the Smell of Insecure Code

Cliff Smith, Parameter SecurityBSides HuntsvilleFebruary 4, 2017

Page 2: Something Died Inside Your Git Repo

Intro• Ethical Hacker at Parameter Security in St. Louis, MO• Co-lead of OWASP Saint Louis• Programmer with 20+ years’ experience writing bad code (and

nonnegligible experience writing good code)• Recovering lawyer

Page 3: Something Died Inside Your Git Repo

Code Smells and Refactoring• “[Kent Beck and I] have learned

to look for certain structures in the code that suggest (sometimes they scream for) the possibility of refactoring.” Martin Fowler, Refactoring, p. 63• Something is wrong and likely to

cause maintenance problems• Poorly conceived design OR code

that has deviated from its original design

Page 4: Something Died Inside Your Git Repo

Code Smells and Security• Patterns in thought, code structure and application behavior• Gaps in understanding of security OR bad habits that lead to mistakes• Something is wrong and is likely to get breached:• You chose the wrong approach, thereby making the problem harder than it is• You probably don’t understand the problem, so you probably screwed it up• You may have shown attackers the weak spots in your code

Page 5: Something Died Inside Your Git Repo

Code Smells and Security

https://xkcd.com/463/

Page 6: Something Died Inside Your Git Repo

Pen Test Story - Stored XSS• Attack: <script>alert(‘XSS’)</script>

Page 7: Something Died Inside Your Git Repo

Pen Test Story - Stored XSS• Attack: <script>alert(‘XSS’)</script>• Fix: reject input containing <script

Page 8: Something Died Inside Your Git Repo

Pen Test Story - Stored XSS• Attack: <script>alert(‘XSS’)</script>• Fix: reject input containing <script• Attack: <img onerror=“alert(‘XSS’)” src=“error.jpg” />• Fix: reject input matching /<[a-zA-Z].*>/

Page 9: Something Died Inside Your Git Repo

Pen Test Story - Stored XSS• Attack: <script>alert(‘XSS’)</script>• Fix: reject input containing <script• Attack: <img onerror=“alert(‘XSS’)” src=“error.jpg” />• Fix: reject input matching /<[a-zA-Z].*>/• Attack: <img onerror=“alert(‘XSS’)” src=“error.jpg” (simply omit the

closing bracket)• Fix: reject input matching /<[a-zA-Z]+ / (space at end)

Page 10: Something Died Inside Your Git Repo

Pen Test Story - Stored XSS• Attack: <script>alert(‘XSS’)</script>• Fix: reject input containing <script• Attack: <img onerror=“alert(‘XSS’)” src=“error.jpg” />• Fix: reject input matching /<[a-zA-Z].*>/• Attack: <img onerror=“alert(‘XSS’)” src=“error.jpg” (simply omit the

closing bracket)• Fix: reject input matching /<[a-zA-Z]+ / (space at end)• Attack: insert <img/onmouseover=“alert(‘XSS’)” (use a slash instead of

a space)

Page 11: Something Died Inside Your Git Repo

Cat-and-Mouse Games• Bad guy breaks in, good guy designs a

narrow defense against the exact method used by the bad guy• Design your defenses based on the

vulnerability, not based on the attack• Implement provably, theoretically correct

solutions

Page 12: Something Died Inside Your Git Repo

Another Stored XSS Example<script type=“text/javascript”>$.ready(function() {

Map.init(‘123 Main St.’);});</script>

Page 13: Something Died Inside Your Git Repo

Another Stored XSS Example<script type=“text/javascript”>$.ready(function() {

Map.init(‘123 Main St.’);});</script>

User data interpolated

directly into code – this is as bad as

eval()!

Page 14: Something Died Inside Your Git Repo

Another Stored XSS Example<script type=“text/javascript”>$.ready(function() {

$.get({ /* ... */,function(response) {

Map.init(response.data);});

});</script>

<script type=“text/template” id=“address”>MTIzIE1haW4gU3Qu</script><script type=“text/javascript”>$.ready(function() {

var address = $(‘#address’).text();

address = atob(address);Map.init(address);

});</script>

Provably correct and safeWorks, but hurts performance

Page 15: Something Died Inside Your Git Repo

Church and State

Don’t mix the two!

Code Data

Page 16: Something Died Inside Your Git Repo

Church and State• Separate data from code whenever possible (and it’s always possible)• Use prepared SQL statements• Use <script type=“text/template”> tags and base 64 encoding

• Never rely on rejecting bad input• Escaping control characters is a last resort!

Page 17: Something Died Inside Your Git Repo

Still More Stored XSS Defenses...• Existing application escaped < > “ with HTML entity encoding before

saving user data to database• Today I watched &quot;The Pirates of Penzance&quot; by Gilbert &amp; Sullivan.

• Form elements changed from <input> to <textarea> and vice-versa during page redesigns• JavaScript replaces form elements with <span>s for printing• $span.html($textarea.text())?• $span.text($textarea.html())?

• Like an airport with all security checkpoints at the highway off-ramp

Page 18: Something Died Inside Your Git Repo

Solutions Decoupled from Problems• Poor modularity; poor delineation of responsibilities• Each component has to be aware of the needs of every other component!

• Injection attacks are presentation-layer problems, so solve them in the presentation layer!• Data integrity and model state should be enforced in the model• Easier to maintain, harder to break

Page 19: Something Died Inside Your Git Repo

Junior’s First Database• Single text file• Entire contents rewritten to disk

on every save• Save operations took about 30

seconds• Zero concurrency

ENTRYtype=employeeid=1firstname=JohnENTRYtype=timeentryid=1date=20030811project_id=7

Page 20: Something Died Inside Your Git Repo

Junior’s First Database• Single text file• Entire contents rewritten to disk

on every save• Save operations took about 30

seconds• Zero concurrency• MySQL was eight years old at

this point

ENTRYtype=employeeid=1firstname=JohnENTRYtype=timeentryid=1date=20030811project_id=7

Page 21: Something Died Inside Your Git Repo

Solving Important Problems From Scratch

• Important problems are (1) fundamental, (2) easy to get wrong, or (3) likely to create a vulnerability if you get them wrong• Or they leave you thinking, “Surely someone has done this before…”• Stand on the shoulders of giants (or at least on stilts)• Consider using a reliable, proven third-party solution• Study the literature• Examples:• Parsing HTTP requests and responses• Crypto and authentication• OWASP Top 10

Page 22: Something Died Inside Your Git Repo

The Abstraction Trap• Abstraction allows the application programmer to interact with an

object at a convenient level of complexity• That level of complexity defines the object’s interface• Implementation details are abstracted away

Page 23: Something Died Inside Your Git Repo

The Abstraction Trap• Vulnerabilities can be hidden in the details we abstract away• Examples:• Plugin that can set the user’s session ID – session fixation• Mobile applications that inadvertently cache HTTP responses• RSA Chinese remainder theorem timing leak

• “Not my code” != “not my responsibility”• Book up on APIs, libraries and other third-party code• Look out for features you don’t need or don’t expect

• Subject matter knowledge and security expertise are important

Page 24: Something Died Inside Your Git Repo

Vulnerability in FOSS CMSdef list_users():

authorize_request()users = User.find(…)…

def save_user(id):authorize_request()user = User.find({‘id’:id})…

def delete_user(id):user = User.find({‘id’:id})…

Page 25: Something Died Inside Your Git Repo

WET Code• DRY = don’t repeat yourself• WET = write everything twice• WET code leaves you one forgetful moment away from a vulnerability• DRY code is set it and forget it – solve problems once, not over and again• TIMTOWTDI versus The Zen of Python• Make the obvious solution the safe solution

Page 26: Something Died Inside Your Git Repo

Pen Test Story - Vulnerability in Commercial OSS

function validate_slug($slug) {if (strpos($slug, ‘<‘) != FALSE || strpos($slug, ‘”’) != FALSE) {return FALSE;}return TRUE;

}/* … */<script>showImage(“<?php echo $slug; ?>”);</script>

Page 27: Something Died Inside Your Git Repo

Pen Test Story - Vulnerability in Commercial OSS

function validate_slug($slug) {if (strpos($slug, ‘<‘) != FALSE || strpos($slug, ‘”’) != FALSE) {return FALSE;}return TRUE;

}/* … */<script>showImage(“<?php echo $slug; ?>”);</script>

Page 28: Something Died Inside Your Git Repo

Code Secured by a Single Set of Eyes

• Mistakes happen, but mistakes like this should be caught• This issue could have been caught with:• PHPLint• BurpSuite Scanner, nikto, WebScarab, any other vulnerability scanner or fuzzer• Unit testing• Manual code review

• Every organization should have some process in place

Page 29: Something Died Inside Your Git Repo

Pen Test Story – Mobile ApplicationGET /account/details?account_number=111111111

HTTP/1.1 200 OK {“message”:”success”,“ssn”:”123-45-6789”}

GET /account/details?account_number=222222222

HTTP/1.1 404 Not Found {“message”:”Invalid account number.”}

GET /account/details?account_number=333333333

HTTP/1.1 403 Access Denied {“message”:”Access violation.”}

Page 30: Something Died Inside Your Git Repo

Pen Test Story – Mobile ApplicationPOST /account/reticulateSplines {“foo”:”bar”}

HTTP/1.1 200 OK {“message”:”success”}

POST /account/reticulateSplines {“foo”:”</bar>”}

HTTP/1.1 500 Internal Server Error {“message”:”Uncaught exception in java.xml.parsers.documentbuilder: unexpected closing tag </bar>; expected

</ACCOUNT_OPERATION> at line 3, colum 94.

Stack trace:

…”}

Page 31: Something Died Inside Your Git Repo

Mind the Information Gap• Client and server are on a mutual need-to-know basis• The server should never tell the client something it doesn’t need to know

• Leakage of sensitive information• Giving the attacker a roadmap

• The client should never tell the server something it already knows• Access control errors

• Limit detail in error messages• The fact of the error; how to fix it; how to get help• Interpreter error messages are for developers, not users

• The client is untrusted!

Page 32: Something Died Inside Your Git Repo

Summary• Cat-and-mouse games• Church and state• Solutions decoupled from problems• Solving important problems from scratch• The abstraction trap• WET code• Code secured by a single set of eyes• Mind the information gap

Page 33: Something Died Inside Your Git Repo

Final Thoughts• Understand the conceptual root of each type of vulnerability• Safe handling of user data is a major source of vulnerabilities• All exploits run on information, assumptions and trust• Information should be carefully controlled and rationed• Identify and manage assumptions

• Don’t be afraid to Google simple questions• Study the specs• Programming is an art and a science• Good code is secure code

Page 34: Something Died Inside Your Git Repo

Questions?

[email protected]@BismthSalamandr