XpressEngine Core  1.11.2
 All Classes Namespaces Files Functions Variables Pages
UploadFileFilter.class.php
Go to the documentation of this file.
1 <?php
7 {
15  public static function check($file, $filename = null)
16  {
17  // Return error if the file is not uploaded.
18  if (!$file || !file_exists($file) || !is_uploaded_file($file))
19  {
20  return false;
21  }
22 
23  // Return error if the file size is zero.
24  if (($filesize = filesize($file)) == 0)
25  {
26  return false;
27  }
28 
29  // Get the extension.
30  $ext = $filename ? strtolower(substr(strrchr($filename, '.'), 1)) : '';
31 
32  // Check the first 4KB of the file for possible XML content.
33  $fp = fopen($file, 'rb');
34  $first4kb = fread($fp, 4096);
35  $is_xml = preg_match('/<(?:\?xml|!DOCTYPE|html|head|body|meta|script|svg)\b/i', $first4kb);
36 
37  // Check SVG files.
38  if (($ext === 'svg' || $is_xml) && !self::_checkSVG($fp, 0, $filesize))
39  {
40  fclose($fp);
41  return false;
42  }
43 
44  // Check XML files.
45  if (($ext === 'xml' || $is_xml) && !self::_checkXML($fp, 0, $filesize))
46  {
47  fclose($fp);
48  return false;
49  }
50 
51  // Check HTML files.
52  if (($ext === 'html' || $ext === 'shtml' || $ext === 'xhtml' || $ext === 'phtml' || $is_xml) && !self::_checkHTML($fp, 0, $filesize))
53  {
54  fclose($fp);
55  return false;
56  }
57 
58  // Return true if everything is OK.
59  fclose($fp);
60  return true;
61  }
62 
71  protected static function _checkSVG($fp, $from, $to)
72  {
73  if (self::_matchStream('/<script|<handler\b|xlink:href\s*=\s*"(?!data:)/i', $fp, $from, $to))
74  {
75  return false;
76  }
77  if (self::_matchStream('/\b(?:ev:(?:event|listener|observer)|on[a-z]+)\s*=/i', $fp, $from, $to))
78  {
79  return false;
80  }
81 
82  return true;
83  }
84 
93  protected static function _checkXML($fp, $from, $to)
94  {
95  if (self::_matchStream('/<!ENTITY/i', $fp, $from, $to))
96  {
97  return false;
98  }
99 
100  return true;
101  }
102 
111  protected static function _checkHTML($fp, $from, $to)
112  {
113  if (self::_matchStream('/<\?(?!xml\b)|<!--#(?:include|exec|echo|config|fsize|flastmod|printenv)\b/i', $fp, $from, $to))
114  {
115  return false;
116  }
117 
118  return true;
119  }
120 
137  protected static function _matchStream($regexp, $fp, $from, $to, $block_size = 16384, $overlap_size = 1024)
138  {
139  fseek($fp, $position = $from);
140  while (strlen($content = fread($fp, $block_size + $overlap_size)) > 0)
141  {
142  if (preg_match($regexp, $content))
143  {
144  return true;
145  }
146  fseek($fp, min($to, $position += $block_size));
147  }
148  return false;
149  }
150 }
151 /* End of file : UploadFileFilter.class.php */
152 /* Location: ./classes/security/UploadFileFilter.class.php */
static _checkHTML($fp, $from, $to)
static _checkXML($fp, $from, $to)
static _checkSVG($fp, $from, $to)
static _matchStream($regexp, $fp, $from, $to, $block_size=16384, $overlap_size=1024)
static check($file, $filename=null)