Secure Zend Framework programing in ZF2

Comments on this webinar:

What are the most common security risks?

OWASP Top 10 Application Security Risks – 2010

A1-Injection Injection flaws, such as SQL, OS, and LDAP injection, occur when untrusted data is sent to an interpreter as part of a command or query. The attacker’s hostile data can trick the interpreter into executing unintended commands or accessing unauthorized data.
A2-Cross Site Scripting (XSS) XSS flaws occur whenever an application takes untrusted data and sends it to a web browser without proper validation and escaping. XSS allows attackers to execute scripts in the victim’s browser which can hijack user sessions, deface web sites, or redirect the user to malicious sites.
A3-Broken Authentication and Session Management Application functions related to authentication and session management are often not implemented correctly, allowing attackers to compromise passwords, keys, session tokens, or exploit other implementation flaws to assume other users’ identities.
A4-Insecure Direct Object References A direct object reference occurs when a developer exposes a reference to an internal implementation object, such as a file, directory, or database key. Without an access control check or other protection, attackers can manipulate these references to access unauthorized data.
A5-Cross Site Request Forgery (CSRF) A CSRF attack forces a logged-on victim’s browser to send a forged HTTP request, including the victim’s session cookie and any other automatically included authentication information, to a vulnerable web application. This allows the attacker to force the victim’s browser to generate requests the vulnerable application thinks are legitimate requests from the victim.
A6-Security Misconfiguration Good security requires having a secure configuration defined and deployed for the application, frameworks, application server, web server, database server, and platform. All these settings should be defined, implemented, and maintained as many are not shipped with secure defaults. This includes keeping all software up to date, including all code libraries used by the application.
A7-Insecure Cryptographic Storage Many web applications do not properly protect sensitive data, such as credit cards, SSNs, and authentication credentials, with appropriate encryption or hashing. Attackers may steal or modify such weakly protected data to conduct identity theft, credit card fraud, or other crimes.
A8-Failure to Restrict URL Access Many web applications check URL access rights before rendering protected links and buttons. However, applications need to perform similar access control checks each time these pages are accessed, or attackers will be able to forge URLs to access these hidden pages anyway.
A9-Insufficient Transport Layer Protection Applications frequently fail to authenticate, encrypt, and protect the confidentiality and integrity of sensitive network traffic. When they do, they sometimes support weak algorithms, use expired or invalid certificates, or do not use them correctly.
A10-Unvalidated Redirects and Forwards Web applications frequently redirect and forward users to other pages and websites, and use untrusted data to determine the destination pages. Without proper validation, attackers can redirect victims to phishing or malware sites, or use forwards to access unauthorized pages.


“Filter input, escape output”
Yest, but it’s not enough.

Security tools in ZF2

  • ZendAuthentication
  • ZendPermissions
  • ZendFilter
  • ZendValidator
  • ZendInputFilter
  • ZendEscaper
  • ZendCaptcha
  • ZendCrypt
  • ZendMath



    API for authentication and includes concrete authentication adapters for common use case scenarios:

    • Database table
    • Digest
    • HTTP
    • LDAP
    • Or your custom authentication adapter…

    Example of ZendAuthentication use:

      use ZendAuthenticationAuthenticationService;$auth = new AuthenticationService();$authAdapter = new MyAuthAdapter($username, $password);if(!$result->isValid()){//auth failedvar_dump($result->getMessages());}else{//auth success, $username is stored in the session}


      Proviedes access control list (ACL) for privileges management

      • Resource: An object which access is controlled
      • Role: An object that may request access to a resource.

      Example of ZendPermissions use:

      use ZendPermissionsAclAcl;use ZendPermissionsAclRoleGenericRole as Role;use ZendPermissionsAclResourceGenericResource as Resource;$acl = new Acl();$acl->addRole(new Role('guest'));    ->addRole(new Role('member'));    ->addRole(new Role('admin'));$parents = array('guest', 'member', 'admin');$acl->addRole(new('someUser'), $parents);$acl->addResource(new Resource('someResource'));$acl->deny('guest', 'someResource');$acl->deny('member', 'someResource');echo $acl->isAllowed('someUser', 'someResource')? 'allowed' : 'denied';

      ZendPermissionsRbac adapter in ZF2.1 is a new Role-Based Access Control based in PHP 5.3 SPL RecursiveIterator. It put emphasis on roles and their permissions rather than resource objects:

      • identity: one or more roles
      • role: requests acces to a permission
      • permission is givet to a role.



      Provides a set of commonly needed data filters and a chainging mechanism by which multiple filters may be applied.

      Standard Filter Classes…

      • Alnum
      • Alpha
      • BaseName
      • Boolean
      • Compress/Decompress
      • Digits
      • Dir
      • Encrypt/Decrypt
      • HtmlEntities
      • Int
      • Null
      • NumberFormat
      • PregReplace
      • RealPath
      • StringToLower/ToUpper
      • StringTrim
      • StripNewLines/Tags
      • Callback (custom filter)



      Provides a set of commonly needed validators and a validator chainging mechanism by which multiple validators may be applied.

      It examines its input with respecto to requirements and
      productes a boolean result whether the input successfully validates against the requirements.

      $validator = new ZendValidatorEmailAddress;
      if(!$validator->isValid($email)){//valid email}else{//print reasons email is invalidvar_dump($validator->getMessages());}


      Standard Validator Classes…

      • Alnum
      • Alpha
      • Barcode
      • Between
      • CreditCard
      • Date
      • DbRecordExists and NoRecordExists
      • Digits
      • EmailAddress
      • GreaterThan/LessThan
      • Hex
      • Hostname
      • Iban
      • Identical
      • InArray
      • Ip
      • Isbn
      • NotEmpty
      • PostCode
      • Regex
      • Sitemap
      • Step
      • StringLength
      • Callback (custom filter)



      Can be used to filter and validate generic sets of input data. For instance $_GET, $_POST, CLI, etc

      use ZendInputFilterInputFilter;use ZendInputFilterInput;use ZendValidator;$email = new Input('email');$email->getValidatorChain()  ->addValidator(new ValidatorEmailAddress());$password = new Input('password');$password ->getValidatorChain()  ->addValidator(new ValidatorStringLength(8));$inputFilter = new InputFilter();$inputFilter->add($email)            ->add($password)            ->setData($_POST);if(!$inputFilter->isValid()){//form is valid}else{//print reasons form is invalidvar_dump($inputFilter->getInvalidInput());}




      Always escape the output, multiple formats:

      • escapeHtml()
      • escapeHtmlAttr()
      • escapeJs()
      • escapeUrl()
      • EscapeCss()


      Prevent submision from automated tools (Figlet, AbstractWord, Dumb, Image, ReCaptcha)

      $captcha = new ZendCaptchaFiglet(array( 'name=>'foo', 'wordLen'=>6, 'timeout'=>300,));$id = $captcha->generate();echo $captcha->getFiglet()->render($captcha->getWord());//On subsequent requestif($captcha->isValid($_POST['foo'], $_POST)){  //validated}



      Use cryptography in a convenient way (instead of php built-in functions and extensions crypt, mcrypt, openssl, hash, mhash):

      • ZendCryptPassword
      • ZendCryptKeyDerivation
      • ZendCryptSymmetric
      • ZendCryptPublicKey
      • ZendCryptHash
      • ZendCryptHmac
      • ZendCryptBlockCipher

      Example of how to encrypt sensitive data:

      • ZendCryptBlockCipher symmetric encryption and authenication (HMAC)
      • Simplified API: setKey($key), encrypt($data), decrupt($data) uses Mcrypt adapter (Zend CryptSymmetricMcrypy) for us.
      • Defult values used by BlockCipher:
        • AES (256 bits key)
        • CBC mode + HMAC (SHA-256)
        • PKCS6 padding mode (RFC 5652)
        • PBKDF2 to generate encryption key + auth key for HMAC
        • Random IV for each encryption

      BlockCipher using AES encryption

      use ZendCryptBlockCipher;$cipher = BlockCipher::factory(  'mcrypt',   array('algorithm' => 'aes'));$cipher->setKey('this is the encryption key');$plaintext = 'This is the sensitive message to encrypt';//encoded base64, get binary using setBinaryOutput(true)$encrypted = $cipher->encrypt($plaintext);// You will see three parts: HMAC, IV and ciphertextprintf("encrypted text: %sn", $encrypted); file_put_contents('test.crypt',  $encrypted);


      BlockCipher decryption

      use ZendCryptBlockCipher;$cipher = BlockCipher::factory(  'mcrypt',   array('algorithm' => 'aes'));$cipher->setKey('this is the encryption key');$encrypted = file_get_contents('test.crypt');$plaintext = $cipher->decrypt($encrypted );printf("Dencrypted text: %sn", $plaintext );


      Example of how to store a password:

      Insecure, old school: MD5 password or/and salt random string (In a 4 core CPU you can break md5 8 char passwords in less than 2 hours)

      New way: bcrypt (Blowfish cipher is secure way now)

      bcrypt is secure because is very slow and attacks need huge amount of time to be completed (cost value determine how expensive is bcrypt, by default 14 that is equivalent to 1 second of computation using Core i5 CPU at 3.3Ghz.. Check taht your system use at least 1 second)

      Example of how to encrypt the password with bcrypt:

      use ZendCryptPasswordBcrypt;$bcrypt = new Bcrypt();$start = microtime(true);$hash =$bcrypt->create('password');$end = microtime(true);printf("Hash      : %s, %hash); //string of 60 bytesprintf("Exec. time: %.2fn", $end-$start);


      To check if password the user is valid, you verify them using the hash:

      $is_valid = bcrypt::verify($password, $hash)



      PHP generate pseudo-random values but they are not good for cryptography purposes.

      You can get secure random numbers in PHP if you have openssl PHP extension:


      Zend use most secure available function at the moment, never PHP primitives if $strong=true.

      ZendMathMath:randBytes($lenggth, $strong=false)

      ZendMathMath:rand($min, $max, $strong=false)



      Etiquetes: , , ,

      Deixa un comentari

      Fill in your details below or click an icon to log in: Logo

      Esteu comentant fent servir el compte Log Out /  Canvia )

      Google+ photo

      Esteu comentant fent servir el compte Google+. Log Out /  Canvia )

      Twitter picture

      Esteu comentant fent servir el compte Twitter. Log Out /  Canvia )

      Facebook photo

      Esteu comentant fent servir el compte Facebook. Log Out /  Canvia )


      S'està connectant a %s

      %d bloggers like this: