Top 5 Magento Secure Coding Best Practices
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
408
On Slideshare
318
From Embeds
90
Number of Embeds
3

Actions

Shares
Downloads
3
Comments
0
Likes
1

Embeds 90

http://www.slideee.com 86
https://twitter.com 3
http://www.linkedin.com 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Top 5 Magento Secure Coding Best Practices Alex Zarichnyi, Magento ECG
  • 2. Security in Magento • Dedicated team
  • 3. Security in Magento • Dedicated team • External audits
  • 4. Security in Magento • Dedicated team • External audits • Awareness about OWASP Top 10
  • 5. Security in Magento http://magento.com/security • Bug bounty program • Dedicated team • External audits • Awareness about OWASP Top 10 up to $10.000
  • 6. Security in Magento • Built-in security mechanisms • Bug bounty program • Dedicated team • External audits • Awareness about OWASP Top 10
  • 7. Top 5 Secure Coding Practices
  • 8. #1. Validate input as strictly as possible
  • 9. Input Validation Do not trust: • all input parameters • cookie names and values • HTTP header content • Some $_SERVER parameters (e.g. HTTP_X_FORWARDED, HTTP_X_FORWARD ED_FOR)
  • 10. Zend_Validate • Alpha-numeric values • Credit Carts • Host names • IPs • Custom validators (Mage_Core_Model_Url_Validator) • and many more
  • 11. $attributeCode = $this->getRequest()->getParam('attribute_code'); $validator = new Zend_Validate_Regex(array( 'pattern' => '/^[a-z][a-z_0-9]{1,254}$/')); if (!$validator->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 }
  • 12. $email = $this->getRequest()->getParam('email'); if (Zend_Validate::is($email, 'EmailAddress')) { //continue execution } else { $this->_getSession()->addError($this->__('Invalid email address.')); //redirect back } Validate email
  • 13. #2. Use parameterized queries (?, :param1)
  • 14. Working with Data in Magento $id = $this->getRequest()->getParam(‘id’); $model->load($id); $q = $this->getRequest()->getParam(‘q’); $collection->addFieldToFilter(‘name’, ‘%’ . $q . ‘%’)); secure secure
  • 15. $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';
  • 16. $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 customer_entity;
  • 17. $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
  • 18. #3. Escape user input
  • 19. 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($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
  • 20. Mage::helper(‘core’)->escapeHtml($data, $allowedTags = null) Mage_Core_Block_Abstract::escapeHtml($data, $allowedTags = null) String Replacement & &amp; " &quot; ' &#039; < &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
  • 21. #4. Use CSRF tokens (form keys)
  • 22. <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
  • 23. #5. Use security headers
  • 24. 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'
  • 25. /** * 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’); }
  • 26. 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
  • 27. zlik ozarichnyi@ebay.com linkedin.com/in/ozarichnyi Дякую!