Я в настоящее время разрабатываю платформу развлечений, я работаю веб-разработчиком в веб-бюро.
Этот проект является моим собственным персональным проектом, он выполняет стек LAMP на DigitalOcean. На работе у нас есть 'сторонний' парень, который заботится об установках сервера.
Я не очень хорош в серверах/человечности в целом.
Проблема, я могу только загрузить изображения, gifs, и т.д. с chmod - R 777, НО я считал в значительной степени везде, что это - nono, опасный, и т.д., и т.д.
Я, очевидно, использую безопасность в своих сценариях для обработки файлов, вот мой сценарий 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? Я немного смущен относительно того, как решить эту проблему с папками, на которые могут загрузить пользователи?
Как я преодолеваю эту проблему?
Проблема, я могу только загрузить изображения, gifs, и т.д. с chmod - R 777, НО я считал в значительной степени везде, что это - nono, опасный, и т.д., и т.д.
действительно это - большой "nono". Вы не хотите, чтобы посторонние смогли найти и выполнить Ваши сценарии. Или смогите просмотреть конфигурационные файлы, где они могут найти пароли к базам данных.
Никогда ничего не устанавливайте на исполняемый файл ("7"), который не должен быть исполняемым файлом. Файлы, которые нормальны в максимальной потребности 664, но 640, лучше. Для каталогов нужно в максимальных 775, но 770 лучше ("0", означает, что "другие" ничего не могут сделать).
Лучше иметь все исполняемые файлы за пределами веб-сервера и косвенно запускать их с веб-сервера. Тем путем никто не может оскорбить их, и самое большее они могут запустить их косвенно, так не получил бы ответов от тех сценариев.
Если Вы придерживаетесь этого, можно использовать опцию "группы" добавить обоих пользователей к той же группе. Это позволяет Вам и другим использовать полномочия группы (и это будет то же для всех вовлеченных пользователей).
Команды, которые могли бы быть полезными:
sudo groupadd webserver
sudo usermod -a -G webserver rinzwind
groups
Существует другой метод с намного меньше, чтобы сделать (но также и не лучший метод): у Вас может быть задание крона (/etc/cronjob), заботятся о Вашей проблеме. Загрузка, в чем Вы нуждаетесь к структуре каталогов в (например), Вашем / домой и настраиваете cronjob, чтобы сделать перемещение, которое размещает их в корректное место./etc/cronjob может быть настроен для использования определенного имени пользователя (и Вы сделали бы это пользователем, который владеет веб-сервером). Решает Вашу проблему также.