PCI Compliance for Hipsters
-
Upload
phillip-jackson -
Category
Software
-
view
659 -
download
0
Transcript of PCI Compliance for Hipsters
PCI Compliance for Hipsters
Or, How I Learned to Stop Worrying and Love Regulatory Compliance
Phillip JacksonMagento Practice Lead, Something Digital
1 — ©2016 Philwinkle LLC SunshinePHP 2016
What this talk is about:· What is PCI?
· Identifying ways that users and programmers can break compliance
· Finding problems before they go to production
· Introducing tools to aide you in your journey
10 — ©2016 Philwinkle LLC SunshinePHP 2016
What this talk is not:· A comprehensive survey of all of PCI
(or any standard)· Every organization is different
· There is no one-size fits all solution· Really has nothing to do with hipsters
11 — ©2016 Philwinkle LLC SunshinePHP 2016
It is a standard created by major credit card issuers,
banks13 — ©2016 Philwinkle LLC SunshinePHP 2016
In case you're bored:tl;dr don't accept payments you don't
have to do any of this!
14 — ©2016 Philwinkle LLC SunshinePHP 2016
About me:· eCommerce developer since ~2000· Magento Developer since late 2007
· I am not a PCI expert· I am a lazy developer
18 — ©2016 Philwinkle LLC SunshinePHP 2016
PCI's 12 step program1
- Install and maintain firewall- Don't use vendor-supplied defaults for system passwords and other security parameters- Protect stored data- Encrypt the transmission of cardholder data and sensitive information across public networks- Use and regularly update antivirus software- Develop and maintain secure systems and applications- Restrict access to data by business need-to-know- Assign a unique ID to each person with computer access- Restrict physical access to cardholder data- Track and monitor all access to network resources and cardholder data- Regularly test security systems and processes- Maintain a policy that addresses information security
1 February 2016 PCI v3.1 https://www.pcisecuritystandards.org/documents/PCIDSSv3-1.pdf
22 — ©2016 Philwinkle LLC SunshinePHP 2016
We're going to talk about 2 of these today- Protect stored data- Develop and maintain secure systems and applications
23 — ©2016 Philwinkle LLC SunshinePHP 2016
What constitutes "stored data" anyways?Writing things to memory (setting them
in a var) is technically "storing" the value
26 — ©2016 Philwinkle LLC SunshinePHP 2016
What constitutes "stored data" anyways?But it is allowed with specific
provisions:- It is **not** stored in non-volatile memory (e.g. Hard drive)
OR
- It **is** stored safely depending on the type of data that it is
27 — ©2016 Philwinkle LLC SunshinePHP 2016
Password � One-way hashCredit Card Number � Strong
EncryptionCVV � Never
28 — ©2016 Philwinkle LLC SunshinePHP 2016
Stored data:The entire 15 or 16 digits of a credit
card number
(The last 4 digits of the card is not considered cardholder data)
Customer authentication credentials (password, auth key, app id,
biometrics)29 — ©2016 Philwinkle LLC SunshinePHP 2016
Safe (Intentional) StorageThe obvious question (in February
2016):Which algo to use?
OWASP suggests use of PBKDF2, bcrypt or scrypt for password storage2
Hashes: Use the built-in password_hash algorithm 2 Magento stores can use PBKDF2 with a module for drop in encryption replacement via PHPCryptLib with https://github.com/ikonoshirt/pbkdf2 by @fabian_ikono
31 — ©2016 Philwinkle LLC SunshinePHP 2016
bad:$password = md5($salt . $_REQUEST['password']);
better:$password = password_hash($_REQUEST['password']);
32 — ©2016 Philwinkle LLC SunshinePHP 2016
Is this storing the card safely?
$ccNumber = $_GET['cc_number'];$payment->setCreditCard($ccNumber);$payment->save();
33 — ©2016 Philwinkle LLC SunshinePHP 2016
A bit better (but increases your burden):
$ccNumber = $helper->encrypt($_GET['cc_number']);$payment->setCreditCard($ccNumber);$payment->save();
34 — ©2016 Philwinkle LLC SunshinePHP 2016
Storage even in volatile memory is still storage, but may not violate PCI.
36 — ©2016 Philwinkle LLC SunshinePHP 2016
There is no way to protect against this in your application:
$ curl --data "cc_number=4111111111111111" yourawesomesite.com
result:$_POST['cc_number'] //bullocks
37 — ©2016 Philwinkle LLC SunshinePHP 2016
This is why the standard dictates things like SSL
...and Antivirus (yes even on your Production hardware)
38 — ©2016 Philwinkle LLC SunshinePHP 2016
Side note: a WAF (web application firewall) is invaluable to your
applicationModSecurity is OSS. If you're on AWS
there is a WAF appliance.
39 — ©2016 Philwinkle LLC SunshinePHP 2016
In general don't do this. You increase your risk and therefore scope. Rather use methods provided by the bank to
store the card with use of a token.
40 — ©2016 Philwinkle LLC SunshinePHP 2016
Proving that developers still have the power to potentially create risky
scenarios. class Payment implements \PaymentInterface{ public function authorizeAndCapture(LoggerInterface $logger) { //log the request son $logger->log($_GET); }
}
42 — ©2016 Philwinkle LLC SunshinePHP 2016
We can guard against those scenarios using interpolation brute force:
class SuperSafeLogger implements \LoggerInterface{ use Psr\Log\LoggerTrait;
public function log($level, $message, array $context = array()); { $message = preg_replace('\d{15,16}','****************', $message); }
}
43 — ©2016 Philwinkle LLC SunshinePHP 2016
Logs usually get backed up or shipped off to another service for analysis. Is
this transfer done via SSL?This can create windows of opportunity
to fall out of compliance.
44 — ©2016 Philwinkle LLC SunshinePHP 2016
So we know how to store things that we expect to contain sensitive data. What about things that we don't expect to
contain a credit card?array(3) { ["firstname"]=> string(7) "Phillip" ["lastname"]=> string(7) "Jackson" ["address"]=> array(5) { ["street1"]=> string(16) "4111111111111111" ["street2"]=> string(0) "234" ["city"]=> string(15) "West Palm Beach" ["region"]=> string(2) "FL" ["postcode"]=> string(5) "33411" }}
45 — ©2016 Philwinkle LLC SunshinePHP 2016
Client-side input validation helps.In this case we can qualify by using the inverse of the filter_var to ensure
fields are not numeric:if(filter_var($street1, FILTER_VALIDATE_INT)){ throw new Exception('!!!!!') }
46 — ©2016 Philwinkle LLC SunshinePHP 2016
At SD we use a number of techniques to ensure compliance:
· Peer review· Mentor review
· Scrutinizer· Unit tests
· Integration tests
50 — ©2016 Philwinkle LLC SunshinePHP 2016
PCI 6.3.2:#1. Code changes are reviewed by
individuals other than the originating code author, and by individuals
knowledgeable about code-review techniques and secure coding
practices.
52 — ©2016 Philwinkle LLC SunshinePHP 2016
PCI 6.3.2:#2. Code reviews ensure code is
developed according to secure coding guidelines
53 — ©2016 Philwinkle LLC SunshinePHP 2016
PCI 6.3.2:#3. Appropriate corrections are implemented prior to release.
54 — ©2016 Philwinkle LLC SunshinePHP 2016
PCI 6.3.2:#4. Code-review results are reviewed
and approved by management prior to release.
55 — ©2016 Philwinkle LLC SunshinePHP 2016
What to focus on in code review?· Don't trust the user
· Don't trust the programmerIn short, filter in, escape out.
56 — ©2016 Philwinkle LLC SunshinePHP 2016
Filter in$unsafe = $_GET['unsafe'];
if(!filter_var($unsafe, FILTER_VALIDATE_INT)){ throw new Exception('¯\_(�)_/¯');}$pdo->bind($query, $unsafe);
Escape outecho $helper->escape($unsafe); //Or just use TWIG.
57 — ©2016 Philwinkle LLC SunshinePHP 2016
In this case filter_var is not just here for the protection of our
application but for the protection of the customer.
58 — ©2016 Philwinkle LLC SunshinePHP 2016
Most XSS attacks come from plain oldrun-of-the-mill echoing $_GET
60 — ©2016 Philwinkle LLC SunshinePHP 2016
PHP CodeSniffer is an invaluable tool for testing code for common issues but
you need a good set of sniffs to find code which breaks from best
practice®™Caution: having the right sniffs is
crucial
63 — ©2016 Philwinkle LLC SunshinePHP 2016
ugly.php:<?php//let's introduce an XSSecho $_GET['unsafe'];?>
64 — ©2016 Philwinkle LLC SunshinePHP 2016
Output of PHPCS default:FILE: /Users/pjackson/ugly.php----------------------------------------------------------------------FOUND 1 ERROR AFFECTING 1 LINE---------------------------------------------------------------------- 2 | ERROR | Missing file doc comment----------------------------------------------------------------------
Time: 47ms; Memory: 3Mb
65 — ©2016 Philwinkle LLC SunshinePHP 2016
I prefer to use the default Magento ECG ruleset with Magento:
phpcs --standard=vendor/magento-ecg/coding-standard/Ecg/ ugly.php
results in
FILE: /Users/pjackson/Desktop/xss-vuln/ugly.php----------------------------------------------------------------------FOUND 1 ERROR AND 1 WARNING AFFECTING 1 LINE---------------------------------------------------------------------- 4 | WARNING | Use of echo language construct is discouraged. 4 | ERROR | Direct use of $_GET Superglobal detected.----------------------------------------------------------------------
Time: 43ms; Memory: 2.75Mb
66 — ©2016 Philwinkle LLC SunshinePHP 2016
Gulp is a task runner. We use it to automate all kinds of things.
Specifically to run audit tools to catch mistakes before they make it up to git.
(Because Scrutinizer is slow !)
69 — ©2016 Philwinkle LLC SunshinePHP 2016
In gulpfile.js:gulp.task('default', function() { gulp.watch('src/**/*.php').on('change', function(file) { gulp.src(file.path) .pipe(phpcs({ bin: '/usr/local/bin/phpcs', standard: 'vendor/magento-ecg/coding-standard/Ecg/', warningSeverity: 0 })) .pipe(notify()); });});
70 — ©2016 Philwinkle LLC SunshinePHP 2016
Breakdown· We create a watch task for all PHP files
· When a PHP file is changed we send that file to PHPCS
· We run PHPCS with the ECG standard (mentioned earlier)
· We can optionally choose to use a system notification on error
71 — ©2016 Philwinkle LLC SunshinePHP 2016
Even better is FloeDesignTechnologies/phpcs-security-audit:
--------------------------------------------------------------------------------FOUND 1 WARNING(S) AFFECTING 1 LINE(S)-------------------------------------------------------------------------------- 6 | WARNING | Possible XSS detected with . on echo
73 — ©2016 Philwinkle LLC SunshinePHP 2016
CasperJS is a headless Webkit scriptable with a Javscript API.
Casper is good at navigating pages and submitting forms.
76 — ©2016 Philwinkle LLC SunshinePHP 2016
XSS Sniffingcasper.start('http://127.0.0.1:8080/search.php', function() { this.fill('form#search', { 'searchTerm': '<script>alert(1);</script>' }, true);});
casper.then(function() { this.evaluateOrDie(function() { return /<script/.test(document.body.innerText); }, 'XSS Vulnerability detected');});
77 — ©2016 Philwinkle LLC SunshinePHP 2016
gulp.task('xss', function() { var casper = require('casper').create(); casper.userAgent('Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36...blahblah'); casper.start();
casper.start('http://127.0.0.1:8080/search.php', function() { this.fill('form#contact-form', { 'searchTerm': '<script>alert(1);</script>' }, true); });
casper.then(function() { this.evaluateOrDie(function() { return /<script/.test(document.body.innerText); }, 'XSS Vulnerability detected'); })});
79 — ©2016 Philwinkle LLC SunshinePHP 2016
To put this in perspective this can be the type of break you may not find through peer review and may only
discover when your PCI audit tool is running in production.
80 — ©2016 Philwinkle LLC SunshinePHP 2016
Consider this code (don't ever do this):function request(){ foreach($_test as $key=>$var){ yield [$var=>$key]; }}
Later:foreach(request() as $pairs){ echo $pairs['unsafe'];}
81 — ©2016 Philwinkle LLC SunshinePHP 2016
There are a number of tools in the frontend ops stack today that can
assist creating secure code.
83 — ©2016 Philwinkle LLC SunshinePHP 2016
PCI Compliant code (or any standards compliant code) can still be susceptible
to attack.
84 — ©2016 Philwinkle LLC SunshinePHP 2016