chmod - R 777 - 775 不起作用我该怎么办?

chmod - R 777 - 775 不起作用我该怎么办?

我目前正在开发一个娱乐平台,我在一家网络公司担任网络开发人员。

这个项目是我个人的项目,它在 DigitalOcean 上运行 LAMP 堆栈。在工作中,我们有一个“第三方”人员负责服务器设置。

总的来说,我不太擅长服务器/ubuntu。

问题是,我只能使用 chmod - R 777 上传图像、gif 等,但我几乎在各个地方都看到,这是不可以的、危险的,等等。

我显然在脚本中使用安全性来处理文件,这是我的 UploadFile 脚本。

class UploadFile {

    protected $destination;
    protected $messages = [];
    protected $maxSize = 51200;
    protected $permittedTypes = array(
        'image/jpeg',
        'image/pjpeg',
        'image/gif',
        'image/png',
        'image/webp'
    );
    protected $permittedHere;
    protected $name;
    protected $newName;
    protected $fixedName = false;
    protected $typeCheckingOn = true;
    protected $notTrusted = array('bin', 'cgi', 'exe', 'js', 'pl', 'php', 'py', 'sh');
    protected $suffix = '.upload';
    protected $renameDuplicates;
    protected $maxHeight;
    protected $minHeight;
    protected $maxWidth;
    protected $minWidth;
    protected $status = false;

    public function getMessages() {
        return $this->messages;
    }

    private function setMessages($type, $message) {
        $this->messages[] = [$type => $message];
    }

    public function __construct($uploadFolder, $maxHeight, $permitted = false) {
        $this->permittedHere = $permitted;
        $this->maxHeight = $maxHeight;
        if (!is_dir($uploadFolder) || !is_writable($uploadFolder)) {
            self::setMessages("error", "$uploadFolder must be a valid, writable folder.");
        }
        if ($uploadFolder[strlen($uploadFolder) - 1] != '/') {
            $uploadFolder .= '/';
        }
        $this->destination = $uploadFolder;

    }

    public function setMaxSize($bytes) {
        $serverMax = self::convertToBytes(ini_get('upload_max_filesize'));
        if (is_numeric($bytes) && $bytes > 0) {
            $this->maxSize = $bytes;
        }
    }

    public function setMaxHeight() {
        $this->maxHeight = $maxHeight;
    }

    public function setMinHeight() {
        $this->minHeight = $minHeight;
    }

    public function setMaxWidth($maxWidth) {
        $this->maxWidth = $maxWidth;
    }

    public function setMinWidth($minWidth) {
        $this->minWidth = $minWidth;
    }

    public static function convertToBytes($val) {
        $val = trim($val);
        $last = strtolower($val[strlen($val) - 1]);
        if (in_array($last, array('g', 'm', 'k'))) {
            switch ($last) {
                case 'g':
                    $val *= 1024;
                case 'm':
                    $val *= 1024;
                case 'k':
                    $val *= 1024;
            }
        }
        return $val;
    }

    public static function convertFromBytes($bytes) {
        $bytes /= 1024;
        if ($bytes > 1024) {
            return number_format($bytes / 1024, 1) . ' MB';
        } else {
            return number_format($bytes, 1) . ' KB';
        }
    }

    public function allowAllTypes($suffix = null) {
        $this->typeCheckingOn = false;
        if (!is_null($suffix)) {
            if (strpos($suffix, '.') === 0 || $suffix == '') {
                $this->suffix = $suffix;
            } else {
                $this->suffix = ".$suffix";
            }
        }
    }

    public function upload($renameDuplicates = true, $fixedName = false) {
        $this->renameDuplicates = $renameDuplicates;
        $this->fixedName = $fixedName;

        $uploaded = current($_FILES);
        $this->name = $uploaded['name'];
        if (is_array($uploaded['name'])) {
            foreach ($uploaded['name'] as $key => $value) {
                $currentFile['name'] = $uploaded['name'][$key];
                $currentFile['type'] = $uploaded['type'][$key];
                $currentFile['tmp_name'] = $uploaded['tmp_name'][$key];
                $currentFile['error'] = $uploaded['error'][$key];
                $currentFile['size'] = $uploaded['size'][$key];

                if ($this->checkFile($currentFile)) {
                    $this->moveFile($currentFile);
                }
            }
        } else {
            if ($this->checkFile($uploaded)) {
                $this->moveFile($uploaded);
            }
        }
    }

    public function getName() {
        return $this->name;
    }

    public function getNewName() {
        return $this->newName;
    }

    public function getStatus() {
        return $this->status;
    }

    public function getSourceName() {
        return $this->sourceName;
    }

    protected function checkFile($file) {
//        echo "<p class='checkme'>";
//        echo "<pre>";
//        print_r($file);
//        echo "</pre>";

        if ($file['error'] != 0) {
            $this->getErrorMessage($file);
            return false;
        }
        if (!$this->checkSize($file)) {
            return false;
        }
        if (!empty($this->maxHeight)) {
            if (!$this->checkHeight($file)) {
                return false;
            }
        }
        if ($this->typeCheckingOn) {
            if (!$this->checkType($file)) {
                return false;
            }
        }
        $this->checkName($file);
        return true;
    }

    protected function getErrorMessage($file) {
        switch ($file['error']) {
            case 1:
            case 2:
                self::setMessages("error", $file['name'] . " is too big: (max: " . self::convertFromBytes($this->maxSize) . ")");
                break;
            case 3:
                self::setMessages("error", $file['name'] . " was only partially uploaded.");
                break;
            case 4:
                self::setMessages("error", "No file submitted.");
                break;
            default:
                self::setMessages("error", "Sorry, there was a problem uploading " . $file['name']);
                break;
        }
    }

    protected function checkSize($file) {
        if ($file['size'] == 0) {
            self::setMessages("error", $file['name'] . " is empty.");
            return false;
        } elseif ($file['size'] > $this->maxSize) {
            self::setMessages("error", $file['name'] . " exceeds the maximum size for a file (" . self::convertFromBytes($this->maxSize) . ").");
            return false;
        } else {
            return true;
        }
    }

    protected function checkHeight($file) {
        $data = getimagesize($file['tmp_name']);
        $height = $data[1];
        if ($height > $this->maxHeight) {
            self::setMessages("error", "Height exceed the limit of " . $this->maxHeight);
            return false;
        }
        if ($height > $this->minHeight) {
            self::setMessages("error", "The image should be minimum " . $this->minHeight);
            return false;
        }
        return true;
    }

    protected function checkType($file) {
        if (in_array($file['type'], $this->permittedTypes)) {
            if (isset($this->permittedHere) && !empty($this->permittedHere)) {
                if (in_array($file['type'], $this->permittedHere)) {
                    return true;
                } else {
                    self::setMessages("error", $file['name'] . " is not permitted type of file.");
                    return false;
                }
            } else {
                return true;
            }
        } else {
            self::setMessages("error", $file['name'] . " is not permitted type of file.");
            return false;
        }
    }

    protected function checkName($file) {
        $this->newName = null;

            $nospaces = str_replace(' ', '_', $file['name']);
            if ($nospaces != $file['name']) {
                $this->newName = $nospaces;
            }
            $nameparts = pathinfo($nospaces);
            $extension = isset($nameparts['extension']) ? $nameparts['extension'] : '';
            if (!$this->typeCheckingOn && !empty($this->suffix)) {
                if (in_array($extension, $this->notTrusted) || empty($extension)) {
                    $this->newName = $nospaces . $this->suffix;
                } else {
                    self::setMessages("error", "Something went wrong please try again.");
                }
            }

            if ($this->fixedName){
                if (!in_array($extension, $this->notTrusted) || !empty($extension)) {
                    $this->newName = $this->fixedName . ".$extension";
                } else {
                    self::setMessages("error", "Something went wrong please try again.");
                }
            }

            if ($this->renameDuplicates) {
                $name = isset($this->newName) ? $this->newName : $file['name'];
                $existing = scandir($this->destination);
                if (in_array($name, $existing)) {
                    $i = 1;
                    do {
                        $this->newName = $nameparts['filename'] . '_' . $i++;
                        if (!empty($extension)) {
                            $this->newName .= ".$extension";
                        }
                        if (in_array($extension, $this->notTrusted)) {
                            $this->newName .= $this->suffix;
                        }
                    } while (in_array($this->newName, $existing));
                }
            }

    }

    protected function moveFile($file) {
        $filename = isset($this->newName) ? $this->newName : $file['name'];
        $success = move_uploaded_file($file['tmp_name'], $this->destination . $filename);
        if ($success) {
            $result = $file['name'] . ' was uploaded successfully';
            if (!is_null($this->newName)) {
                $result .= ', and was renamed ' . $this->newName;
            }
            $result .= '.';
            self::setMessages("success", $result);
            $this->status = true;
        } else {
            self::setMessages("error", $result);
        }
    }

}

因此,如果 chmod - R 775 对我不起作用,除了使用 chmod - R 777 之外,我还有什么其他选择?我有点困惑如何解决用户可以上传到的文件夹的问题?

我该如何解决这个问题?

答案1

问题是,我只能使用 chmod - R 777 上传图像、gif 等,但我几乎在各个地方都看到,这是不可以的、危险的,等等。

  • 这确实是一个大忌。你不希望外人能够找到并执行你的脚本。或者能够查看配置文件,从中找出数据库的密码。

  • 切勿将任何不需要可执行的内容设置为可执行(“7”)。正常文件的最大权限为 664,但最好为 640。目录的最大权限为 775,但最好为 770(“0”表示“其他”无法执行任何操作)。

  • 最好将所有可执行文件放在 Web 服务器之外,并从 Web 服务器间接启动它们。这样就没有人可以滥用它们,最多只能间接启动它们,因此不会收到来自这些脚本的任何回复。

如果您坚持这样做,您可以使用“组”选项将两个用户添加到同一组。这样您和其他人就可以使用组权限(并且这些权限对于所有相关用户都是相同的)。

可能有用的命令:

  • 创建一个组“webserver”:sudo groupadd webserver
  • 将用户 rinzwind 添加到此组:sudo usermod -a -G webserver rinzwind
  • 列出当前用户所属的组groups

还有另一种方法,需要做的事情少得多(但也不是最好的方法):您可以让 cron 作业 (/etc/cronjob) 处理您的问题。将您需要的内容上传到(例如)/home 中的目录结构,然后设置一个 cronjob 来执行将它们放置到正确位置的移动。/etc/cronjob 可以设置为使用特定的用户名(您可以将其设置为拥有 Web 服务器的用户)。这也解决了您的问题。

相关内容