Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Security::htmlentities() is not working.
  • Hi,

    What I am doing is getting my Security::htmlentities(Input::get('post')) content and save it to the database, then in the other controller I retrieve the data from the database:

    $data = array(
    [..]
    'post' => Security::htmlentities($post),
    );

    And passing it to my view like:

    return Response::forge(View::forge('other/view", $data));

    In the results, the $post variable HTML content is not being escaped and I see fe. (bolded) text instead of the <strong>text</strong>.

    When I do replace the both above System::htmlentities() with the htmlspecialchars() its working.
  • Couple of weird things going on here.

    Input::get('post')

    suggests you're having a URL variable called "post". Then you say "$post variable HTML content", suggesting that the URL variable contained HTML? That sounds quite odd to me.

    And how many times do you want to encode? Now you are encoding on:
    - URL variable to database
    - database to $data array
    - $data array to View (Fuel does this automatically, always)

    Given the fact that in step 3 there is encoding, the other two steps are not needed. If you would use

    $data = array(
        [..]
        'post' => '<strong>text</strong',
    );

    you would still see the HTML as text in your view output.
  • If that doesn't happen, you haven't configured your app properly.

    You need your security filters in your app/config.php. This is mine:

        /**
         * Security settings
         */
        'security' => array(
            'csrf_autoload'    => false,
            'csrf_token_key'   => 'fuel_csrf_token',
            'csrf_expiration'  => 0,
            'uri_filter'       => array('htmlentities'),

            /**
             * This input filter can be any normal PHP function as well as 'xss_clean'
             *
             * WARNING: Using xss_clean will cause a performance hit.  How much is
             * dependant on how much input data there is.
             */
            'input_filter'  => array(),

            /**
             * This output filter can be any normal PHP function as well as 'xss_clean'
             *
             * WARNING: Using xss_clean will cause a performance hit.  How much is
             * dependant on how much input data there is.
             */
            'output_filter'  => array('Security::htmlentities'),

            /**
             * Whether to automatically filter view data
             */
            'auto_filter_output'  => true,

            /**
             * With output encoding switched on all objects passed will be converted to strings or
             * throw exceptions unless they are instances of the classes in this array.
             */
            'whitelisted_classes' => array(
                'Fuel\\Core\\Response',
                'Fuel\\Core\\View',
                'Fuel\\Core\\ViewModel',
                'Closure',
            )
        ),
  • Okay, I have edited the security config (actually I just had to enable the 'auto_filter_output' becuse had it disabled). Removed all of the filters, saved my string once again to the database and it seems like its not working yet: http://i.imgur.com/XYBN9Lx.png
  • And you do have this bit?

    'output_filter'  => array('Security::htmlentities'),

    if not, nothing will happen...
  • Sure. IIRC this is the default Fuel's configuration set.

    Here is my security array configuration: http://bin.fuelphp.com/snippet/view/ym/Od2Tsai89IM5hvxmqg9F
  • By default (i.e. no config in app), there is NO output filter active. You have to define one in your config (and Security will complain if you don't).

    That config looks ok, so I don't see why the HTML won't be escaped. Have you tried my example, and just passed a HTML string to the View, and see if that works?
  • Yes, I have set the $data['test'] = '<strong>text</strong>';

    and in the view: <?= $test ?> outputs bolded text.
  • I can not reproduce it.

    Here, on a fresh install of 1.8/develop, it displays "<strong>text</strong>" and not "text" in bold.
  • I'm using the latest stable version which is 1.7.1 

  • HarroHarro
    Accepted Answer
    No difference on 1.7.1.

    In the controller:

        public function action_index()
        {
            return Response::forge(View::forge('welcome/index', array('test' => '<b>TEST</b>')));
        }

    In the View:

                <h1>Welcome! <?= $test ?></h1>

    Result:

    http://imgur.com/SSRAaWL
  • I have no idea what happend then. Does the View_Smarty escape the HTML as well as in View?

    Maybe you know where (in which file) Fuel's rendering the output and escape the HTML?
  • The variables are escaped in View::get_data(), which is called in the closure in View::render() which includes the view file and passes the variables on.

    View_Smarty uses

    $parser->assign($this->get_data());

    so it also fetched the cleaned data before assigning it to the template.
  • I think I know why it doesnt works. I am using the Smarty in one file (index.tpl) which is loading the each controller view output and passing it to the smarty view in the {$content} variable... I think I have made it wrong way.

    Please, could we meet on IRC or something like that? 
  • My Smarty is extremely rusty, haven't used it in 4-5 years.

    Pop in and check if I'm online, I'm at GMT+1, but rather busy during the day.
  • I have rewritten my Smarty implementation code and seems, like its working now :).

    --

    Now I know that when passing the data to the view, it does get filtered and escaped by default, is there a way to skip the escaping in certain cases? Sometime I do prepare my HTML in the controller file, thats why I wonder, and yes, I know I can just pass the third `false` argument but I am looking for some other way because at certain cases I would need to pass HTML and escape it. Would I have to still pass the third argument to the View::forge, but then use the Security:;htmlentities on the passing argument instead? 

    Thank you for your time Harro!

    Regards
  • If it's an object, you can whitelist it (which should be done with caution, as it whitelists all instances, and all data inside the instance!).

    If it's a Model_Crud or ORM model object, you can add custom encoding rules to them, which allows you to deal with field contents at a more granular level (i.e. escape every value except the column that contains HTML). In other words, they can encode themselfs when requested by the View.

    Otherwise you can use the set() method with false as third parameter, or the set_safe() method (which is a set with implied false).
  • Thank you so much!

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion