You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHPMailer文件上传实现的正确性、安全性验证及临时文件疑问

Hey there! Let's break down your questions and walk through your file upload + PHPMailer code to address both your security concerns and temporary file questions.

1. Temporary File Existence & Cleanup

Short answer: Yes, the temporary files in sys_get_temp_dir() will still exist after compression, and you do need to delete them manually.

Here's why:

  • tempnam() creates a persistent file in the system's temporary directory—this file won't be automatically deleted by PHP or the OS (unless your system has a cron job to clean old temp files, which you shouldn't rely on).
  • After you run compressImage($uploadfile, $target_dir . basename($fileName), 60);, the original temp file at $uploadfile is no longer needed.

Fix: Add unlink($uploadfile); right after your compression step to clean up the temp file. To avoid leaving orphan files if compression fails, wrap it in a conditional or use a try/finally block:

else {
    $fileName = clean($_POST['appName']). "_" . $key . "_" . $dateKey . "." . $imageFileType;
    $compressedPath = $target_dir . basename($fileName);
    if (compressImage($uploadfile, $compressedPath, 60)) {
        $msg .= "compression success; ";
        unlink($uploadfile); // Clean up temp file only if compression works
    } else {
        $msg .= "compression failed; ";
        unlink($uploadfile); // Still clean up even if compression fails
        $uploadOk = 0;
    }
}
2. Code Correctness & Security Review

Your code works in basic scenarios, but there are several security gaps and functional tweaks to make it robust:

Critical Security Fixes

  • Fix Email Validation: You're only sanitizing the email with FILTER_SANITIZE_EMAIL—you should also validate it's a valid address with FILTER_VALIDATE_EMAIL:
    $clean_email = filter_var($_POST['appEmail'], FILTER_VALIDATE_EMAIL);
    if (!$clean_email) {
        die("Invalid email address");
    }
    
  • Avoid Hardcoded Credentials: Your SMTP username/password are hardcoded in the script. This is a huge security risk (if your code is leaked, attackers can access your email account). Use environment variables instead:
    $mail->Username = getenv('SMTP_USER');
    $mail->Password = getenv('SMTP_PASS');
    
  • Prevent XSS in Email Links: The $fileString uses raw $file['name'] in the email HTML. Attackers could upload files with names containing malicious HTML/JS (e.g., "><script>stealCookies()</script>.jpg). Escape the filename, and use the actual saved filename (not the original, which was broken):
    $safeFileName = htmlspecialchars($fileName, ENT_QUOTES);
    $fileString .= strtoupper($key).": <a href='XXXXXXXX/uploads/" . $safeFileName . "'>" . $safeFileName . "</a><br>";
    
  • Better File Type Validation: Checking file extensions alone is insecure (attackers can rename a malware file to .jpg). Use the MIME type from getimagesize() to confirm it's actually an image:
    $check = getimagesize($uploadfile);
    if($check === false) {
        $fileMessage .= $key."=noimage,";
        $uploadOk = 0;
    } else {
        $allowedMimes = ['image/jpeg', 'image/png', 'image/gif'];
        if (!in_array($check['mime'], $allowedMimes)) {
            $fileMessage .= $key."=wrongfile,";
            $uploadOk = 0;
        }
    }
    

Functional Improvements

  • Fix File Existence Check: You're checking if the original filename exists in $target_dir, but you're saving the file under $fileName. Update the check to use the actual saved filename:
    $target_file = $target_dir . $fileName;
    if (file_exists($target_file)) {
        $fileMessage .= $key."=fileexists,";
        $uploadOk = 0;
    }
    
  • Improve Error Handling: Instead of concatenating strings to $msg, use an array to track errors—this makes debugging easier:
    $errors = [];
    // ... later ...
    $errors[] = "File {$key} is not an image";
    // ... at the end ...
    echo 'Message sent successfully. '.implode(' ', $errors);
    
  • Add the File Links to the Email: Right now, your email body doesn't include the $fileString you built. Update the Body line:
    $mail->Body = "This is the HTML message body <b>in bold!</b><br><br>Uploaded Files:<br>{$fileString}";
    
  • Secure the clean Function: Your current function allows hyphens, which is fine, but consider adding trim() to remove leading/trailing spaces before replacing:
    function clean($string) {
        $string = trim($string);
        $string = str_replace(' ', '-', $string);
        return preg_replace('/[^A-Za-z0-9\-]/', '', $string);
    }
    
Final Notes

Overall, the core logic of uploading, compressing, and emailing works, but the security fixes are critical to prevent attacks like XSS, file upload malware, and credential leaks. Don't forget to test edge cases (large files, invalid file types, duplicate filenames) to ensure everything behaves as expected.

内容的提问来源于stack exchange,提问作者cannon303

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 14:47:51