1
\$\begingroup\$

I have started to implement cross site scripting prevention (xss) within my code.

However as I am using symfony for this particular project I have read up that nothing needs to be done for xss in symfony as it is already protected from it, is this case?

If this is not the case I want to make sure that the code I have written below if sufficient enough to protect from xss. Or if there is anything I can do to enhance it to prevent xss attacks.

Here is what my controller looks like

$app->post('/addTimetable', function(Request $request) use($app) {

$tutoremail = $app['request']->get('tutoremail');
$starttime = $app['request']->get('starttime');
$endtime = $app['request']->get('endtime');
$location = $app['request']->get('location');
$class = $app['request']->get('class');
$level = $app['request']->get('level');
$topic = $app['request']->get('topic');
$capacity = $app['request']->get('capacity');
$postcode = $app['request']->get('postcode');
$post = array($tutoremail,$starttime,$endtime,$location,$class,$level,$topic,$capacity,$postcode);

$tutoremail = trim(filter_var($tutoremail,FILTER_SANITIZE_EMAIL));
//not sure how to filter datetime
$location = trim(filter_var($location,FILTER_SANITIZE_STRING));
$class = trim(filter_var($class,FILTER_SANITIZE_STRING));
$level = trim(filter_var($level,FILTER_SANITIZE_STRING));
$topic = trim(filter_var($topic,FILTER_SANITIZE_STRING));
$capacity = trim(filter_var($capacity,FILTER_SANITIZE_NUMBER_INT));

if(!(isset($tutoremail)) || !(isset($starttime)) || !(isset($endtime)) || !(isset($location)) || !(isset($class)) || !(isset($level)) || !(isset($topic)) || !(isset($capacity))){
    $app['session']->getFlashBag()->add('error','Please fill in all fields');
    return $app->redirect('/admin');
}else if($app['auth']->spamBotCheck($post)){
    $app['session']->getFlashBag()->add('error', 'There was a problem with the information you entered');
    return $app->redirect('/admin');
}else if($app['auth']->honeyPotCheck($postcode)){
    $app['session']->getFlashBag()->add('error','Your form submission has an error');
    return $app->redirect('/admin');
}else if(is_numeric($capacity) && $app['admin']->add_timetable($tutoremail,$starttime,$endtime,$location,$class,$level,$topic,$capacity)){
    $app['session']->getFlashBag()->add('success','Success! New lesson added to timetable');
    return $app->redirect('/admin');
} else {
    $app['session']->getFlashBag()->add('error','Error! New lesson not added to timetable');
    return $app->redirect('/admin');
}
});

Here is the model code for the methods spamBotCheck and honeyPotCheck

public function spamBotCheck($post){
    foreach($post as $value){
        if(stripos($value,'Content-Type:') !== FALSE){
            return true;
        }else{
            return false;
        }
    }

}

public function honeyPotCheck($postcode){
 if($postcode != ""){
    return true;
 }else{
    return false;
 }
}

and lastly here is my form from my twig file

<form class="form-signin collapse" id="demo" method="post" action="/addTimetable">

    <label for="ad_tutoremail" class="sr-only">Tutor Email:</label>
    <input class="form-control" name="tutoremail" type="email" id="ad_tutoremail" placeholder="Tutoremail" required>

    <label for="ad_starttime" class="sr-only">Starttime:</label>
    <input class="form-control" name="starttime" type="text" id="ad_starttime" placeholder="Starttime" required>

    <label for="ad_endtime" class="sr-only">Endtime:</label>
    <input class="form-control" name="endtime" type="text" id="ad_endtime" placeholder="Endtime" required>

    <label for="ad_location" class="sr-only">Location:</label>
    <input class="form-control" name="location" type="text" id="ad_location" placeholder="Location" required>

    <label for="ad_class" class="sr-only">Class:</label>
    <input class="form-control" name="class" type="text" id="ad_class" placeholder="Class" required>

    <label for="ad_level" class="sr-only">Level:</label>
    <input class="form-control" name="level" type="text" id="ad_level" placeholder="Level" required>

    <label for="ad_topic" class="sr-only">Topic:</label>
    <input class="form-control" name="topic" type="text"id="ad_topic" placeholder="Topic" required>

    <label for="ad_capacity" class="sr-only">Capacity:</label>
    <input class="form-control" name="capacity" type="text" id="ad_capacity" placeholder="Capacity" required>

    <div class="spamCheck">
        <label for="inputPostcode" class=sr-only">Postcode</label>
        <input type="text" id="inputPostcode" class="form-control" name="postcode" placeholder="Leave this field blank" />
    </div>

    <input class="createButton" type="submit" value="Create">

</form>
\$\endgroup\$
4
  • \$\begingroup\$ Is there any reason for not using symfony's form support? \$\endgroup\$ Jul 4, 2016 at 10:35
  • \$\begingroup\$ Yes originally someone else wrote this code who was teaching me how to code, and I'm guessing as I am a noob, he probably thought it would be easier for me to understand in plain html form. In fact after I am done with this one I am reverting back to learning pure php as I am not confident with OOP and it took me a while to understand a lot of the stuff in symfony. \$\endgroup\$
    – mp252
    Jul 4, 2016 at 10:39
  • \$\begingroup\$ @mp252: If you're not comfortable with OOP, then please learn about that first. PHP allows you to write procedural scripts, true enough, but as your projects grow, OO (done right) really is one of the best ways to protect your sanity \$\endgroup\$ Jul 4, 2016 at 15:47
  • \$\begingroup\$ @EliasVanOotegem Thanks, I do plan to learn it properly I know the basics. I am thinking about building a to do application in oop to get a feel for it, and then a user/registration login system \$\endgroup\$
    – mp252
    Jul 4, 2016 at 16:14

1 Answer 1

1
\$\begingroup\$

I have read up that nothing needs to be done for xss in symfony as it is already protected from it, is this case?

The Twig templating engine automatically encodes output variables, which will prevent XSS in most situations, but not all. A simple example is <script>[user_input]</script> or <a href="" onclick="[user_input]">click me</a>.

PHP templates do not encode output, and of course any echoes you perform outside of templates are also not encoded.

If this is not the case I want to make sure that the code I have written below if sufficient enough to protect from xss. Or if there is anything I can do to enhance it to prevent xss attacks.

You don't actually print any variables, so there is no danger of XSS in the code you provided.

Your additional input filter is generally a very good idea (as defense-in-depth; never as only defense; XSS is prevented by encoding output), although I would suggest that you write your own instead of using the filter functions PHP provides. The problem with FILTER_SANITIZE_STRING:

  • It is poorly named. What does sanitize string even mean? This also means that the behavior may be changed in later versions, as it would still fit the name.
  • It is poorly documented. It says this: Strip tags, optionally strip or encode special characters. It does apply strip_tags, but it also encodes ' and " by default, not optionally. < and > on the other hand are not encoded.
  • It changes your input. strip_tags doesn't actually just strip tags. If there is a stray < in the string, it will remove anything afterwards which may cause bugs (I <3 you becomes I, super<secure_password becomes super).
  • Encoding should happen at the output, not at the input.

I would suggest that you write your own input filter class, which may look something like the linked one.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you for the answer. I think I must have been getting confused about XSS being effected by input as well. So if for example within my form I used a value attribute. I would have to escape the output on that ? With regards to my own filter class I will give it a go, I am a noob so would be a good challenge. \$\endgroup\$
    – mp252
    Jul 4, 2016 at 10:00
  • \$\begingroup\$ @mp252 Right, the value attribute would be one example where you would need to encode (although I would strongly suggest using Twig instead, it's saver and the code is generally nicer to read). If you output the stored values anywhere else, you would also need to encode. And I agree, writing a filter class would be a nice exercise. Feel free to post your code once you are done. \$\endgroup\$
    – tim
    Jul 4, 2016 at 10:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.