Form security

4

I have the following code:

PHP (server):

if(isset($_POST['subdate']) && !empty($_POST['date'])) {

   $daysOff = array();
   $get_date = explode(',', $_POST['date']);
   foreach ($get_date as $date) {
     $date = explode('-', $date);
     $day = $date[0];
     $month = $date[1];
     $year = $date[2];
     $time_Stamp = mktime(0,0,0,$month,$day,$year);
     $daysOff[] = strftime('%d-%m-%Y', $time_Stamp);
   }

   $daysOff = json_encode($daysOff);
   echo "dates off: " .$daysOff;
}

else {
   $daysOff = json_encode(array("23-09-2015", "15-09-2015"));
   echo "dates off: " .$daysOff;
}

HTML (client)

...
<link rel="stylesheet" href="https://code.jquery.com/ui/1.11.4/themes/pepper-grinder/jquery-ui.css">
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script><scriptsrc="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
...
<form method="POST">
    <input id="datepicker" type="date" name="date" autocomplete="off" readonly>
    <br>
    <input type="submit" name="subdate">
</form>
...

Javascript (client)

function datePicker() {

   <?php echo "var datesOff = JSON.parse('" .$daysOff. "');"; ?>
   var daysSelected = [];

   var datepickerOpts = {

      beforeShowDay: function(date){

         var day = $.datepicker.formatDate('dd-mm-yy', date);
         var checkDate = datesOff.indexOf(day);

         if(checkDate == -1) {
             // not found, data available
             return [true, "", "available"];
         }
         else {
            return [false, "", "not available"];
         }
      },
      onSelect: function(date) {

         var index = daysSelected.indexOf(date);

         if(index == -1){
            daysSelected.push(date);
            console.log(daysSelected);
         }
         else {
            daysSelected.splice(index, 1);
            console.log(daysSelected);
         }
         $('input[type="date"]').val(daysSelected);
         // prevent from closing datepicker when clicking date
         $(this).data('datepicker')['inline'] = true;
      },
      onClose: function() {
         $(this).data('datepicker')['inline'] = false;
      },
      dateFormat: 'dd-mm-yy',
      showOn: "both",
      buttonImage: "http://icons.iconarchive.com/icons/icons8/ios7/256/Time-And-Date-Calendar-icon.png",
      buttonImageOnly: true,
      buttonText: "Select date",
      showAnim: "slideDown",
   };

   $('#datepicker').datepicker(datepickerOpts);
}

datePicker();

Everything works very well, starting from the principle that will not change manually the value of the input as shown in the image below, which causes a server error, more specifically with the function explode. I wanted to avoid this, I liked that there was a simple check (I've already tried with try / catch), eg if the inputs were this format: "dd-mm-aaa,dd-mm-aaaa" is that we advance to explodes etc ... Keeping in mind that it must also result if there is only one date: "dd-mm-aaaa" . Other suggestions for avoiding errors in this case are also welcome. Example of what happens:

Before submitting, manually change the value:

Aftersubmitting:

Errors arise when trying to access the indexes of $date , within the cycle we have in the server side code.

    
asked by anonymous 09.09.2015 / 13:01

2 answers

4

Most of your problems will be solved with some simple validations, eg:

<?php

if(isset($_POST['subdate']) && !empty($_POST['date'])) {

   $daysOff = array();
   $get_date = explode(',', $_POST['date']);
   foreach ($get_date as $date) {

      // Validação com Expressão Regular
      // Apenas com essa validação você pode resolver a maioria dos seus problemas
      if(!preg_match('/^([0-9]{2}\-[0-9]{2}\-[0-9]{4})$/', $date)){
         // Não está no formato NN-NN-NNNN
         // Tome qualquer providencia aqui
      }

      $date = explode('-', $date);

      // Validando a quantidade de elementos retornados pelo explode
      if (count($date) == 3){
         $day = $date[0];
         $month = $date[1];
         $year = $date[2];
         $time_Stamp = mktime(0,0,0,$month,$day,$year);
         $daysOff[] = strftime('%d-%m-%Y', $time_Stamp);
      } else {
         // O explode não resultou em 3 elementos
         // Tome qualquer providencia aqui
      }
   }

   $daysOff = json_encode($daysOff);
   echo "dates off: " .$daysOff;
} else {
   $daysOff = json_encode(array("23-09-2015", "15-09-2015"));
   echo "dates off: " .$daysOff;
}

I commented the code showing the validations. Keep in mind one thing, whenever you receive data from the user / client, even though a javascript library is crucial to validate this data . Any input data must be validated by the system, especially when the process relies on these data.

I could still do other validations to see if the data actually is dates: Correctly determine if date string is a valid date in that format

    
09.09.2015 / 13:36
0

Well, as you work with forms and do not know what the customer is going to pass would be good to avoid several mistakes, add a mascara of date in your input. Another thing I usually do in my code is always to use php's DateTime , a tip for you to work with. date would be more or less like this in the input parameter.

Ex: $ newDate = implode ('-', array_reverse ( explode (' / ', $ date)));

$ newDate = new DateTime ($ newDate);

And in the output parameter you add a treatment for the date.

    
09.09.2015 / 14:00