Fragile Security
CSS
User submitted anything is a security risk. User submitted CSS and HTML even more so. This is why I was hesitant in offering users the ability to add custom CSS.
It's one thing when you are adding CSS to a page only you can access, and it's an entirely different can of worms once others can access your page as well.
The way I decided to deal with sanitizing CSS without relying on external libraries for the time being is like so:
public static function sanitizeCSS(string $string) : string {
$string = str_replace("'", '"', $string); // Replace single quote with double quote
$string = strip_tags($string);
$string = preg_replace('#((?:java)?script|onload|x00)#', '', $string);
return $string;
}
So, in essence:
- Make sure we only have double quotes.
- Strip all HTML tags from CSS.
- Remove any instances of
javascript
,script
,onload
or NUL bytes.
Uploading Images
If user CSS was a troublesome addition due to the potential security risks it opens up, then uploading images anything is even worse.
Prior to upload, the following things are checked:
NONCE verification.TBD.- User logged in verification.
Validity checks:
private static function isImageValid(array $image): bool {
$path = $image['tmp_name'];
$type = $image['type'];
$extension = pathinfo($image['name'], PATHINFO_EXTENSION);
$validType = array_key_exists($type, self::$allowedFiletypes) && array_key_exists(mime_content_type($path), self::$allowedFiletypes);
$validExt = $validType && self::$allowedFiletypes[$type] === $extension;
$validSize = $image['size'] <= self::$maxFileSize;
return $validType && $validExt && $validSize;
}
- The MIME type is checked against an array of allowed types.
- The file extension is evaluated against the MIME type.
- The file size is checked against the maximum allowed size.
- If the file is valid, it's moved to the upload directory and renamed to the MD5 value of the file. This way we also prevent duplicates.
- If the file is invalid, it's renamed and passed to quarantine to be analyzed later.