Hello fellow programmers,

I've built an upload script that, as usual, verifies if a file extension is allowed. However, the comparison seems to not be working, as it gives me an unhauthorized file trying to be uploaded (when in fact the file has an authorized extension).

If i comment the block below, the upload works fine

Anyone could give me a hint?

//Array containing the authorized extensions
$ext_permitidas = array("jpg","jpeg","gif","png"); 

/* SOME CODE HERE */

//String comparison and validation

$ext = substr($filename, strpos($filename,'.'), strlen($filename)-1);

if(!in_array($ext,$ext_permitidas))
    die('A extensão da imagem '.$ext.' não é permitida');

Dani AI

Generated

Short summary and context from the thread: reported an allowed-extension being rejected; pointed out the extraction logic can include a leading dot and fail with multiple periods; fixed it by adding a dot to each allowed entry and suggested explicit comparisons. Those quick fixes work, but a more robust flow avoids string-parsing pitfalls and improves security.

Safer, practical approach — normalize the extension, then verify actual file type (do not trust extension alone). Use PHP's pathinfo() to get the extension, strtolower() to normalize, then check a whitelist; additionally validate the uploaded file's MIME with finfo_file() (or getimagesize() for images) before accepting it.

$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
$allowed = array('jpg','jpeg','png','gif');

if (!in_array($ext, $allowed)) {
    // reject upload
}
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES['file']['tmp_name']);
finfo_close($finfo);

$allowed_mimes = array('image/jpeg','image/png','image/gif');
if (!in_array($mime, $allowed_mimes)) {
    // reject upload
}

Checklist and extra precautions: store uploads outside the webroot, use move_uploaded_file(), generate safe/random filenames, limit file size, remove or validate any user-supplied filename (basename + strict whitelist), detect double extensions and null bytes, and set non-executable permissions. For image uploads prefer getimagesize() or finfo to confirm real content. See the PHP docs for pathinfo() and finfo_file() and the OWASP file upload guidance for best practices: PHP pathinfo(), PHP finfo_file(), PHP getimagesize(), OWASP File Upload Cheat Sheet.

Recommended Answers

All 3 Replies

This might not be the best way to do this but it should work.

You could try something like this instead of using an array.

$ext = substr($filename, strpos($filename,'.'), strlen($filename)-1);

if (($ext == "png") || ($ext == "jpg") || ($ext == "jpeg") || ($ext == "gif")) {
  //ADD FILE CODE HERE
} else {
 die('A extensão da imagem '.$ext.' não é permitida');
}
Member Avatar for Member #120589

the $ext includes the "." - so none of your array extensions will work. Try this:

substr($filename, strpos($filename,'.')+1, strlen($filename))

BTW - this doesn't wok if there are multiple periods in the name. In whic case, use this:

substr($filename, strrpos($filename,'.')+1, strlen($filename))

note the strrpos (get first period in reverse order)

Solved.

thanks for your sugestions, but I ended up using a "." before each extension in the array though.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.