Security

From EQdkp Plus
Jump to navigation Jump to search

If you write extensions for EQdkp Plus, they should be secure. Therefore, we give you some best practices for secure coding.

Sessions

EQdkp Plus has an own session system. Therefore there is no need to use the PHP Session System.

  • register('user')->setSessionVar($strVarname, $strValue) for adding a session variable to the users current session
  • register('user')->data['session_vars'][$strVarname] to access your stored variable

Input Parameters

You should never trust the direct input of data. Therefore, we have the input class, which handles the user input.

  • register('input')->get('myvar', 0) returns the value of the GET/POST var with key myvar, as integer. If the key does not exist, it will return 0.
  • register('input')->getArray('myarray', 'string') returns the values of the GET/POST var with key myarray, as string array. Will return an empty array if key does not exist.
  • register('input')->getCookie('cookiename', 'string') returns the value of the cookie cookiename. For handling EQdkp Plus Cookies (read and write), see the next section.

Before you will output input variables back to the user, e.g. by using echo, the variables should be sanitized.

  • Use sanitize($var), an EQDkp Plus Method
  • Use htmlspecialchars or filter_var($input, FILTER_SANITIZE_STRING);

Cookies

  • register('input')->getEQdkpCookie('cookiename') will read the content from the EQdkp Plus cookie prefix_cookiename
  • set_cookie($name, $cookie_data, $cookie_time, $blnHttpOnly=true) (an EQDkp Plus Method) is the method for setting an EQdkp Plus Cookie. You should leave the flag $blnHttpOnly true, if there is no need to access the cookie with JavaScript.

Database

Input should never directly written into database. Before, it should be sanitized. To prevent SQL Injection attacks, SQL Strings should not directly be built.

  • Use prepare and execute methods, it's better than escaping every parameter
  • Use the ConditionBuilder if you have multiple conditions
  • If you really need variables in your SQL query, use register('db')->escape($var) to escape all php params in your query string.
$sql = "INSERT	INTO __plugin_statistics (dateID, visits) VALUES (?, 1) ON DUPLICATE KEY UPDATE visits=visits+1";
$this->db->prepare($sql)->execute($date);
$objQuery = $this->db->prepare("DELETE FROM __articles WHERE id =?")->execute($id);
$this->db->prepare("UPDATE __articles :p WHERE id=?")->set(array(
	'category' => 1,
))->execute($intArticleID);

Using MySQL "IN":

$objQuery = $this->db->prepare("UPDATE __articles :p WHERE id :in")->set(array(
	'published'		=> 1,
))->in($arrIDs)->execute($id);

Condition Builder:

$objQuery = $this->db->prepare("SELECT log_id FROM __logs");
if ($plugin !== false) $objQuery->addCondition("log_plugin=?", $plugin);
if ($ip !== false) $objQuery->addCondition("log_ipaddress LIKE ?", '%'.$ip.'%');
if ($sid !== false) $objQuery->addCondition("log_sid LIKE ?", '%'.$sid.'%');
$objQuery = $objQuery->execute();

File Upload

Never allow the upload of bad files, like .php or .html files. Use good formats as .txt or .zip. When saving the files, remove the file extension when possible, and store the files with an random hash as filename.

$blnResult = register('uploader')->upload_mime('file', 'system/articleimages', array("image/jpeg","image/png","image/gif"), array('jpg', 'png', 'gif'), 'uploaded_'.md5(rand()), register('pfh')->FolderPath('', 'files'));

This will put files (image files only) from the field file to the folder 'system/articleimages' at the data subfolder 'files' (last param), as filename uploaded_.md5(rand())

Protected Folders

  • register('filehandler')->secure_folder($folder) creates a .htaccess file as well as an index.html file to prevent access to the folder and directory listing.

Serialized Arrays/Objects

  • Use JSON where possible instead of serialized arrays
  • Do not use serialized objects
  • Use unserialize_noclasses() function instead of unserialize() method to unserialize arrays, as it prevents unserializing objects