Fragile Security

August 9th 2021 · 314 words, 1 minute read

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:

  1. Make sure we only have double quotes.
  2. Strip all HTML tags from CSS.
  3. 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:

  1. NONCE verification. TBD.
  2. 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;
    }
  1. The MIME type is checked against an array of allowed types.
  2. The file extension is evaluated against the MIME type.
  3. The file size is checked against the maximum allowed size.