| Revision | 851cf4974927fb3623cea3dce1103ca5caa706d1 (tree) |
|---|---|
| Time | 2017-01-13 16:38:56 |
| Author | Keishi Tanaka <kc@toie...> |
| Commiter | GitHub |
Hotfix dlexec Vulnerability
| @@ -11,7 +11,7 @@ | ||
| 11 | 11 | // PukiWiki version / Copyright / Licence |
| 12 | 12 | |
| 13 | 13 | define('S_VERSION', '1.4.7'); |
| 14 | -define('QHM_VERSION', '6.0.8'); //絶対に編集しないで下さい | |
| 14 | +define('QHM_VERSION', '6.0.9'); //絶対に編集しないで下さい | |
| 15 | 15 | define('QHM_OPTIONS', 'update=download; support=false; banner=true'); |
| 16 | 16 | define('S_COPYRIGHT', |
| 17 | 17 | 'powered by <strong><a href="http://www.open-qhm.net/">QHM</a> ' . QHM_VERSION . '</strong> haik<br />' . |
| @@ -43,6 +43,7 @@ if( file_exists('lib/qdsmtp.php') ){ | ||
| 43 | 43 | *********************************************/ |
| 44 | 44 | |
| 45 | 45 | $key = md5( file_get_contents('qhm.ini.php') ); |
| 46 | +validate_downloadable_path(); | |
| 46 | 47 | download($key); |
| 47 | 48 | |
| 48 | 49 |
| @@ -67,6 +68,12 @@ function download($auth_key){ | ||
| 67 | 68 | $wikifile = 'wiki/'. encode($page) . '.txt'; |
| 68 | 69 | $source = file_exists($wikifile) ? file_get_contents($wikifile) : ''; |
| 69 | 70 | |
| 71 | + if(! is_downloadable_file($filename)) | |
| 72 | + { | |
| 73 | + header('HTTP/1.1 403 Forbidden'); | |
| 74 | + error_msg('Error : Invalid access'); | |
| 75 | + exit; | |
| 76 | + } | |
| 70 | 77 | if ($page === '' OR ! preg_match('/&dl(?:button|link)\('. preg_quote($filename, '/').'(?:,|\))/', $source)) |
| 71 | 78 | { |
| 72 | 79 | header('HTTP/1.1 403 Forbidden'); |
| @@ -121,6 +128,77 @@ function download($auth_key){ | ||
| 121 | 128 | |
| 122 | 129 | } |
| 123 | 130 | |
| 131 | +function is_downloadable_file($filename) { | |
| 132 | + global $downloadable_path; | |
| 133 | + $pathinfo = pathinfo($filename); | |
| 134 | + $paths = array_filter(explode(";", $downloadable_path), 'strlen'); | |
| 135 | + return in_array($pathinfo['dirname'], $paths, true); | |
| 136 | +} | |
| 137 | + | |
| 138 | +function validate_downloadable_path() { | |
| 139 | + global $downloadable_path; | |
| 140 | + $cwd = getcwd(); | |
| 141 | + $paths = array_filter(explode(';', $downloadable_path), 'strlen'); | |
| 142 | + $result = TRUE; | |
| 143 | + | |
| 144 | + if (count($paths) === 0) { | |
| 145 | + $result = FALSE; | |
| 146 | + } | |
| 147 | + | |
| 148 | + foreach ($paths as $path) { | |
| 149 | + $canonicalized_path = canonicalize_path($path, $cwd); | |
| 150 | + if ($canonicalized_path !== FALSE) { | |
| 151 | + if ($canonicalized_path === $cwd) { | |
| 152 | + // インストールディレクトリ直下なのでNG | |
| 153 | + $result = FALSE; | |
| 154 | + } else if (strpos($canonicalized_path, $cwd) === 0) { | |
| 155 | + // インストールディレクトリ以下なのでOK | |
| 156 | + } else { | |
| 157 | + // インストールディレクトリ以下ではない | |
| 158 | + $result = FALSE; | |
| 159 | + } | |
| 160 | + } else { | |
| 161 | + // 指定されたパスに権限がない、あるいは存在しない | |
| 162 | + $result = FALSE; | |
| 163 | + } | |
| 164 | + } | |
| 165 | + | |
| 166 | + if ($result === FALSE) { | |
| 167 | + header('HTTP/1.1 500 Internal Server Error'); | |
| 168 | + error_msg('Error : Invalid Configuration'); | |
| 169 | + exit; | |
| 170 | + } | |
| 171 | +} | |
| 172 | + | |
| 173 | +function canonicalize_path($path, $cwd=null){ | |
| 174 | + | |
| 175 | + // don't prefix absolute paths | |
| 176 | + if (substr($path, 0, 1) === "/") { | |
| 177 | + $filename = $path; | |
| 178 | + } | |
| 179 | + // prefix relative path with $root | |
| 180 | + else { | |
| 181 | + $root = is_null($cwd) ? getcwd() : $cwd; | |
| 182 | + $filename = sprintf("%s/%s", $root, $path); | |
| 183 | + } | |
| 184 | + | |
| 185 | + // get realpath of dirname | |
| 186 | + $dirname = dirname($filename); | |
| 187 | + $canonical = realpath($dirname); | |
| 188 | + | |
| 189 | + // return FALSE if $dirname is nonexistent | |
| 190 | + if ($canonical === false) { | |
| 191 | + return FALSE; | |
| 192 | + } | |
| 193 | + | |
| 194 | + // prevent double slash "//" below | |
| 195 | + if ($canonical === "/") $canonical = null; | |
| 196 | + | |
| 197 | + // return canonicalized path | |
| 198 | + return sprintf("%s/%s", $canonical, basename($filename)); | |
| 199 | +} | |
| 200 | + | |
| 201 | + | |
| 124 | 202 | function dl_sendmail($email, $filename, $title){ |
| 125 | 203 | |
| 126 | 204 | global $smtp_auth, $smtp_server, $google_apps, $google_apps_domain; |
| @@ -160,6 +160,8 @@ $modifierlink = 'http://www.example.co.jp/'; // Site admin's Web page | ||
| 160 | 160 | $googlemaps_apikey = 'ABQIAAAAiGS5xMxFoCjNEIdoMGiCBRSh3wgB-evfR4k_uhb9NTlXTFSqGRScvANPOtehBVz7qEVDLEwY4PlLng'; |
| 161 | 161 | // Fit videos to screen |
| 162 | 162 | $enable_fitvids = true; |
| 163 | +// Downloadable path delimitered semicolon (;) | |
| 164 | +$downloadable_path = 'swfu/d;pub'; | |
| 163 | 165 | |
| 164 | 166 | |
| 165 | 167 | $mobile_redirect = ''; // Mobile Access Redirect |