aboutsummaryrefslogtreecommitdiffhomepage
path: root/inc
diff options
context:
space:
mode:
authortcitworld <tcit@tcit.fr>2014-05-20 11:55:20 +0200
committertcitworld <tcit@tcit.fr>2014-05-20 11:55:20 +0200
commit88f0e316225a3e9c98f5dbcf0ee8749d8eab55a5 (patch)
tree237c4f0b59423694b0b0820e009a6264927588a3 /inc
parent04b43dc097c3d69fd42d724b2cf082aff86d7272 (diff)
parent38eecef26ba33a052475c52dead699e434b2362a (diff)
downloadwallabag-88f0e316225a3e9c98f5dbcf0ee8749d8eab55a5.tar.gz
wallabag-88f0e316225a3e9c98f5dbcf0ee8749d8eab55a5.tar.zst
wallabag-88f0e316225a3e9c98f5dbcf0ee8749d8eab55a5.zip
Merge pull request #703 from tcitworld/images_security
Security fixes for downloaded images (thanks @leblanc-simon)
Diffstat (limited to 'inc')
-rwxr-xr-xinc/poche/config.inc.default.php3
-rw-r--r--inc/poche/pochePictures.php58
2 files changed, 55 insertions, 6 deletions
diff --git a/inc/poche/config.inc.default.php b/inc/poche/config.inc.default.php
index edc42fc9..ffcd205d 100755
--- a/inc/poche/config.inc.default.php
+++ b/inc/poche/config.inc.default.php
@@ -30,7 +30,8 @@
30 30
31@define ('MODE_DEMO', FALSE); 31@define ('MODE_DEMO', FALSE);
32@define ('DEBUG_POCHE', FALSE); 32@define ('DEBUG_POCHE', FALSE);
33@define ('DOWNLOAD_PICTURES', FALSE); 33@define ('DOWNLOAD_PICTURES', FALSE); # This can slow down the process of adding articles
34@define ('REGENERATE_PICTURES_QUALITY', 75);
34@define ('CONVERT_LINKS_FOOTNOTES', FALSE); 35@define ('CONVERT_LINKS_FOOTNOTES', FALSE);
35@define ('REVERT_FORCED_PARAGRAPH_ELEMENTS', FALSE); 36@define ('REVERT_FORCED_PARAGRAPH_ELEMENTS', FALSE);
36@define ('SHARE_TWITTER', TRUE); 37@define ('SHARE_TWITTER', TRUE);
diff --git a/inc/poche/pochePictures.php b/inc/poche/pochePictures.php
index e4b0b160..7c319a85 100644
--- a/inc/poche/pochePictures.php
+++ b/inc/poche/pochePictures.php
@@ -14,6 +14,7 @@
14function filtre_picture($content, $url, $id) 14function filtre_picture($content, $url, $id)
15{ 15{
16 $matches = array(); 16 $matches = array();
17 $processing_pictures = array(); // list of processing image to avoid processing the same pictures twice
17 preg_match_all('#<\s*(img)[^>]+src="([^"]*)"[^>]*>#Si', $content, $matches, PREG_SET_ORDER); 18 preg_match_all('#<\s*(img)[^>]+src="([^"]*)"[^>]*>#Si', $content, $matches, PREG_SET_ORDER);
18 foreach($matches as $i => $link) { 19 foreach($matches as $i => $link) {
19 $link[1] = trim($link[1]); 20 $link[1] = trim($link[1]);
@@ -22,8 +23,17 @@ function filtre_picture($content, $url, $id)
22 $filename = basename(parse_url($absolute_path, PHP_URL_PATH)); 23 $filename = basename(parse_url($absolute_path, PHP_URL_PATH));
23 $directory = create_assets_directory($id); 24 $directory = create_assets_directory($id);
24 $fullpath = $directory . '/' . $filename; 25 $fullpath = $directory . '/' . $filename;
25 download_pictures($absolute_path, $fullpath); 26
26 $content = str_replace($matches[$i][2], $fullpath, $content); 27 if (in_array($absolute_path, $processing_pictures) === true) {
28 // replace picture's URL only if processing is OK : already processing -> go to next picture
29 continue;
30 }
31
32 if (download_pictures($absolute_path, $fullpath) === true) {
33 $content = str_replace($matches[$i][2], $fullpath, $content);
34 }
35
36 $processing_pictures[] = $absolute_path;
27 } 37 }
28 38
29 } 39 }
@@ -64,17 +74,55 @@ function get_absolute_link($relative_link, $url) {
64 74
65/** 75/**
66 * Téléchargement des images 76 * Téléchargement des images
77 *
78 * @return bool true if the download and processing is OK, false else
67 */ 79 */
68function download_pictures($absolute_path, $fullpath) 80function download_pictures($absolute_path, $fullpath)
69{ 81{
70 $rawdata = Tools::getFile($absolute_path); 82 $rawdata = Tools::getFile($absolute_path);
83 $fullpath = urldecode($fullpath);
71 84
72 if(file_exists($fullpath)) { 85 if(file_exists($fullpath)) {
73 unlink($fullpath); 86 unlink($fullpath);
74 } 87 }
75 $fp = fopen($fullpath, 'x'); 88
76 fwrite($fp, $rawdata); 89 // check extension
77 fclose($fp); 90 $file_ext = strrchr($fullpath, '.');
91 $whitelist = array(".jpg",".jpeg",".gif",".png");
92 if (!(in_array($file_ext, $whitelist))) {
93 Tools::logm('processed image with not allowed extension. Skipping ' . $fullpath);
94 return false;
95 }
96
97 // check headers
98 $imageinfo = getimagesize($absolute_path);
99 if ($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg'&& $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {
100 Tools::logm('processed image with bad header. Skipping ' . $fullpath);
101 return false;
102 }
103
104 // regenerate image
105 $im = imagecreatefromstring($rawdata);
106 if ($im === false) {
107 Tools::logm('error while regenerating image ' . $fullpath);
108 return false;
109 }
110
111 switch ($imageinfo['mime']) {
112 case 'image/gif':
113 $result = imagegif($im, $fullpath);
114 break;
115 case 'image/jpeg':
116 case 'image/jpg':
117 $result = imagejpeg($im, $fullpath, REGENERATE_PICTURES_QUALITY);
118 break;
119 case 'image/png':
120 $result = imagepng($im, $fullpath, ceil(REGENERATE_PICTURES_QUALITY / 100 * 9));
121 break;
122 }
123 imagedestroy($im);
124
125 return $result;
78} 126}
79 127
80/** 128/**