* @access private
*/
function processUpload() {
- global $wgUser, $wgOut, $wgLang;
+ global $wgUser, $wgOut, $wgLang, $wgContLang;
global $wgUploadDirectory;
global $wgSavedFile, $wgUploadOldVersion;
global $wgUseCopyrightUpload, $wgCheckCopyrightUpload;
return $this->uploadError( wfMsg( 'badfiletype', htmlspecialchars( $ext ) ) );
}
+ if( !$this->verify( $this->mUploadTempName, $ext ) ) {
+ return $this->uploadError( wfMsg( 'uploadcorrupt' ) );
+ }
+
$this->saveUploadedFile( $this->mUploadSaveName, $this->mUploadTempName );
if ( !$nt->userCanEdit() ) {
return $this->uploadError( wfMsg( 'protectedpage' ) );
}
if( $nt->getArticleID() ) {
$sk = $wgUser->getSkin();
- $dname = $wgLang->getNsText( Namespace::getImage() ) .':'.$this->mUploadSaveName;
+ $dname = $wgContLang->getNsText( Namespace::getImage() ) .':'.$this->mUploadSaveName;
$dlink = $sk->makeKnownLink( $dname, $dname );
$warning .= '<li>'.wfMsg( 'fileexists', $dlink ).'</li>';
}
$sk = $wgUser->getSkin();
$ilink = $sk->makeMediaLink( $this->mUploadSaveName, Image::wfImageUrl( $this->mUploadSaveName ) );
- $dname = $wgLang->getNsText( Namespace::getImage() ) . ':'.$this->mUploadSaveName;
+ $dname = $wgContLang->getNsText( Namespace::getImage() ) . ':'.$this->mUploadSaveName;
$dlink = $sk->makeKnownLink( $dname, $dname );
$wgOut->addHTML( '<h2>' . wfMsg( 'successfulupload' ) . "</h2>\n" );
$fd = wfMsg( 'filedesc' );
$ulb = wfMsg( 'uploadbtn' );
- $clink = $sk->makeKnownLink( wfMsg( 'copyrightpage' ),
+ $clink = $sk->makeKnownLink( wfMsgForContent( 'copyrightpage' ),
wfMsg( 'copyrightpagename' ) );
$ca = wfMsg( 'affirmation', $clink );
$iw = wfMsg( 'ignorewarning' );
<input tabindex='5' type='submit' name=\"wpUpload\" value=\"{$ulb}\" />
</td></tr></table></form>\n" );
}
+
+ /**
+ * Returns false if the file is of a known type but can't be recognized,
+ * indicating a corrupt file.
+ * Returns true otherwise; unknown file types are not checked if given
+ * with an unrecognized extension.
+ *
+ * @param string $tmpfile Pathname to the temporary upload file
+ * @param string $extension The filename extension that the file is to be served with
+ * @return bool
+ */
+ function verify( $tmpfile, $extension ) {
+ if( $this->triggersIEbug( $tmpfile ) ) {
+ return false;
+ }
+
+ $fname = 'SpecialUpload::verify';
+ $mergeExtensions = array(
+ 'jpg' => 'jpeg',
+ 'tif' => 'tiff' );
+ $extensionTypes = array(
+ # See http://www.php.net/getimagesize
+ 1 => 'gif',
+ 2 => 'jpeg',
+ 3 => 'png',
+ 4 => 'swf',
+ 5 => 'psd',
+ 6 => 'bmp',
+ 7 => 'tiff',
+ 8 => 'tiff',
+ 9 => 'jpc',
+ 10 => 'jp2',
+ 11 => 'jpx',
+ 12 => 'jb2',
+ 13 => 'swc',
+ 14 => 'iff',
+ 15 => 'wbmp',
+ 16 => 'xbm' );
+
+ $extension = strtolower( $extension );
+ if( isset( $mergeExtensions[$extension] ) ) {
+ $extension = $mergeExtensions[$extension];
+ }
+ wfDebug( "$fname: Testing file '$tmpfile' with given extension '$extension'\n" );
+
+ if( !in_array( $extension, $extensionTypes ) ) {
+ # Not a recognized image type. We don't know how to verify these.
+ # They're allowed by policy or they wouldn't get this far, so we'll
+ # let them slide for now.
+ wfDebug( "$fname: Unknown extension; passing.\n" );
+ return true;
+ }
+
+ $data = @getimagesize( $tmpfile );
+ if( false === $data ) {
+ # Didn't recognize the image type.
+ # Either the image is corrupt or someone's slipping us some
+ # bogus data such as HTML+JavaScript trying to take advantage
+ # of an Internet Explorer security flaw.
+ wfDebug( "$fname: getimagesize() doesn't recognize the file; rejecting.\n" );
+ return false;
+ }
+
+ $imageType = $data[2];
+ if( !isset( $extensionTypes[$imageType] ) ) {
+ # Now we're kind of confused. Perhaps new image types added
+ # to PHP's support that we don't know about.
+ # We'll let these slide for now.
+ wfDebug( "$fname: getimagesize() knows the file, but we don't recognize the type; passing.\n" );
+ return true;
+ }
+
+ $ext = strtolower( $extension );
+ if( $extension != $extensionTypes[$imageType] ) {
+ # The given filename extension doesn't match the
+ # file type. Probably just a mistake, but it's a stupid
+ # one and we shouldn't let it pass. KILL THEM!
+ wfDebug( "$fname: file extension does not match recognized type; rejecting.\n" );
+ return false;
+ }
+
+ wfDebug( "$fname: all clear; passing.\n" );
+ return true;
+ }
+
+ /**
+ * Internet Explorer for Windows performs some really stupid file type
+ * autodetection which can cause it to interpret valid image files as HTML
+ * and potentially execute JavaScript, creating a cross-site scripting
+ * attack vectors.
+ *
+ * Returns true if IE is likely to mistake the given file for HTML.
+ *
+ * @param string $filename
+ * @return bool
+ */
+ function triggersIEbug( $filename ) {
+ $file = fopen( $filename, 'rb' );
+ $chunk = strtolower( fread( $file, 200 ) );
+ fclose( $file );
+
+ $tags = array( '<html', '<head', '<body', '<script' );
+ foreach( $tags as $tag ) {
+ if( false !== strpos( $chunk, $tag ) ) {
+ return true;
+ }
+ }
+ return false;
+ }
}
?>