Defensive Coding Crash Course - ZendCon 2017

Post on 22-Jan-2018

257 views 0 download

Transcript of Defensive Coding Crash Course - ZendCon 2017

Defensive CodingCrash Course

Mark Niebergall https://joind.in/talk/d4c29

About Mark Niebergall• PHP since 2005 • Masters degree in MIS • Senior Software Engineer • Drug screening project • UPHPU President • CSSLP, SSCP Certified and SME • Drones, fishing, skiing, father, husband

Defensive CodingCrash Course

Defensive CodingCrash Course

• Why defensive coding

• How to code defensively

• Community trends with best practices

Why Defensive Coding

Why Defensive Coding• Denver Broncos

- 2 recent Super Bowl appearances: 2013 and 2015

- What was the difference?

Why Defensive Coding• Rogue One - The Empire

- Single point of failure

- No encryption of sensitive data

- Missing authentication

- Bad error handling

Why Defensive Coding• The Three R’s:

- Reliability

- Resiliency

- Recoverability

Why Defensive Coding• Reliability

- Predictable behavior

- Likelihood of failure is low

- Achieved by writing resilient code

Why Defensive Coding• Resiliency

- Ability to recover from problems

- How errors are handled

Why Defensive Coding• Resiliency

- Avoid assumptions

Why Defensive Coding• Resiliency

- Use correct data types

- Use type hinting

- Use return types

- Use visibility modifiers

Why Defensive Coding• Resiliency

- function do_something($thing) { $thing->do_ThatThing(); }

- public function doSomething(Thing $thing) : bool{ return $thing->doThatThing(); }

Why Defensive Coding• Recoverability

- Application can come back from crashes and failures

Why Defensive Coding• Recoverability

- Good exception handling

- try { … } catch (SomeException $exception) { … }

- Hope for the best, code for the worst

Why Defensive Coding• Good code qualities

Why Defensive Coding• Good code qualities

- Efficient

‣ High performance

‣ foreach ($array as $thing) { $db = new $Db; $db->update(‘thing’, $thing); }

Why Defensive Coding• Good code qualities

- Efficient

‣ Separation of services

‣ class Pet{ public function walkDog(Dog $dog) {…} public function feedFish(Fish $fish) {…} public function cleanDishes(Dish $dish) {…}}

Why Defensive Coding• Good code qualities

- Efficient

‣ Loosely coupled

‣ protected function driveCar(){ $car = new Car; $driver = new Person; …}

Why Defensive Coding• Good code qualities

- Secure

‣ Strong cryptography

• password_hash and password_verify

‣ Proven approaches to reduce vulnerabilities

‣ Secure architecture

Why Defensive Coding• Good code qualities

- Maintain

‣ Good code organization, file structure, domains

‣ Documentation, doc blocks

‣ Adaptability

Why Defensive Coding• Achieved by practicing effective defensive coding

Why Defensive Coding

How to Code Defensively

How to Code Defensively• Cover a variety of techniques

How to Code Defensively• Attack surfaces • Input validation • Canonicalization • Secure type checking • External library vetting • Cryptographic agility • Exception management • Code reviews • Unit and behavioral testing

How to Code Defensively• Attack surfaces • Input validation • Canonicalization • Secure type checking • External library vetting • Cryptographic agility • Exception management • Code reviews • Unit and behavioral testing

How to Code Defensively• Attack surfaces

- Measurement of exposure of being exploited by threats

- Part of threat modeling - Ability of software to be attacked

How to Code Defensively• Attack surfaces

- Each accessible entry and exit point ‣ Everything in public/ ‣ Every route

- Every feature is an attack vector

How to Code Defensively• Attack surfaces

- Attack surface evaluation ‣ Features that may be exploited ‣ Given a weight based on severity of impact ‣ Controls prioritized based on weight

How to Code Defensively• Attack surfaces

- Relative Attack Surface Quotient (RASQ) ‣ 3 Dimensions

• Targets and Enablers (resources) • Channels and Protocols (communication) • Access Rights (privileges)

How to Code Defensively• Attack surfaces

- High value resources ‣ Data ‣ Functionality

How to Code Defensively• Attack surfaces • Input validation • Canonicalization • Secure type checking • External library vetting • Cryptographic agility • Exception management • Code reviews • Unit and behavioral testing

How to Code Defensively• Input validation

- Source - Type - Format - Length - Range - Values - Canonical

How to Code Defensively• Input validation

- Source ‣ Unsafe superglobals includes $_GET, $_POST,

$_SERVER, $_COOKIE, $_FILES, $_REQUEST ‣ Scrutinize trusted sources ‣ Any user input should be treated as unsafe

How to Code Defensively• Input validation

- Type ‣ is_x functions ‣ Name then all?

How to Code Defensively• Input validation

- Type ‣ is_string($name) ‣ is_int($age) ‣ is_float($percentage) ‣ is_bool($isAccepted) ‣ is_null($questionableThing) ‣ is_array($keyValueData) ‣ is_object($jsonDecoded) ‣ is_resource($fileHandle)

How to Code Defensively• Input validation

- Type ‣ if ($thing instanceof SomeThing) {…}

• class • abstract • interface • trait

How to Code Defensively• Input validation

- Format ‣ Phone number: preg_match(/^\d{10}$/, $phone) ‣ Email address (complicated) ‣ Country code: preg_match(/^[A-Z]{2}$/, $code) ‣ Character patterns

How to Code Defensively• Input validation

- Length ‣ Minimum: strlen($string) >= 5 ‣ Maximum: preg_match(/^[a-zA-Z0-9]{1,10}$/,

$number) ‣ Is it required?

How to Code Defensively• Input validation

- Range ‣ Between 1 and 10: $value >= 1 && $value <= 10 ‣ Date range ‣ AA to ZZ ‣ Start and end values

How to Code Defensively• Input validation

- Values ‣ Whitelist: in_array($checking, [1, 2, 3], true) ‣ Blacklist: !in_array($checking, [‘X’, ‘Y’, ‘Z’]) ‣ Regular expressions ‣ Alphanumeric ‣ Free text ‣ Allowed values

How to Code Defensively• Input validation

- Injection prevention - Malicious

How to Code Defensively• Input validation

- Techniques ‣ Filtration ‣ Sanitization

How to Code Defensively• Input validation

- Techniques ‣ Filtration

• Whitelist and blacklist • Regular expressions with preg_match

• preg_match(/^d{10}$/, $number) • preg_match(/^[a-zA-Z0-9]$/, $string)

How to Code Defensively• Input validation

- Techniques ‣ Filtration

• filter_input(TYPE, $variableName, $filter [, $options])

• boolean false if filter fails • NULL if variable is not set • variable upon success

How to Code Defensively• Input validation

- Techniques ‣ Filtration

• filter_input(INPUT_POST, ‘key’, FILTER_VALIDATE_INT)

• filter_input(INPUT_GET, ‘search’, FILTER_VALIDATE_REGEXP, [‘options’ => [‘regexp’ => ‘/^d{10}$/‘]])

How to Code Defensively• Input validation

- Techniques ‣ Filtration

• filter_var($email, FILTER_VALIDATE_EMAIL) • filter_var($id, FILTER_VALIDATE_INT) • filter_var($bool, FILTER_VALIDATE_BOOLEAN)

How to Code Defensively• Input validation

- Techniques ‣ Sanitization

• Remove unwanted characters or patterns • str_replace([‘ ‘, ‘-‘, ‘(‘, ‘)’], ‘’, $phone) • preg_replace([‘/A/‘, ‘/B/‘, ‘/C/‘], [1, 2, 3],

$subject) • strip_tags($text, ‘<marquee>’)

• Clean up the data

How to Code Defensively• Input validation

- Techniques ‣ Sanitization

• filter_input(INPUT_POST, ‘user_email’, FILTER_SANITIZE_EMAIL)

• filter_input(INPUT_COOKIE, ‘some_url’, FILTER_SANITIZE_URL)

How to Code Defensively• Input validation

- When to validate data ‣ Frontend (client) ‣ Backend (server) ‣ Filter input, escape output

How to Code Defensively• Attack surfaces • Input validation • Canonicalization • Secure type checking • External library vetting • Cryptographic agility • Exception management • Code reviews • Unit and behavioral testing

How to Code Defensively• Canonicalization

- Translating input to a standardized value ‣ Encoding ‣ Character set ‣ Aliases ‣ Alternative spellings, formats

How to Code Defensively• Canonicalization

- Translating input to a standardized value ‣ 2017-08-17 ‣ 8/17/17 ‣ 17/8/17 ‣ Thursday, August 17, 2017

How to Code Defensively• Canonicalization

- Translating input to a standardized value ‣ Yes ‣ On ‣ 1 ‣ true ‣ T

How to Code Defensively• Canonicalization

- Translating input to a standardized value ‣ Free text vs pre-defined choices

• Proper foreign keys in relational data • Utilize database integrity checks and

normalization • Denormalize to an extent for optimizations

How to Code Defensively• Attack surfaces • Input validation • Canonicalization • Secure type checking • External library vetting • Cryptographic agility • Exception management • Code reviews • Unit and behavioral testing

How to Code Defensively• Secure type checking

- Part of Code Access Security (CAS) ‣ Only trusted sources can run application ‣ Prevent trusted sources from compromising

security

How to Code Defensively• Secure type checking

- PHP is a type-safe language - C is not a type-safe language

How to Code Defensively• Secure type checking

- PHP manages memory use for you - C is unmanaged ‣ Susceptible to attacks like buffer overflow

How to Code Defensively• Secure type checking

- Apply PHP security patches - Vet third-party libraries

How to Code Defensively• Attack surfaces • Input validation • Canonicalization • Secure type checking • External library vetting • Cryptographic agility • Exception management • Code reviews • Unit and behavioral testing

How to Code Defensively• External library vetting

- Security - Quality

How to Code Defensively• External library vetting

- Security ‣ Secure implementation ‣ Security audit ‣ Handling security issues ‣ Use trusted projects

How to Code Defensively• External library vetting

- Quality ‣ Unit tests ‣ Actively maintained ‣ Popularity ‣ Ease of use ‣ Coding standards ‣ Community acceptance

How to Code Defensively• Attack surfaces • Input validation • Canonicalization • Secure type checking • External library vetting • Cryptographic agility • Exception management • Code reviews • Unit and behavioral testing

How to Code Defensively• Cryptographic agility

- Ability to stay current

How to Code Defensively• Cryptographic agility

- Use vetted and trusted algorithms - Avoid: ‣ Broken algorithms ‣ Weak algorithms ‣ Custom-made algorithms

• Cryptography is complex, please don’t make your own algorithm

How to Code Defensively• Cryptographic agility

- PHP password_hash and password_verify

How to Code Defensively• Cryptographic agility

- PHP 7.2 includes libsodium in core ‣ Modern security library ‣ Vetted ‣ Passed security audit

- PHP 7.1 deprecated mcrypt ‣ Upgrade to libsodium or openssl

How to Code Defensively• Attack surfaces • Input validation • Canonicalization • Secure type checking • External library vetting • Cryptographic agility • Exception management • Code reviews • Unit and behavioral testing

How to Code Defensively• Exception management

- Handle errors with try/catch blocks ‣ try {...} catch (Exception $e) {…}

How to Code Defensively• Exception management

- Do not display PHP errors except in development environment ‣ dev: display_errors = On ‣ others: display_errors = Off

How to Code Defensively• Exception management

- Log errors and review them actively ‣ dev: error_reporting = E_ALL ‣ prod: E_ALL & ~E_DEPRECATED & ~E_STRICT ‣ E_ALL ‣ E_NOTICE ‣ E_STRICT ‣ E_DEPRECATED

How to Code Defensively• Attack surfaces • Input validation • Canonicalization • Secure type checking • External library vetting • Cryptographic agility • Exception management • Code reviews • Unit and behavioral testing

How to Code Defensively• Code reviews

- Static - Dynamic

How to Code Defensively• Code reviews

- Peers reviewing code changes ‣ Web-based tools ‣ Manual/static code review

- Automatic code review ‣ Commit hooks ‣ Coding standards ‣ Run tests

How to Code Defensively• Code reviews

- Constructive feedback

How to Code Defensively• Code reviews

- Architecture direction

How to Code Defensively• Code reviews

- Coding standards

How to Code Defensively• Code reviews

- Security issues ‣ Cryptographic agility ‣ Injection flaws

- Business rules - Related functionality - Exception handling

How to Code Defensively• Code reviews

- Automatic code reviews ‣ Coding standard enforcement ‣ Run unit and behavioral tests ‣ Continuous integration tools

How to Code Defensively• Code reviews

- Automatic code reviews ‣ Statistics ‣ Security ‣ Design patterns

How to Code Defensively• Attack surfaces • Input validation • Canonicalization • Secure type checking • External library vetting • Cryptographic agility • Exception management • Code reviews • Unit and behavioral testing

How to Code Defensively• Unit and behavioral testing

- Unit tests to ensure logic ‣ PHPUnit

- Behavioral tests to ensure functionality ‣ behat ‣ codeception

How to Code Defensively• Attack surfaces • Input validation • Canonicalization • Secure type checking • External library vetting • Cryptographic agility • Exception management • Code reviews • Unit and behavioral testing

How to Code Defensively• Tips and Tricks

How to Code Defensively• Tips and Tricks

- Hope for the best, plan for the worst

How to Code Defensively• Tips and Tricks

- Abuse cases ‣ Harmful interactions ‣ Help identify threats

- Misuse cases ‣ Inverse of use case ‣ Highlights malicious acts

How to Code Defensively• Tips and Tricks

- Limit class functionality - Limit function lines of code

How to Code Defensively• Tips and Tricks

- Leverage framework functionality - Leverage built-in PHP functionality

How to Code Defensively• Tips and Tricks

- Use type hinting - Use return types - Use correct data types ‣ Bool true or false instead of string ’T' or ‘false’ ‣ Be aware of type casting issues ‣ Use strict type === comparisons when possible ‣ Use is_* checks

How to Code Defensively• Tips and Tricks

- Use database integrity ‣ Have foreign keys ‣ Use correct data types ‣ Normalize data to good level

• Usually 2nd or 3rd level • Beyond that usually slows performance • Denormalize to improve performance but take

up more disk space

How to Code Defensively• Community movements

How to Code Defensively• Community movements

- PHP Standards Recommendations (PSR) ‣ Coding standard and style guide ‣ Autoloading ‣ Caching ‣ HTTP Message Interface

How to Code Defensively• Community movements

- PHP Standards Recommendations ‣ Security issue reporting and handling ‣ Documentation ‣ Extended coding style guide

How to Code Defensively• Community movements

- Security ‣ New OWASP Top 10 ‣ Security at all parts of SDLC ‣ libsodium with PHP 7.2 ‣ Sophisticated attacks ‣ MD5 sunset ‣ IoT

How to Code Defensively• Community movements

- Security ‣ Increasing importance ‣ Good skill to complement development ‣ Core software feature ‣ Investment that can save a project

How to Code Defensively• Community movements

- Conferences help set trends - Magazines focus on topics monthly - Blogs to dispense knowledge - Social media to share ideas - Instant messaging to get live help

How to Code Defensively• Considerations

How to Code Defensively• Considerations

- How could your project be attacked? - What are weak points in your projects?

How to Code Defensively• Considerations

- What will you do differently?

How to Code Defensively• Considerations

- Make a plan - Make a change

How to Code Defensively

How to Code Defensively• Questions?

- Rate on joind.in ‣ https://joind.in/talk/d4c29