Prevent XSS (Zend Framework 2 and Doctrine 2 Stack)

XSS Attack (Also known as Cross-site script­ing ) enables hack­er to inject mali­cious javascript code in your web appli­ca­tion. If you are tak­ing input from user in your web appli­ca­tion then your Web Appli­ca­tion can be XSS Vul­ner­a­ble.

How It works:

Your appli­ca­tion takes input from user and stores it to data­base (or any­where else) and then on anoth­er page you are dis­play­ing that data to anoth­er user , In this case sup­pose if user enters any javascript code (for exam­ple ) as input then this code will direct­ly go to data­base as it is, and then while dis­play­ing it will echo that  as it is, and brows­er will treat it as a javascript as it have

How to pre­vent XSS:

You can either fil­ter the code at out­put end or at input end.

For Input End :

For any exist­ing or ful­ly  devel­oped appli­ca­tion this is the best way ( for new appli­ca­tion as well ) Cause there are only few points of con­trol while insert­ing data (for exam­ple exchangeAr­ray() func­tion in zend) , In our appli­ca­tion we were using ZendFramework2 + Doc­trine 2.2 , so all data which we are sav­ing to DB was pass­ing through Doc­trine, so it is the smart choice to imple­ment a fil­ter at Doc­trine end By tak­ing advan­tage of doc­trine hooks.

How?

Approach 1:

Most of the appli­ca­tion archi­tect cre­ates an AbstractEn­ti­ty , it  is the doc­trine Enti­ty class, which is par­ent of all oth­er Enti­ty class­es in the appli­ca­tion, (you can write com­mon prop­er­ty here like update_date,delete_flag etc) . If you dont have cre­ate one.

And in this AbstractEn­ti­ty class we will add a doc­trine hook pre­Flush , and then -

 

This pre­Flush  hook will be called auto­mat­i­cal­ly when you flush any enti­ty object, We have access over enti­ty object via $this , and we are get­ting its all meth­ods, then we are fil­ter­ing just get­ters, and then we are tak­ing their val­ue and pass­ing through html­spe­cialchars func­tion and then again set­ting it and then just return­ing that enti­ty, sim­ple as that.

Now your all data which we are stor­ing is html spe­cial char encod­ed and safe for echo­ing. If you need to save html data in data­base for any case then add con­di­tions in this hook it will work.

 

Approach 2:

Use any appli­ca­tion fire­wall like NAXSI , it will pre­vent all Seri­ous XSS attack and also secure your appli­ca­tion from oth­er attacks like sql injec­tions , this is mod­ule of Nginx you can learn more about it here —  NAXSI

In lat­est browsers there is a new fea­ture named XSS-Pro­tec­tion, You just have to enable it from your request head­er -

It works on client‘s brows­er and pre­vent from var­i­ous xss attack. Read More about it here
You can apply both approach to secure your appli­ca­tion from XSS.

 

 

For out­put end: just fil­ter your each php vari­able with html­spe­cialchars() 🙂

vivek

Web Developer & Server Admin, Skilled in Java , PHP , LAMP, Tomcat, Mongo DB & SQL. Available for freelancing project or Open Source Contribution, Feel free to contact me at contact@viveksoni.net .

You may also like...

  • Shaun

    As a note, I came across a few improve­ments for approach 1.:
    — I want­ed to inher­it off anoth­er enti­ty, whilst still pro­vid­ing the func­tion­al­i­ty I required. A trait imple­ment­ed this nice­ly.
    — The fil­ter­En­ti­ty can be short­ened down to one line with a return.
    — The prop­er­ty­set­ter should check if the method exists, as it is not uncom­mon to pro­vide addi­tion­al get­ters that add addi­tion­al func­tion­al­i­ty to the out­put.

    The result is as fol­lows:

    trait XSSPro­tect
    {
    /**
    * Hooks for pre­Flush
    * To pre­vent XSS attack we are fil­ter­ing each string prop­er­ty and pass­ing those string to strip_tags
    *
    * @link https://viveksoni.net/prevent-xss-zend-framework-2-and-doctrine-2-stack
    *
    * @ORMPrePersist
    * @ORMPreUpdate
    *
    * @return $this
    */
    pub­lic func­tion xssPro­tect()
    {
    $class_methods = get_class_methods($this);
    $prop­er­ties = array_filter($class_methods, array($this, ‘fil­ter­En­ti­ty’));

    fore­ach( $prop­er­ties as $prop­er­ty ){
    $val­ue = $this->$property();

    if( is_string($value) ){
    $prop­er­ty­Set­ter = ‘set’ . substr($property, 3);

    // Ensure the method exists.
    if ( method_exists($this, $prop­er­ty­Set­ter) ) {
    $val­ue = html_entity_decode($value, ENT_COMPAT);
    $val­ue = strip_tags($value);

    $this->$propertySetter($value);
    }
    }
    }
    return $this;
    }

    /**
    * This func­tion is not relat­ed to doc­trine any­how, it checks that whether input string
    * have “get” In it or not, if have return true.
    *
    * @link https://viveksoni.net/prevent-xss-zend-framework-2-and-doctrine-2-stack
    *
    * @param $val­ue
    * @return bool
    */
    pub­lic func­tion filterEntity($value){
    return strpos($value, ‘get’) !== false;
    }
    }