Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building Rugged Software in a DevOps World

Building Rugged Software in a DevOps World

In this talk, Matt will tackle the challenges of building robust secure software in a world of continuous delivery. To start, Matt will introduce a visual model of a typical delivery pipeline and illustrate how and where different security tools and processes can be layered into the model in an additive non-blocking way. Of course, DevOps adoption presents both challenges and opportunities. Understanding security and DevOps in the same frame of reference makes it possible to make Rugged part of our DNA. One of the foundations of continuous delivery is strong unit testing. To satisfy those seeking deep technical examples and practices they can take home with them and implement tomorrow, I will demonstrate and walk through a suite of common security related unit tests that can be used to ensure that security is a first class consideration that gets tested with each delivery.

Matt Konda

June 07, 2016
Tweet

More Decks by Matt Konda

Other Decks in Technology

Transcript

  1. Introduction 1997 2006 2014 Consultant Engineer Software Architect Director of

    Engineering Rabble Rouser: Perl Java Applet C++ J2EE J2EE
 Spring Analytics Certificate Authority Vulnerability Scanner Penetration Test Manager Pricing Retail Banking Manufacturing Pharma Healthcare Research Ruby Rails Chicago BSides 2011, 2012 Defcon Skytalk OWASP Chicago, MSP 2013 AppSec USA 2012, 2013 ChicagoRuby 2013 Secure 360 Lone Star Ruby 2013 WindyCityRails 2013 Chicago JUG 2014 RailsConf 2014 Converge 2014 Chicago Coder Conference 2015 MS in CS Founder Consultant Agile Clojure Graph Database Trying to hack a business model that succeeds while helping developers. Domains: Projects: DevOps / Automation Training Coaching Code Review Plugged in to SDLC Consulting Assessments @mkonda [email protected] DevOps Growing
  2. I recognize that software has become a foundation of our

    modern world. I recognize the awesome responsibility that comes with this foundational role. I recognize that my code will be used in ways I cannot anticipate, in ways it was not designed, and for longer than it was ever intended. I recognize that my code will be attacked by talented and persistent adversaries who threaten our physical, economic and national security. I recognize these things – and I choose to be rugged.
  3. I recognize that software has become a foundation of our

    modern world. I recognize the awesome responsibility that comes with this foundational role. I recognize that my code will be used in ways I cannot anticipate, in ways it was not designed, and for longer than it was ever intended. I recognize that my code will be attacked by talented and persistent adversaries who threaten our physical, economic and national security. I recognize these things – and I choose to be rugged.
  4. I recognize that software has become a foundation of our

    modern world. I recognize the awesome responsibility that comes with this foundational role. I recognize that my code will be used in ways I cannot anticipate, in ways it was not designed, and for longer than it was ever intended. I recognize that my code will be attacked by talented and persistent adversaries who threaten our physical, economic and national security. I recognize these things – and I choose to be rugged.
  5. Database What does a delivery pipeline really look like? AppServ1

    AppServ2 AppServN WebServ1 WebServ2 WebServ3 LB1 LB2
  6. Database What does a delivery pipeline really look like? AppServ1

    AppServ2 AppServN WebServ1 WebServ2 WebServ3 LB1 LB2
  7. Database What does a delivery pipeline really look like? AppServ1

    AppServ2 AppServN WebServ1 WebServ2 WebServ3 LB1 LB2
  8. Database What does a delivery pipeline really look like? AppServ1

    AppServ2 AppServN WebServ1 WebServ2 WebServ3 LB1 LB2
  9. Database What does a delivery pipeline really look like? AppServ1

    AppServ2 AppServN WebServ1 WebServ2 WebServ3 LB1 LB2
  10. Database What does a delivery pipeline really look like? AppServ1

    AppServ2 AppServN WebServ1 WebServ2 WebServ3 LB1 LB2
  11. Database What does a delivery pipeline really look like? AppServ1

    AppServ2 AppServN WebServ1 WebServ2 WebServ3 LB1 LB2
  12. Running Pipeline from Docker 1. docker-machine create --driver virtualbox default

    2. eval $(docker-machine env default) 3. docker pull owasp/pipeline:0.8.7 4. docker run —rm owasp/pipeline:0.8.7 -h 5. docker run —rm owasp/pipeline:0.8.7 -t brakeman https://github.com/Jemurai/ triage.git
  13. Security in the SDLC • Building software is a process.

    • The best way to make software secure is to make security part of the process. • There are many ways to do this - none is perfect. • Find a way to make the security fit your process.
  14. Story Continuous Delivery: The Unit of Work is a Story

    Requirements Design Code Test Security Requirements Security Unit Tests Exploratory Testing Static Analysis on Commit Code Review Threat model / attack surface Checklists Understand Dependencies
  15. Running Pipeline on a Git Hook 1. Copy /hooks/pre-commit to

    your project in <project-root>/.git/hooks 2. chmod +x pre-commit 3. Edit pre-commit to reflect your path and tools 4. Regular process: 1. Change a <file> 2. git add <file> 3. git commit -m “Testing” <file>
  16. Recap of “Tasks” • File: AV, FIM • Code: •

    Ruby/Rails: brakeman, bundler-audit • JavaScript: NodeSecurityProject, eslint, retire.js • Java: owasp-dependency-check • Checkmarx • Live: ZAP
  17. This year, organized crime became the most frequently seen threat

    actor for Web App Attacks. Source: Verizon 2015 Data Breach Investigations Report
  18. continuous delivery Since its easy to provision we can do

    security testing safely in a new env.
  19. continuous delivery Another principle of software delivery: build security in!

    Done means secure! Empowered to do security right!
  20. Commit • Security Unit Tests • Static Code Analysis (Pipeline)

    • Security Requirements • Check Dependencies • Code Review • Checklists
  21. Deploy • Scripted Provisioning / Built in Change Control •

    Provisioning Auditing (Chef Audit, hardening.io) • Gauntlt
  22. Periodic • Full app analysis (static, manual pen test) •

    Secure Development Training • Baseline Security Requirements Review • ASVS Review • Data Science on Results
  23. Demo cucumber --name "person is restricted from putting input into

    a field that will be executed by the system"
  24. Root cause def destroy @project = Project.find(params[:id]) name = @project.name

    `rm /tmp/#{name}.log` @project.destroy respond_to do |format| format.html { redirect_to projects_url } format.json { head :no_content } end end What if @project.name is : "; cat /etc/passwd > public/passwd.html;”
  25. Feature: person is restricted from accessing project they do not

    own Scenario: person accesses a project  that is not theirs  Given a new project created by a user When a different person attempts to access the project Then the system should prevent access
  26. Given(/^a new project created by a user$/) do uuid =

    SecureRandom.uuid @user1 = "fb_user_1_#{uuid}@jemurai.com" register_as_user(@user1, "password") new_project("Insecure Direct Object Reference #{uuid}", "Forceful Browsing Desc") @url = current_url end When(/^a different person attempts to access the project$/) do logout(@user1) uuid = SecureRandom.uuid @user2 = "fb_user_2_#{uuid}@jemurai.com" register_as_user(@user2, "password") end Then(/^the system should prevent access$/) do visit @url expect(page).not_to have_content "Forceful Browsing Desc" end
  27. Handy http://localhost:3000/projects?name=%27A%27%29%20or%201=1%20-- def index email = current_user.email conditions = "owner

    LIKE '#{email}'" if params[:name] conditions = "name like #{params[:name]} " + conditions end @projects = Project.find(:all, :conditions=>conditions) respond_to do |format| format.html # index.html.erb format.json { render json: @projects } end end SELECT "projects".* FROM "projects" WHERE (name like 'A') or 1=1 -- owner LIKE '[email protected]') For illustration
  28. Feature: user is prevented from putting XSS in project form

    fields A user wants to be sure that others users can't put XSS in the projects pages in order to ensure that their sessions and information are safe. @javascript Scenario Outline: xss attempt Given the field is "<fieldname>" When the value is "<value>" Then the field result should be "<result>" Scenarios: xss in fields | fieldname | value | result | | project[name] | ProjectName | noxss | | project[name] | ProjectName <script>alert('project[name]->xss');</script> | xss | | project[desc] | ProjectDesc <script>alert('project[desc]->xss');</script> | nods |
  29. new_project("XSS Name #{@field} #{uniq}","XSS Desc #{@field}"+ uniq) click_link 'Edit' fill_in

    @field, :with => @value click_button "Update Project" if @result == "xss" # This should have xss in it...did it stick? alerted = false begin page.driver.browser.switch_to.alert.accept alerted = true rescue end if alerted fail("XSS Used to create Popup in #{@field} with #{@value}") else puts "Good news, no xss where expected." end else expect(page).to have_content @value end
  30. Feature: user is protected from malicious content and having their

    page framed A user wants to be sure that effective browser protections are enabled in order to ensure that their information is safe. @javascript Scenario Outline: check for secure headers attempt Given a new project created by a user And the page is "<page>" When the header is "<header>" Then the header value should be "<result>" Scenarios: headers in pages | page | header | result | | projects/ | X-Frame-Options | DENY | | projects/ | X-XSS-Protection | 1 |
  31. cookies = Capybara.current_session.driver.browser.manage.all_cookies csrf_token = Capybara.current_session.driver.browser.find_element(:xpath, "//meta[@name='csrf-token']").attribute('content'); # Switch mode

    to net::http uri = URI.parse(url) http = Net::HTTP.new(uri.host, uri.port) http.verify_mode = OpenSSL::SSL::VERIFY_NONE request = Net::HTTP::Post.new(uri.request_uri) request['Cookie'] = cookies request.set_form_data( { "_method" => "put", "authenticity_token" => "#{csrf_token}", "project[name]"=> "header updated and verified", "commit"=>"Update Project" }) response = http.request(request) ... if response[@header] == @result #pass else fail("Header #{@header} not set to #{@result} as expected. Instead was #{response[@header]}.") end
  32. Simplified Steps • Injection: inject commands into fields and detect

    functions being called. • XSS: inject scripts into fields and detect that alerts are thrown • Mass assignment: set raw form data with net::http and send it to see how the server responds • CSRF: alter CSRF token and send otherwise valid request • Headers: interact with system and verify that headers are being set • Sensitive Data: open session cookie and inspect
  33. SELECT "orders".* FROM "orders" WHERE (rewards_code = 'a') union select

    id, 'product', 1, 1, 'cc', 'cvv', 'expiration', email as first_name, encrypted_password as last_name, created_at, updated_at, id, 'reward' from users; --')
  34. Getting Rugged? Train. Search for string concatenation: +, append prefer

    parameterized queries! Do code review. Use static analysis. Use web app scanning.
  35. Getting Rugged? Train. Search for {{{, innerHTML, .raw, utext, etc.

    Do code review. Use static analysis. Use web app scanning.