diff options
author | thomascube <thomas@roundcube.net> | 2009-08-12 10:44:46 +0000 |
---|---|---|
committer | thomascube <thomas@roundcube.net> | 2009-08-12 10:44:46 +0000 |
commit | db522183372aebf81c0dd958a351f108a76efeae (patch) | |
tree | 2f70b2d5484a4bbb02b0067d171d94f22c9cce19 | |
parent | 75969686c23575e61f306ae4502f132968848096 (diff) |
Improve security of modcss.php by setting timeouts and more sanity checks
-rw-r--r-- | bin/modcss.php | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/bin/modcss.php b/bin/modcss.php index a4bd0846f..7e02e4651 100644 --- a/bin/modcss.php +++ b/bin/modcss.php @@ -33,7 +33,7 @@ if (empty($RCMAIL->user->ID)) { exit; } -$url = preg_replace('/[^a-z0-9.-_\?\$&=%]/i', '', $_GET['u']); +$url = preg_replace('![^a-z0-9:./\-_?$&=%]!i', '', $_GET['u']); if ($url === null) { header('HTTP/1.1 403 Forbidden'); echo $error; @@ -45,42 +45,63 @@ $port = $a_uri['port'] ? $a_uri['port'] : 80; $host = $a_uri['host']; $path = $a_uri['path'] . ($a_uri['query'] ? '?'.$a_uri['query'] : ''); -if (!($fp = fsockopen($host, $port, $errno, $errstr, 30))) { +// don't allow any other connections than http(s) +if (strtolower(substr($a_uri['scheme'], 0, 4)) != 'http') { + header('HTTP/1.1 403 Forbidden'); + echo "Invalid URL"; + exit; +} + +// try to open socket connection +if (!($fp = fsockopen($host, $port, $errno, $error, 15))) { header('HTTP/1.1 500 Internal Server Error'); echo $error; exit; } +// set timeout for socket +stream_set_timeout($fp, 30); + +// send request $out = "GET $path HTTP/1.0\r\n"; $out .= "Host: $host\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); +// read response $header = true; +$headers = array(); while (!feof($fp)) { $line = trim(fgets($fp, 4048)); - if ($header - && preg_match('/^HTTP\/1\..\s+(\d+)/', $line, $regs) - && intval($regs[1]) != 200) { - break; - } else if (empty($line) && $header) { - $header = false; - } else if (!$header) { + if ($header) { + if (preg_match('/^HTTP\/1\..\s+(\d+)/', $line, $regs) + && intval($regs[1]) != 200) { + break; + } + else if (empty($line)) { + $header = false; + } + else { + list($key, $value) = explode(': ', $line); + $headers[strtolower($key)] = $value; + } + } + else { $source .= "$line\n"; } } fclose($fp); -if (!empty($source)) { +// check content-type header and mod styles +$mimetype = strtolower($headers['content-type']); +if (!empty($source) && in_array($mimetype, array('text/css','text/plain'))) { header('Content-Type: text/css'); - echo rcmail_mod_css_styles( - $source, - preg_replace('/[^a-z0-9]/i', '', $_GET['c']), - $url - ); + echo rcmail_mod_css_styles($source, preg_replace('/[^a-z0-9]/i', '', $_GET['c'])); exit; } +else + $error = "Invalid response returned by server"; header('HTTP/1.0 404 Not Found'); echo $error; |