* @return mixed True if the file is verified, an array otherwise
*/
protected function verifyMimeType( $mime ) {
- global $wgVerifyMimeType;
+ global $wgVerifyMimeType, $wgVerifyMimeTypeIE;
if ( $wgVerifyMimeType ) {
wfDebug( "mime: <$mime> extension: <{$this->mFinalExtension}>\n" );
global $wgMimeTypeBlacklist;
return [ 'filetype-badmime', $mime ];
}
- # Check what Internet Explorer would detect
- $fp = fopen( $this->mTempPath, 'rb' );
- $chunk = fread( $fp, 256 );
- fclose( $fp );
-
- $magic = MediaWiki\MediaWikiServices::getInstance()->getMimeAnalyzer();
- $extMime = $magic->guessTypesForExtension( $this->mFinalExtension );
- $ieTypes = $magic->getIEMimeTypes( $this->mTempPath, $chunk, $extMime );
- foreach ( $ieTypes as $ieType ) {
- if ( $this->checkFileExtension( $ieType, $wgMimeTypeBlacklist ) ) {
- return [ 'filetype-bad-ie-mime', $ieType ];
+ if ( $wgVerifyMimeTypeIE ) {
+ # Check what Internet Explorer would detect
+ $fp = fopen( $this->mTempPath, 'rb' );
+ $chunk = fread( $fp, 256 );
+ fclose( $fp );
+
+ $magic = MediaWiki\MediaWikiServices::getInstance()->getMimeAnalyzer();
+ $extMime = $magic->guessTypesForExtension( $this->mFinalExtension );
+ $ieTypes = $magic->getIEMimeTypes( $this->mTempPath, $chunk, $extMime );
+ foreach ( $ieTypes as $ieType ) {
+ if ( $this->checkFileExtension( $ieType, $wgMimeTypeBlacklist ) ) {
+ return [ 'filetype-bad-ie-mime', $ieType ];
+ }
}
}
}
*
* @param string[] $ext
* @param string[] $list
- * @return bool
+ * @return string[]
*/
public static function checkFileExtensionList( $ext, $list ) {
return array_intersect( array_map( 'strtolower', $ext ), $list );
* @return bool True if the file contains something looking like embedded scripts
*/
public static function detectScript( $file, $mime, $extension ) {
- global $wgAllowTitlesInSVG;
-
# ugly hack: for text files, always look at the entire file.
# For binary field, just check the first K.
- if ( strpos( $mime, 'text/' ) === 0 ) {
+ $isText = strpos( $mime, 'text/' ) === 0;
+ if ( $isText ) {
$chunk = file_get_contents( $file );
} else {
$fp = fopen( $file, 'rb' );
}
}
- /**
- * 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.
- *
- * Apple's Safari browser also performs some unsafe file type autodetection
- * which can cause legitimate files to be interpreted as HTML if the
- * web server is not correctly configured to send the right content-type
- * (or if you're really uploading plain text and octet streams!)
- *
- * Returns true if IE is likely to mistake the given file for HTML.
- * Also returns true if Safari would mistake the given file for HTML
- * when served with a generic content-type.
- */
+ // Quick check for HTML heuristics in old IE and Safari.
+ //
+ // The exact heuristics IE uses are checked separately via verifyMimeType(), so we
+ // don't need them all here as it can cause many false positives.
+ //
+ // Check for `<script` and such still to forbid script tags and embedded HTML in SVG:
$tags = [
- '<a href',
'<body',
'<head',
'<html', # also in safari
- '<img',
- '<pre',
'<script', # also in safari
- '<table'
];
- if ( !$wgAllowTitlesInSVG && $extension !== 'svg' && $mime !== 'image/svg' ) {
- $tags[] = '<title';
- }
-
foreach ( $tags as $tag ) {
if ( strpos( $chunk, $tag ) !== false ) {
wfDebug( __METHOD__ . ": found something that may make it be mistaken for html: $tag\n" );
/**
* @param string $filename
* @param bool $partial
- * @return mixed False of the file is verified (does not contain scripts), array otherwise.
+ * @return bool|array
*/
protected function detectScriptInSvg( $filename, $partial ) {
$this->mSVGNSError = false;
* Callback to filter SVG Processing Instructions.
* @param string $target Processing instruction name
* @param string $data Processing instruction attribute and value
- * @return bool (true if the filter identified something bad)
+ * @return bool|array
*/
public static function checkSvgPICallback( $target, $data ) {
// Don't allow external stylesheets (T59550)
* @param string $element
* @param array $attribs
* @param array|null $data
- * @return bool
+ * @return bool|array
*/
public function checkSvgScriptCallback( $element, $attribs, $data = null ) {
list( $namespace, $strippedElement ) = $this->splitXmlNamespace( $element );
* $wgAntivirusRequired may be used to deny upload if the scan fails.
*
* @param string $file Pathname to the temporary upload file
- * @return mixed False if not virus is found, null if the scan fails or is disabled,
+ * @return bool|null|string False if not virus is found, null if the scan fails or is disabled,
* or a string containing feedback from the virus scanner if a virus was found.
* If textual feedback is missing but a virus was found, this function returns true.
*/
*
* @param User $user
*
- * @return mixed True on success, array on failure
+ * @return bool|array
*/
private function checkOverwrite( $user ) {
// First check whether the local file can be overwritten
$partname = $n ? substr( $filename, 0, $n ) : $filename;
return (
- substr( $partname, 3, 3 ) == 'px-' ||
- substr( $partname, 2, 3 ) == 'px-'
- ) &&
- preg_match( "/[0-9]{2}/", substr( $partname, 0, 2 ) );
+ substr( $partname, 3, 3 ) == 'px-' ||
+ substr( $partname, 2, 3 ) == 'px-'
+ ) &&
+ preg_match( "/[0-9]{2}/", substr( $partname, 0, 2 ) );
}
/**