This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "FusionForge".
The branch, 6.0 has been updated
via 39a2a375f609f6c19753b59fe4186925183cc767 (commit)
from f7a9921d32b9dd8e6af5fe48be12e5c42689dd8f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 39a2a375f609f6c19753b59fe4186925183cc767
Author: Sylvain Beucler <[email protected]>
Date: Mon Jun 15 12:01:09 2015 +0200
downloading user content: make behavior (including security) consistent
[#773]
diff --git a/src/CHANGES b/src/CHANGES
index 6782b31..caa1fee 100644
--- a/src/CHANGES
+++ b/src/CHANGES
@@ -8,6 +8,7 @@ FusionForge 6.0.1:
* Tracker: fix description re-html-ization when editing item (Inria)
* Tracker: fix HTML entities in mail notifications (Inria)
* Tracker: provide a "Submit" button below the "add a comment" field [#776]
(TrivialDev)
+* Tracker/FRS/Docman/Forum: allow viewing text and image files within the
browser [#773] (Inria)
* Widgets: MyProjects: only display active projects (Inria)
* SCM SVN: fix double-compression in ViewVC (Inria)
* SCM SVN: support files with spaces in ViewVC (Inria)
diff --git a/src/common/include/utils.php b/src/common/include/utils.php
index 610742cc..77c6bf6 100644
--- a/src/common/include/utils.php
+++ b/src/common/include/utils.php
@@ -1830,6 +1830,39 @@ function getThemeIdFromName($dirname) {
return db_result($res,0,'theme_id');
}
+/**
+ * Generate attachment download headers, with security checks around the MIME
type
+ */
+function utils_headers_download($filename, $mimetype, $size) {
+ /* SECURITY: do not serve content with JavaScript execution (and e.g.
cookie theft) */
+ /* Namely do NOT include: text/html, image/svg+xml, application/pdf...
*/
+ /* https://grepular.com/Scalable_Vector_Graphics_and_XSS */
+ /*
https://lists.wikimedia.org/pipermail/mediawiki-announce/2015-March/000175.html
*/
+ /* https://www.owasp.org/images/a/ac/PDF_XSS_vulnerability.pdf */
+ /*
https://groups.google.com/forum/#!topic/mozilla.dev.pdf-js/Fyl5RnaUWVc */
+ /* (PDF theoretically supports JS, not sure how pdf.js deals with that)
*/
+ $authorized_inline = ',^(text/plain|image/png|image/jpg|image/gif)$,';
+ /* Disarm XSS-able text/html, and inline common text files (*.c,
*.pl...) */
+ $force_text_plain =
',^(text/html|text/.*|application/x-perl|application/x-ruby)$,';
+
+ if (preg_match($force_text_plain, $mimetype))
+ $mimetype = 'text/plain';
+
+ if (preg_match($authorized_inline, $mimetype)) {
+ header('Content-Disposition: inline; filename="' .
str_replace('"', '', $filename) . '"');
+ header('Content-Type: '. $mimetype);
+ } else {
+ header('Content-Disposition: attachment; filename="' .
str_replace('"', '', $filename) . '"');
+ header('Content-Type: '. $mimetype);
+ }
+ header('Content-Length: ' . $size);
+
+ /* Also, make sure browsers such as IE8 don't interpret a non text/html
attachment as HTML... */
+ /*
https://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx?Redirected=true
*/
+ /* IE6 ignores this, but IE6 users have higher security concerns than
this.. */
+ header('X-Content-Type-Options: nosniff');
+}
+
// Local Variables:
// mode: php
// c-file-style: "bsd"
diff --git a/src/www/docman/view.php b/src/www/docman/view.php
index f7e3e69..6acfd03 100644
--- a/src/www/docman/view.php
+++ b/src/www/docman/view.php
@@ -84,16 +84,12 @@ if (is_numeric($docid)) {
if ($d->getFileName() != $docname) {
session_redirect('/docman/view.php/'.$group_id.'/'.$docid.'/'.urlencode($d->getFileName()));
}
-
- header('Content-disposition: attachment; filename="'.str_replace('"',
'', $d->getFileName()) . '"');
- header("Content-type: ".$d->getFileType());
- header("Content-Transfer-Encoding: binary");
ob_end_clean();
$file_path = $d->getFilePath();
$length = filesize($file_path);
$d->downloadUp();
- header("Content-length: $length");
+ utils_headers_download($d->getFileName(), $d->getFileType(), $length);
readfile_chunked($file_path);
} elseif ($docid === 'backup') {
diff --git a/src/www/forum/attachment.php b/src/www/forum/attachment.php
index ceacc73..fabc6b9 100644
--- a/src/www/forum/attachment.php
+++ b/src/www/forum/attachment.php
@@ -189,22 +189,10 @@ $sysdebug_enable = false;
$last = gmdate('D, d M Y H:i:s', db_result($res,0,'dateline'));
header('Last-Modified: ' . $last . ' GMT');
header('ETag: "' .
db_result($res,0,'attachmentid').db_result($res,0,'filehash') . '"');
-$extension = substr(strrchr(strtolower(db_result($res,0,'filename')), '.'), 1);
-if ($extension != 'txt') {
- header("Content-disposition: inline; filename=\"" .
db_result($res,0,'filename') . "\"");
- header('Content-transfer-encoding: binary');
-} else {
- header("Content-disposition: attachment; filename=\"" .
db_result($res,0,'filename') . "\"");
-}
-
-header('Content-Length: ' . db_result($res,0,'filesize') );
-
+$filename = db_result($res,0,'filename');
$mimetype = db_result($res,0,'mimetype');
-if ($mimetype) {
- header('Content-type: '.$mimetype);
-} else {
- header('Content-type: application/octet-stream');
-}
+$filesize = db_result($res,0,'filesize');
+utils_headers_download($filename, $mimetype, $filesize);
if ($pending) {
readfile_chunked(ForumPendingStorage::instance()->get($attachid));
diff --git a/src/www/frs/download.php b/src/www/frs/download.php
index 122cc0f..f32f659 100644
--- a/src/www/frs/download.php
+++ b/src/www/frs/download.php
@@ -47,10 +47,8 @@ function send_file($filename, $filepath, $file_id = NULL,
$mode = NULL) {
session_redirect404();
}
- header('Content-disposition: attachment; filename="'.str_replace('"',
'', $filename).'"');
- sysdebug_off("Content-type: application/binary");
$length = filesize($filepath);
- header("Content-length: $length");
+ utils_headers_download($filename, 'application/binary', $length);
readfile_chunked($filepath);
diff --git a/src/www/tracker/download.php b/src/www/tracker/download.php
index 5df0a2c..4aaa04c 100644
--- a/src/www/tracker/download.php
+++ b/src/www/tracker/download.php
@@ -57,12 +57,7 @@ if (!$ah || !is_object($ah)) {
} elseif ($afh->isError()) {
exit_error($afh->getErrorMessage(),'tracker');
} else {
- Header('Content-disposition: filename="'.str_replace('"', '',
$afh->getName()).'"');
- /* SECURITY: do not serve as $afh->getType() but
application/octet-stream */
- header('X-Content-Type-Options: nosniff');
- header('Content-Type: application/octet-stream');
- header("Content-length: ".$afh->getSize());
-
+ utils_headers_download($afh->getName(), $afh->getType(),
$afh->getSize());
readfile_chunked($afh->getFile());
}
}
-----------------------------------------------------------------------
Summary of changes:
src/CHANGES | 1 +
src/common/include/utils.php | 33 +++++++++++++++++++++++++++++++++
src/www/docman/view.php | 6 +-----
src/www/forum/attachment.php | 18 +++---------------
src/www/frs/download.php | 4 +---
src/www/tracker/download.php | 7 +------
6 files changed, 40 insertions(+), 29 deletions(-)
diff --git a/src/CHANGES b/src/CHANGES
index 6782b31..caa1fee 100644
--- a/src/CHANGES
+++ b/src/CHANGES
@@ -8,6 +8,7 @@ FusionForge 6.0.1:
* Tracker: fix description re-html-ization when editing item (Inria)
* Tracker: fix HTML entities in mail notifications (Inria)
* Tracker: provide a "Submit" button below the "add a comment" field [#776]
(TrivialDev)
+* Tracker/FRS/Docman/Forum: allow viewing text and image files within the
browser [#773] (Inria)
* Widgets: MyProjects: only display active projects (Inria)
* SCM SVN: fix double-compression in ViewVC (Inria)
* SCM SVN: support files with spaces in ViewVC (Inria)
diff --git a/src/common/include/utils.php b/src/common/include/utils.php
index 610742cc..77c6bf6 100644
--- a/src/common/include/utils.php
+++ b/src/common/include/utils.php
@@ -1830,6 +1830,39 @@ function getThemeIdFromName($dirname) {
return db_result($res,0,'theme_id');
}
+/**
+ * Generate attachment download headers, with security checks around the MIME
type
+ */
+function utils_headers_download($filename, $mimetype, $size) {
+ /* SECURITY: do not serve content with JavaScript execution (and e.g.
cookie theft) */
+ /* Namely do NOT include: text/html, image/svg+xml, application/pdf...
*/
+ /* https://grepular.com/Scalable_Vector_Graphics_and_XSS */
+ /*
https://lists.wikimedia.org/pipermail/mediawiki-announce/2015-March/000175.html
*/
+ /* https://www.owasp.org/images/a/ac/PDF_XSS_vulnerability.pdf */
+ /*
https://groups.google.com/forum/#!topic/mozilla.dev.pdf-js/Fyl5RnaUWVc */
+ /* (PDF theoretically supports JS, not sure how pdf.js deals with that)
*/
+ $authorized_inline = ',^(text/plain|image/png|image/jpg|image/gif)$,';
+ /* Disarm XSS-able text/html, and inline common text files (*.c,
*.pl...) */
+ $force_text_plain =
',^(text/html|text/.*|application/x-perl|application/x-ruby)$,';
+
+ if (preg_match($force_text_plain, $mimetype))
+ $mimetype = 'text/plain';
+
+ if (preg_match($authorized_inline, $mimetype)) {
+ header('Content-Disposition: inline; filename="' .
str_replace('"', '', $filename) . '"');
+ header('Content-Type: '. $mimetype);
+ } else {
+ header('Content-Disposition: attachment; filename="' .
str_replace('"', '', $filename) . '"');
+ header('Content-Type: '. $mimetype);
+ }
+ header('Content-Length: ' . $size);
+
+ /* Also, make sure browsers such as IE8 don't interpret a non text/html
attachment as HTML... */
+ /*
https://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx?Redirected=true
*/
+ /* IE6 ignores this, but IE6 users have higher security concerns than
this.. */
+ header('X-Content-Type-Options: nosniff');
+}
+
// Local Variables:
// mode: php
// c-file-style: "bsd"
diff --git a/src/www/docman/view.php b/src/www/docman/view.php
index f7e3e69..6acfd03 100644
--- a/src/www/docman/view.php
+++ b/src/www/docman/view.php
@@ -84,16 +84,12 @@ if (is_numeric($docid)) {
if ($d->getFileName() != $docname) {
session_redirect('/docman/view.php/'.$group_id.'/'.$docid.'/'.urlencode($d->getFileName()));
}
-
- header('Content-disposition: attachment; filename="'.str_replace('"',
'', $d->getFileName()) . '"');
- header("Content-type: ".$d->getFileType());
- header("Content-Transfer-Encoding: binary");
ob_end_clean();
$file_path = $d->getFilePath();
$length = filesize($file_path);
$d->downloadUp();
- header("Content-length: $length");
+ utils_headers_download($d->getFileName(), $d->getFileType(), $length);
readfile_chunked($file_path);
} elseif ($docid === 'backup') {
diff --git a/src/www/forum/attachment.php b/src/www/forum/attachment.php
index ceacc73..fabc6b9 100644
--- a/src/www/forum/attachment.php
+++ b/src/www/forum/attachment.php
@@ -189,22 +189,10 @@ $sysdebug_enable = false;
$last = gmdate('D, d M Y H:i:s', db_result($res,0,'dateline'));
header('Last-Modified: ' . $last . ' GMT');
header('ETag: "' .
db_result($res,0,'attachmentid').db_result($res,0,'filehash') . '"');
-$extension = substr(strrchr(strtolower(db_result($res,0,'filename')), '.'), 1);
-if ($extension != 'txt') {
- header("Content-disposition: inline; filename=\"" .
db_result($res,0,'filename') . "\"");
- header('Content-transfer-encoding: binary');
-} else {
- header("Content-disposition: attachment; filename=\"" .
db_result($res,0,'filename') . "\"");
-}
-
-header('Content-Length: ' . db_result($res,0,'filesize') );
-
+$filename = db_result($res,0,'filename');
$mimetype = db_result($res,0,'mimetype');
-if ($mimetype) {
- header('Content-type: '.$mimetype);
-} else {
- header('Content-type: application/octet-stream');
-}
+$filesize = db_result($res,0,'filesize');
+utils_headers_download($filename, $mimetype, $filesize);
if ($pending) {
readfile_chunked(ForumPendingStorage::instance()->get($attachid));
diff --git a/src/www/frs/download.php b/src/www/frs/download.php
index 122cc0f..f32f659 100644
--- a/src/www/frs/download.php
+++ b/src/www/frs/download.php
@@ -47,10 +47,8 @@ function send_file($filename, $filepath, $file_id = NULL,
$mode = NULL) {
session_redirect404();
}
- header('Content-disposition: attachment; filename="'.str_replace('"',
'', $filename).'"');
- sysdebug_off("Content-type: application/binary");
$length = filesize($filepath);
- header("Content-length: $length");
+ utils_headers_download($filename, 'application/binary', $length);
readfile_chunked($filepath);
diff --git a/src/www/tracker/download.php b/src/www/tracker/download.php
index 5df0a2c..4aaa04c 100644
--- a/src/www/tracker/download.php
+++ b/src/www/tracker/download.php
@@ -57,12 +57,7 @@ if (!$ah || !is_object($ah)) {
} elseif ($afh->isError()) {
exit_error($afh->getErrorMessage(),'tracker');
} else {
- Header('Content-disposition: filename="'.str_replace('"', '',
$afh->getName()).'"');
- /* SECURITY: do not serve as $afh->getType() but
application/octet-stream */
- header('X-Content-Type-Options: nosniff');
- header('Content-Type: application/octet-stream');
- header("Content-length: ".$afh->getSize());
-
+ utils_headers_download($afh->getName(), $afh->getType(),
$afh->getSize());
readfile_chunked($afh->getFile());
}
}
hooks/post-receive
--
FusionForge
_______________________________________________
Fusionforge-commits mailing list
[email protected]
http://lists.fusionforge.org/cgi-bin/mailman/listinfo/fusionforge-commits