Security is important
As the application is built now, we have a potential security issue. There is only taken care of SQL-injection on data that is saved to the database. But filter_input() does not prevent any malisious code to be posted into the system. So we want to replace that function with our own like this: Http::filter_input($method, $param, $filter). So that we can make a simple search and replace in our application and change all the instances to our secure one. Lets start by creating the file classes/Http.php
Now we can do a search and replace in our entire codebase for filter_input and replace it with Http::filter_input. And from now on we always use the Http::filter_input to make sure that the input we send to our database is secured. In our index.php we will change the following code:
function printContent() {
$module = filter_input(INPUT_GET, 'module', FILTER_SANITIZE_URL);
$view = filter_input(INPUT_GET, 'view', FILTER_SANITIZE_URL);
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
To this:
function printContent() {
// stripcslashes is because Http::filter_input makes & and _ slashed. We do not want that on these values. They are not used in LIKE queries in the database
$module = stripcslashes(Http::filter_input(INPUT_GET, 'module', FILTER_SANITIZE_URL));
$view = stripcslashes(Http::filter_input(INPUT_GET, 'view', FILTER_SANITIZE_URL));
$id = Http::filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
Notice that we use the stripcslashes() to remove the slashes from % and _ because we do not want them in our model and view variable. There is no security issue there. We also want to add stripcslashes() in places where post data is displayd in forms directly. Like in our search form in list. The only real reason for doing this is to avoid have the user think that the search query was changed, and that in some way made the search less effective.
Now we are using % for wildcard search as default in this search form. But in some cases you might want to have the posibillity for the user to add a wildcard search instead. Then you use the *, as it is more wildly known to be a wildcard and in your query you replace all * with %. You might also do the same in order to get a single character wildcart and replace . with _ in the string.
I have previously discussed the String::slashText() function. But I add it her as well in order to remind you what it does. And I have also added some code to prevent any unexpected behavior if you for some reason would want to write #a# in your text. Preiously that would have resulted in an unexpected tag.
]*?>.*?/is', '', $text);
$text = preg_replace('//is', '', $text);
// Secure all safe tags, only allowing tags and slashes. No other information inside tags.
$text = preg_replace('/(<(/?)(b|p|i|u|s|span|li|lu|table|tr|th|td|cite|wbr|strong|em|italic|code|pre)(/?)>)/i', '###$2$3$4¤¤¤', $text);
$text = preg_replace('/<(a).*?(href="[^"]*?").*?(target="[^"]*?")>/i', '###$1 $2 $3¤¤¤', $text);
$text = preg_replace('/<(a).*?(href="[^"]*?")>/i', '###$1 $2¤¤¤', $text);
$text = preg_replace('/(<(/a)>)/i', '###$2¤¤¤', $text);
$text = preg_replace('/<(img)s+(src="[^"]*?")s+(style="[^"]*?")[^>]*?>/i', '###$1 $2 $3¤¤¤', $text);
$text = preg_replace('/<(img)s+(src="[^"]*?")[^>]*?>/i', '###$1 $2¤¤¤', $text);
$text = preg_replace('//', '###br###', $text);
// Remove all tags that are left
$text = preg_replace('/<[^>]*?>/', '', $text);
// Restore all safe tags
$text = preg_replace('/###br###/', '
', $text);
$text = preg_replace('/(###(/a)¤¤¤)/i', '<$2>', $text);
$text = preg_replace('/(###(a.*?)¤¤¤)/i', '<$2>', $text);
$text = preg_replace('/(###(img.*?)¤¤¤)/i', '<$2>', $text);
$text = preg_replace('/(###(/?(b|p|i|u|s|span|li|lu|table|tr|th|td|cite|wbr|strong|em|italic|code|pre)/?)¤¤¤)/i', '<$2>', $text);
// Restore the faile safe
$text = str_replace('#-#-#', '###', $text);
$text = str_replace('¤-¤-¤', '¤¤¤', $text);
return $text;
}
- framework, php, security, software