Defensive Coding Crash Course - ZendCon 2017
-
Upload
mark-niebergall -
Category
Software
-
view
260 -
download
0
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