• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revision851cf4974927fb3623cea3dce1103ca5caa706d1 (tree)
Time2017-01-13 16:38:56
AuthorKeishi Tanaka <kc@toie...>
CommiterGitHub

Log Message

Hotfix dlexec Vulnerability

Change Summary

Incremental Difference

--- a/lib/init.php
+++ b/lib/init.php
@@ -11,7 +11,7 @@
1111 // PukiWiki version / Copyright / Licence
1212
1313 define('S_VERSION', '1.4.7');
14-define('QHM_VERSION', '6.0.8'); //絶対に編集しないで下さい
14+define('QHM_VERSION', '6.0.9'); //絶対に編集しないで下さい
1515 define('QHM_OPTIONS', 'update=download; support=false; banner=true');
1616 define('S_COPYRIGHT',
1717 'powered by <strong><a href="http://www.open-qhm.net/">QHM</a> ' . QHM_VERSION . '</strong> haik<br />' .
--- a/plugin/dlexec.php
+++ b/plugin/dlexec.php
@@ -43,6 +43,7 @@ if( file_exists('lib/qdsmtp.php') ){
4343 *********************************************/
4444
4545 $key = md5( file_get_contents('qhm.ini.php') );
46+validate_downloadable_path();
4647 download($key);
4748
4849
@@ -67,6 +68,12 @@ function download($auth_key){
6768 $wikifile = 'wiki/'. encode($page) . '.txt';
6869 $source = file_exists($wikifile) ? file_get_contents($wikifile) : '';
6970
71+ if(! is_downloadable_file($filename))
72+ {
73+ header('HTTP/1.1 403 Forbidden');
74+ error_msg('Error : Invalid access');
75+ exit;
76+ }
7077 if ($page === '' OR ! preg_match('/&dl(?:button|link)\('. preg_quote($filename, '/').'(?:,|\))/', $source))
7178 {
7279 header('HTTP/1.1 403 Forbidden');
@@ -121,6 +128,77 @@ function download($auth_key){
121128
122129 }
123130
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+
124202 function dl_sendmail($email, $filename, $title){
125203
126204 global $smtp_auth, $smtp_server, $google_apps, $google_apps_domain;
--- a/pukiwiki.ini.php
+++ b/pukiwiki.ini.php
@@ -160,6 +160,8 @@ $modifierlink = 'http://www.example.co.jp/'; // Site admin's Web page
160160 $googlemaps_apikey = 'ABQIAAAAiGS5xMxFoCjNEIdoMGiCBRSh3wgB-evfR4k_uhb9NTlXTFSqGRScvANPOtehBVz7qEVDLEwY4PlLng';
161161 // Fit videos to screen
162162 $enable_fitvids = true;
163+// Downloadable path delimitered semicolon (;)
164+$downloadable_path = 'swfu/d;pub';
163165
164166
165167 $mobile_redirect = ''; // Mobile Access Redirect