我正在为我的网络主机编写一些服务器端脚本,它将为客户端应用程序执行大量自动更新。只要用户使用应用程序名称和密码正确地将自己标识为所有者,他们就应该能够上传到自动创建的服务器上的存储库;但是,我不希望允许上传任何脚本,以便它可以在服务器上运行。我打算允许人们创建他们自己的存储库而不必问我,所以无论如何阻止这个潜在的漏洞?
这是存储库的设置代码,名为APPSEtUP.php:
<?php
$app = str_replace("_", " ", TDecode($_POST['app']));
$pass = str_replace("_", " ", TDecode($_POST['pass']));
$command = str_replace("_", " ", TDecode($_POST['command']));
$worked = false;
if ($command == "SETUP_API") { $worked = SETUP_API($app, $pass); }
if ($command == "MAKE_DIR") { $worked = Make_Directory($app, $pass, TDecode($_POST['DIR']), TDecode($_POST['up'])); }
if ($worked) { echo "SUCCESS!"; }
return;
function Make_Directory($api, $pw, $dir, $up) {
$path = $_SERVER['REQUEST_URI'];
if ($path == "/scripts/APPSETUP.php") { echo "API FAILURE: 008\r\n"; return false; }
if (!startsWith($path, "/scripts/Apps/")) { echo "API FAILURE: 009\r\n"; return false; }
if (!Get_API_PW("./security.LOCK", $pass)) { echo "API FAILURE: 010\r\n"; return false; }
if ($path != "/scripts/Apps/".$api."/APPSETUP.php") { echo "API FAILURE: 011\r\n"; return false; }
while (startsWith($dir, ".") || startsWith($dir, "/")) { $dir = substr($dir, -(strlen($dir)-1)); }
while (endsWith($dir, "/")) { $dir = substr($dir, 0, strlen($dir)-1); }
if (!(file_exists("./".$dir."/") || mkdir("./".$dir."/", "0777", true))) { echo "API FAILURE: 012\r\n"; return false; }
if ($up == "true" && !(file_exists("./".$dir."/UploadFile.php") || copy("./UploadFile.php", "./".$dir."/UploadFile.php"))) {
echo "API FAILURE: 013\r\n"; return false;
} return true;
}
function startsWith($haystack, $needle) {
$length = strlen($needle);
return (substr($haystack, 0, $length) === $needle);
}
function endsWith($haystack, $needle) {
$length = strlen($needle);
return $length === 0 || (substr($haystack, -$length) === $needle);
}
function SETUP_API($api, $pw) {
$temp1 = "./Templates/USERLOG.php";
$temp2 = "./Templates/UploadFile.php";
$temp3 = "./APPSETUP.php";
$dest1 = "./Apps/";
$dest2 = "./Apps/".$api."/";
$dest3 = "./Apps/".$api."/USERLOG.php";
$dest4 = "./Apps/".$api."/security.LOCK";
$dest5 = "./Apps/".$api."/UploadFIle.php";
$dest6 = "./Apps/".$api."/APPSETUP.php";
if (!(file_exists($dest1) || mkdir($dest1, 0777, true))) { echo "API FAILURE: 001\r\n"; return false; }
if (!(file_exists($dest2) || mkdir($dest2, 0777, true))) { echo "API FAILURE: 002\r\n"; return false; }
if (!file_exists($dest4)) { if (!App_Reset($dest2, $dest4, $pw)) { echo "API FAILURE: 003\r\n"; return false; } }
if (!Get_API_PW($dest4, $pw)) { echo "API FAILURE: 004\r\n"; return false; }
if (!copy($temp1, $dest3)) { echo "API FAILURE: 005\r\n"; return false; }
if (!copy($temp2, $dest5)) { echo "API FAILURE: 006\r\n"; return false; }
if (!copy($temp3, $dest6)) { echo "API FAILURE: 007\r\n"; return false; }
return true;
}
function App_Reset($api, $sec, $pw) {
try {
Delete_Bad_App($api);
$pWriter = fopen($sec, "w");
fwrite($pWriter, TEncode($pw));
fclose($pWriter);
return true;
} catch (exception $e) { return false; }
}
function Delete_Bad_App($api) {
$di = new RecursiveDirectoryIterator($api, FilesystemIterator::SKIP_DOTS);
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
foreach ( $ri as $file ) {
$file->isDir() ? rmdir($file) : unlink($file);
} return;
}
function Get_API_PW($sec, $guess) {
try {
$pReader = fopen($sec, "r");
$pw = TDecode(fread($pReader, filesize($sec)));
fclose($pReader);
return $pw == $guess;
} catch (exception $e) { return false; }
}
function TriceInt($c) {
$b = unpack("C*", $c)[1] % 255;
$foo = (string)$b;
while (strlen($foo) < 3) { $foo = "0".$foo; }
return $foo;
}
function TEncode($str) {
if (TEncoded($str)) { return $str; }
return implode(array_map("TriceInt", str_split($str, 1)));
}
function TDecode($str) {
if (!TEncoded($str)) { return $str; }
return implode(array_map("chr", array_map('intval', str_split($str, 3))));
}
function TEncoded($str) {
return (ctype_digit($str) && strlen($str) % 3 == 0);
}
?>
这是用于上传文件的脚本。
<?php
$uploads_dir = './';
if ($_FILES["file"]["error"] == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["file"]["tmp_name"];
$name = $_FILES["file"]["name"];
move_uploaded_file($tmp_name, "$uploads_dir/$name");
}
?>
请注意,上传脚本名为UploadFile.php,位于安装脚本中引用的模板文件夹中。
答案 0 :(得分:1)
因此,根据问题评论中的建议,我尝试使用.htaccess禁用脚本执行,但因为我使用的是由godaddy托管的Windows Server,我使用了错误的文件类型来执行此操作。我发现这个链接解释了如何在web.config中做同样的事情,它适用于Windows服务器。
http://issues.umbraco.org/issue/U4-8472
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<clear />
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
</handlers>
</system.webServer>
</configuration>