fmath is an extremely powerful plug-in library for wysiwyg editors.

It provides an editor for mathematical formulas, which generates images that can be used in drupal sites. It processes mathml and latex.

There is a problem though, images are saved on a server using the following php file.

   $type = $_POST["type"];
   if($_POST["name"] and ($type=="JPG" or $type=="PNG")){
      $img = base64_decode($_POST["image"]);
      $myFile = "img/".$_POST["name"].".".$type ;
      $fh = fopen($myFile, 'w');
      fwrite($fh, $img);
      echo "http://your_server/capture/img/".$_POST["name"].".".$type;
   header('Content-Type: image/jpeg');
   echo base64_decode($_POST["image"]);

This file is publicly available, and can not be restricted with .htaccess to localhost only (the whole library will not work).

From my understanding the file is called by scripts on a user side via an url, and the image is passed by the POST method. That makes the file very dangerous as it allows anyone to save anything on the server.

Are my suspicions correct? How can I make this safe to use?

The whole library weights 11MB so I don't feel like debugging it.

  • It ought to be possible to replace the script in question with a Drupal callback, then you could use Drupal's core santisation functions to do things more safely. I'd remove that script and create a custom module with a menu entry to define the equivalent path. Apr 15, 2013 at 16:36
  • Alfred, If I understand you correctly, you suggest to use drupal's private files system to generate a link, with access control on the file? (At least that's my idea at the moment)
    – Pawel G
    Apr 15, 2013 at 16:49
  • Drupal's file system, yes, which can have public and private areas. It wouldn't have to be private unless you need the generated files to be access controlled for reading. Uploads are always controlled. Apr 15, 2013 at 16:55

2 Answers 2


This should really be addressed to the fmath project maintainers. I've mailed them to point out some security concerns in the code. If they don't respond I'll edit this post to answer the question here, but hopefully they will respond with a new version ;)

Original comment - mailed to fmath maintainer:

Some key things this is missing that you would want to get right:

  • CSRF protection - If you don't use the form API (which includes this already) then you can manually use drupal_get_token and drupal_valid_token are helpers.
  • Malicious file types - file_munge_filename is a helper here
  • Too many/too big of files
  • Temporarily uploading the file to a temporary directory outside of the webroot and giving it a random name so that it can be validated in that temporary location before moving it to the final location
  • Ideally you would validate the file contents (e.g. virus scan, confirm the file is a valid file of whatever the extension/mime type says it is).
  • Control where the file can be placed.

This script looks like it would only allow jpg or png files to be uploaded, but it misses out on a few other security features

There are probably a few other things to worry about, but I think that list is a good start.

I also wonder about this piece and whether you could sneak base64 encoded html into a "jpg" file and then some veresions of internet explorer and safari will do mime type detection and execute the html (i.e. cross site scripting attack):

   echo base64_decode($_POST["image"]);

I have solved this problem by plugging the file to drupal and checking the user if he is not anonymous (please correct me if I'm doing something wrong here).

define('DRUPAL_ROOT', '/home/username/www/');
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
global $user;
if($user->uid != 0){
   // the provided imageCapture.php script
   // end the provided script

As users of my portal will be trusted it does the trick for me. I agree with greggles though that it is something that fmath maintainers should fix.

  • This doesn't solve the issues I was concerned about (thought it's a step in the right direction).
    – greggles
    Apr 17, 2013 at 18:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.