Top 5 magento secure coding best practices Alex Zarichnyi

3,811 views

Published on

Top 5 magento secure coding best practices

Published in: Technology
2 Comments
4 Likes
Statistics
Notes
  • Slide 23: Is there a way to perform the _validateFormKey() function in a non-magento page (a php form-handler located in the root magento folder)? More info on the question here: http://stackoverflow.com/questions/36019881/how-to-add-csrf-to-a-custom-front-end-magento-form-not-using-controller
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • I would also recommend installing Magento security extension http://www.magentocommerce.com/magento-connect/magesecure-security-extension.html
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
3,811
On SlideShare
0
From Embeds
0
Number of Embeds
297
Actions
Shares
0
Downloads
44
Comments
2
Likes
4
Embeds 0
No embeds

No notes for slide

Top 5 magento secure coding best practices Alex Zarichnyi

  1. 1. Top 5 Magento Secure Coding Best Practices Alex Zarichnyi, Magento ECG
  2. 2. About Me zlik ozarichnyi@ebay.com linkedin.com/in/ozarichnyi From Magento ECG
  3. 3. Security in Magento • Dedicated team
  4. 4. Security in Magento • Dedicated team • External audits
  5. 5. Security in Magento • Dedicated team • External audits • Awareness about OWASP Top 10
  6. 6. Security in Magento http://magento.com/security • Bug bounty program • Dedicated team • External audits • Awareness about OWASP Top 10 up to $10.000
  7. 7. Security in Magento • Built-in security mechanisms • Bug bounty program • Dedicated team • External audits • Awareness about OWASP Top 10
  8. 8. Top 5 Secure Coding Practices
  9. 9. #1. Validate input as strictly as possible
  10. 10. Input Validation Do not trust: • all input parameters • cookie names and values • HTTP header content (X-Forwarded-For)
  11. 11. Blacklist vs. Whitelist Validation ‘ 1=1 <script></script> ^d{5}(-d{4})?$ ^(AA|AE|AP|AL|AK|AS|AZ|AR|CA|CO|CT|DE|D C|FM|FL|GA|GU| HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI| MN|MS|MO|MT|NE| NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW |PA|PR|RI|SC|SD|TN| TX|UT|VT|VI|VA|WA|WV|WI|WY)$ Zip Code U.S. State O’Brian <sCrIpT></sCrIpT> Attack patterns What if?
  12. 12. Zend_Validate • Alnum values • Credit Carts • Host names • IPs • Custom validators (Mage_Core_Model_Url_Validator) • and many more
  13. 13. $email = $this->getRequest()->getParam('email'); if (!empty($email) && Zend_Validate::is($email, 'EmailAddress')) { //continue execution } else { $this->_getSession()->addError($this->__('Invalid email address.')); } Validate email
  14. 14. $attributeCode = $this->getRequest()->getParam('attribute_code'); $validator = new Zend_Validate_Regex(array( 'pattern' => '/^[a-z][a-z_0-9]{1,254}$/')); if (!$validato->isValid($attributeCode)) { //stop execution and add a session error } Validate attribute code 1. 2. $attributeCode = $this->getRequest()->getParam('attribute_code'); $validatorChain = new Zend_Validate(); $validatorChain->addValidator(new Zend_Validate_StringLength( array('min' => 1, 'max' => 254))) ->addValidator(new Zend_Validate_Alnum()); if (!$validatorChain->isValid($attributeCode)) { //stop execution and add a session error }
  15. 15. #2. Use parameterized queries (?, :param1)
  16. 16. $select->where("region.code = '{$requestParam}'"); $res = $this->_getReadAdapter()->fetchRow($select); $select->where('region.code = ?', $requestParam); $res = $this->_getReadAdapter()->fetchRow($select); Bad code Good code 1. $select->where('region.code= :regionCode'); $bind = array('regionCode' => $requestParam); $res = $this->getReadAdapter()->fetchRow($select, $bind)); 2. name' ); UPDATE admin_user SET password = '34e159c98148ff85036e23986 6a8e053:v6' WHERE username = 'admin';
  17. 17. $select->joinInner( array('i' => $this->getTable('enterprise_giftregistry/item')), 'e.entity_id = i.entity_id AND i.item_id = ' . $requestParam, array() ); $select->joinInner( array('i' => $this->getTable('enterprise_giftregistry/item')), 'e.entity_id = i.entity_id AND i.item_id = ' . (int) $requestParam, array() ); Bad code Good code 1; DROP TABLE aaa_test;
  18. 18. $result = "IF (COUNT(*) {$operator} {$requestParam}, 1, 0)"; $select->from( array('order' => $this->getResource()->getTable('sales/order')), array(new Zend_Db_Expr($result) ); $value = $select->getAdapter()->quote($requestParam); $result = "IF (COUNT(*) {$operator} {$value}, 1, 0)"; $select->from( array('order' => $this->getResource()->getTable('sales/order')), array(new Zend_Db_Expr($result)) ); Bad code Good code
  19. 19. #3. Escape user input
  20. 20. SQL Query Parameters Escaping $db->quoteInto("WHERE date < ?", "2005-01-02") WHERE date < '2005-01-02’ Zend_Db_Adapter_Abstract quote($value, $type = null) quoteInto($text, $value, $type = null, $count = null) quoteIdentifier(quoteIdentifier($ident, $auto=false) quoteColumnAs($ident, $alias, $auto=false) quoteTableAs($ident, $alias = null, $auto = false) $db->quote("O'Reilly"); O'Reilly $db->quote("' or '1'='1' -- “, Zend_Db::FLOAT_TYPE); 0.000000
  21. 21. Mage::helper(‘core’)->escapeHtml($data, $allowedTags = null) Mage_Core_Block_Abstract::escapeHtml($data, $allowedTags = null) String Replacement & &amp; " &quot; ' ' < &lt; > &gt; HTML Special Characters Escaping https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet Never insert untrusted data except in allowed locations Use both on frontend & backend
  22. 22. #4. Use CSRF tokens (form keys)
  23. 23. <form name="myForm" id="myForm" method="post" action="..."> <?php echo $this->getBlockHtml('formkey')?> <!-- ... --> </form> public function saveAction() { if (!$this->_validateFormKey()) { //stop and throw an exception or redirect back } } <input type="hidden" value="Bcp957eKYP48XL0Y" name="form_key"> in template in controller
  24. 24. #5. Security headers
  25. 25. HTTP security headers https://www.owasp.org/index.php/List_of_useful_HTTP_headers Header Description Example X-XSS-Protection Protects from XSS X-XSS-Protection: 1; mode=block X-Frame-Options Protects from Clickjacking X-Frame-Options: deny X-Content-Type- Options Prevents Internet Explorer and Google Chrome from MIME- sniffing a response away from the declared content-type X-Content-Type-Options: nosniff Content-Security- Policy, X-WebKit-CSP Lets you specify a policy for where content can be loaded Lets you put restrictions on script execution X-WebKit-CSP: default-src 'self'
  26. 26. /** * Add security headers to the response * * @listen controller_action_predispatch * @param Varien_Event_Observer $observer */ public function processPreDispatch(Varien_Event_Observer $observer) { $response = $observer->getControllerAction()->getResponse(); $response->setHeader(‘X-XSS-Protection’, ‘1; mode=block’) ->setHeader(‘X-Frame-Options’, ‘DENY’) ->setHeader(‘X-Content-Type-Options’, ‘nosniff’); }
  27. 27. Additional Resources • https://www.owasp.org – The Open Web Application Security Project • http://websec.io/ – Securing PHP-based applications • http://cwe.mitre.org/ – Common Weakness Enumeration • https://www.youtube.com/watch?v=aGnV7P8NXtA –Magento Security Presentation, Imagine 2012 • http://www.developers-paradise.com/wp- content/uploads/eltrino-paradise-2013-roman_stepanov.pdf - Magento Security and Vulnerabilities Presentation, Magento Developer Paradise 2013
  28. 28. Q&A

×