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

Securing Legacy Applications - Longhorn PHP 2018

Securing Legacy Applications - Longhorn PHP 2018

It’s common to hear people preach “plan in security from the start” and in an ideal world, you can. Here in the real world, though, we have legacy code that’s gathered over time and comes with a host of problems – (in)security included. What do you do when you’ve been commissioned with securing an application that’s showing its age? Follow along with me as I step you through a list of tips and tricks you can use to discover security issues in your application and effectively fix them and secure your application.

Topics will include some of the most common vulnerability types, key places to look for potential issues and arm you with the tools and knowledge you’ll need to refactor that legacy application into something secure.

Chris Cornutt

April 20, 2018
Tweet

More Decks by Chris Cornutt

Other Decks in Programming

Transcript

  1. Securing Legacy
    Applications
    A Developer’s Guide
    Longhorn PHP 2018 @enygma

    View Slide

  2. View Slide

  3. Simplify
    Simplify
    Simplify
    Complexity is the enemy of
    security.
    Refactor for simplicity.

    View Slide

  4. Security
    Risk

    View Slide

  5. Understand the Scope

    View Slide

  6. Understand the Scope
    AUTH OUTPUT
    INPUT
    BUSINESS
    LOGIC
    DATA
    BACKEND

    View Slide

  7. Understand the Scope
    AUTH OUTPUT
    INPUT
    BUSINESS
    LOGIC
    DATA
    BACKEND
    APP

    View Slide

  8. Understand the Scope
    Work from the outside in (general),
    then introduce security
    Identify and document where data changes hands

    View Slide

  9. Quick Hits

    View Slide

  10. Quick Hits: Globals
    Look for global use deeper in code
    In PHP, that’s superglobals first
    $_POST, $_GET, $_SERVER, $_COOKIE
    $_FILES, $_SESSION
    Get rid of these right now:
    $GLOBALS, $_REQUEST
    EGPCS: Environment, Get, Post, Cookie, and Server

    View Slide

  11. Quick Hits: Unfiltered Data
    Using values directly, no filtering/validation
    Also
    getRequestParam()
    Input::get()
    _request->getQuery()
    getParam()
    Dangerous concatenation
    Injection issues
    Solution:
    filter_var or filtering/validation libraries

    View Slide

  12. Quick Hits: Sensitive Logging
    User PII, credentials, tokens
    Logs are output too
    Log servers are often less secured
    Solution:
    Remove the sensitive information
    (and purge the logs!)
    Log only identifiers and hard-coded strings

    View Slide

  13. Quick Hits: Drop Catch-Alls
    Fallbacks are nice, until they’re not
    Be specific, like in routing
    Catch-alls make for sloppy code and difficult to manage
    dependencies.
    Solution:
    Remove them.
    Specify exact matches & functionality

    View Slide

  14. Quick Hits: Action Splitting
    REST-ey principle:
    GET reads, POST/PUT/DELETE updates
    Never the two (or three…or more?) shall meet
    Take advantage of framework-specific handling
    $app->get()
    requirements.sf_method
    Solution:
    Abstract out the handling by action
    Ensure proper protection (CSRF/HMAC)

    View Slide

  15. Input Handling

    View Slide

  16. Input Handling: Input Points
    Locating input points (remember your threat model?)
    grep is your best friend (naming conventions)
    Do you really need it or is it just lazy?
    Solution:
    Avoid user-controllable data sources
    Use the force….er filter.

    View Slide

  17. Input Handling: Determine
    Risk
    Reducing inputs reduces risk
    Examine context (especially mixed)
    Example: is it used in evaluation and output?
    Document risk points (threat model)
    Solution:
    Maintain data via stateful sources (sessions)
    All external data is tainted. Never forget.

    View Slide

  18. Validation
    (Add & Update)

    View Slide

  19. Validation: Do You Even?
    Not a priority in many apps, sadly.
    Same Origin Fallacy
    “It’s mine! All mine!”
    Libraries vs internal methods
    like filter_var or Respect\Validation
    Solution:
    Assess validation needs across application (do they repeat?)
    Remember the threat model for inputs.
    Fail fast.

    View Slide

  20. Validation: Sanitize
    Don’t use as a replacement for input validation.
    The more assumptions you make,
    the higher the risk factor.
    Consider output contexts too (HTML, JS, XML…)
    Solution:
    Validate first, then sanitize.
    Don’t try too hard.

    View Slide

  21. Templating

    View Slide

  22. Templating: PHP
    PHP is not a templating language…no really.
    Largest refactor point in legacy applications.
    Using methods to escape output? That’s templating.
    Evaluate options: template it all vs spot checks.

    View Slide

  23. Templating: Manual
    Prone to mistakes.
    Hard to manage effectively.
    Beware the copy and paste (and context changes).
    Move slowly, replace most used first.
    Based on logging

    View Slide

  24. Templating: Special Output
    HTML is not the only context.
    Javascript, CSS, HTML attribute, plain-text, log output.
    Template (escape) for the context.
    HTML htmlspecialchars
    CSS Replace with [num]
    Javascript Replace with \x
    URL url encode

    View Slide

  25. Access Control

    View Slide

  26. Access Control: Now
    Determine current controls (Auth*)
    Determine coverage of controls
    Threat model!
    Look for over-engineering

    View Slide

  27. Access Control: Credentials
    Look for hard-coded values
    username, token, password
    Extract the values and protect
    Think about protection levels
    External tool, external file, external service

    View Slide

  28. Access Control: Endpoints
    Public, Private, Conditional
    Different protection levels
    Start with most used (logs as a guide)
    Protect at different levels
    router, endpoint, server - defense in depth!
    See if there’s a simpler way

    View Slide

  29. Access Control: User
    Determine user types
    Create a grid of types and endpoints
    Features == users?
    Administrator vs user

    View Slide

  30. Adding New Controls

    View Slide

  31. Adding New Controls
    Can tools be consolidated (or removed)?
    Determine missing controls
    Are there 3rd party tools/libraries you can reuse?
    Simple is good, but sometimes complex is needed
    Are there interfaces with other systems?

    View Slide

  32. Adding New Controls:
    Examples
    CSRF tokens injected automatically on render
    Encryption of data via libraries (ex: libsodium, defuse-php)
    Implementing a templating library
    Access control types:
    Access control list (ACL)
    Role-based access control (RBAC)
    Property-based access control
    Multi-factor authentication

    View Slide

  33. Changing Development
    Practices

    View Slide

  34. Changing Dev Process
    Hardest part in the whole process
    New code needs security guidance
    Manual (security) code review
    Establish a pattern of security refactoring

    View Slide

  35. Changing Dev Process
    Integrate tools and services
    Scanners
    3rd party services
    Pentesting
    Bug Bounty
    Refactor bite-size pieces,
    related to current development
    Build a culture of security

    View Slide

  36. It doesn’t require a security expert, just
    a security mindset.

    View Slide

  37. Thanks! Questions?
    @enygma @securingphp
    https://websec.io

    View Slide