summaryrefslogtreecommitdiff
path: root/includes/upload/UploadBase.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/upload/UploadBase.php')
-rw-r--r--includes/upload/UploadBase.php71
1 files changed, 69 insertions, 2 deletions
diff --git a/includes/upload/UploadBase.php b/includes/upload/UploadBase.php
index 916ad6c1..c0c37b3f 100644
--- a/includes/upload/UploadBase.php
+++ b/includes/upload/UploadBase.php
@@ -44,7 +44,7 @@ abstract class UploadBase {
protected $mFilteredName, $mFinalExtension;
protected $mLocalFile, $mFileSize, $mFileProps;
protected $mBlackListedExtensions;
- protected $mJavaDetected;
+ protected $mJavaDetected, $mSVGNSError;
protected static $safeXmlEncodings = array( 'UTF-8', 'ISO-8859-1', 'ISO-8859-2', 'UTF-16', 'UTF-32' );
@@ -1162,6 +1162,7 @@ abstract class UploadBase {
* @return bool
*/
protected function detectScriptInSvg( $filename ) {
+ $this->mSVGNSError = false;
$check = new XmlTypeCheck(
$filename,
array( $this, 'checkSvgScriptCallback' ),
@@ -1172,6 +1173,9 @@ abstract class UploadBase {
// Invalid xml (bug 58553)
return array( 'uploadinvalidxml' );
} elseif ( $check->filterMatch ) {
+ if ( $this->mSVGNSError ) {
+ return array( 'uploadscriptednamespace', $this->mSVGNSError );
+ }
return array( 'uploadscripted' );
}
return false;
@@ -1198,7 +1202,51 @@ abstract class UploadBase {
* @return bool
*/
public function checkSvgScriptCallback( $element, $attribs ) {
- $strippedElement = $this->stripXmlNamespace( $element );
+ list( $namespace, $strippedElement ) = $this->splitXmlNamespace( $element );
+
+ static $validNamespaces = array(
+ '',
+ 'adobe:ns:meta/',
+ 'http://creativecommons.org/ns#',
+ 'http://inkscape.sourceforge.net/dtd/sodipodi-0.dtd',
+ 'http://ns.adobe.com/adobeillustrator/10.0/',
+ 'http://ns.adobe.com/adobesvgviewerextensions/3.0/',
+ 'http://ns.adobe.com/extensibility/1.0/',
+ 'http://ns.adobe.com/flows/1.0/',
+ 'http://ns.adobe.com/illustrator/1.0/',
+ 'http://ns.adobe.com/imagereplacement/1.0/',
+ 'http://ns.adobe.com/pdf/1.3/',
+ 'http://ns.adobe.com/photoshop/1.0/',
+ 'http://ns.adobe.com/saveforweb/1.0/',
+ 'http://ns.adobe.com/variables/1.0/',
+ 'http://ns.adobe.com/xap/1.0/',
+ 'http://ns.adobe.com/xap/1.0/g/',
+ 'http://ns.adobe.com/xap/1.0/g/img/',
+ 'http://ns.adobe.com/xap/1.0/mm/',
+ 'http://ns.adobe.com/xap/1.0/rights/',
+ 'http://ns.adobe.com/xap/1.0/stype/dimensions#',
+ 'http://ns.adobe.com/xap/1.0/stype/font#',
+ 'http://ns.adobe.com/xap/1.0/stype/manifestitem#',
+ 'http://ns.adobe.com/xap/1.0/stype/resourceevent#',
+ 'http://ns.adobe.com/xap/1.0/stype/resourceref#',
+ 'http://ns.adobe.com/xap/1.0/t/pg/',
+ 'http://purl.org/dc/elements/1.1/',
+ 'http://purl.org/dc/elements/1.1',
+ 'http://schemas.microsoft.com/visio/2003/svgextensions/',
+ 'http://sodipodi.sourceforge.net/dtd/sodipodi-0.dtd',
+ 'http://web.resource.org/cc/',
+ 'http://www.freesoftware.fsf.org/bkchem/cdml',
+ 'http://www.inkscape.org/namespaces/inkscape',
+ 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
+ 'http://www.w3.org/2000/svg',
+ );
+
+ if ( !in_array( $namespace, $validNamespaces ) ) {
+ wfDebug( __METHOD__ . ": Non-svg namespace '$namespace' in uploaded file.\n" );
+ // @TODO return a status object to a closure in XmlTypeCheck, for MW1.21+
+ $this->mSVGNSError = $namespace;
+ return true;
+ }
/*
* check for elements that can contain javascript
@@ -1220,6 +1268,12 @@ abstract class UploadBase {
return true;
}
+ # Block iframes, in case they pass the namespace check
+ if ( $strippedElement == 'iframe' ) {
+ wfDebug( __METHOD__ . ": iframe in uploaded file.\n" );
+ return true;
+ }
+
foreach ( $attribs as $attrib => $value ) {
$stripped = $this->stripXmlNamespace( $attrib );
$value = strtolower( $value );
@@ -1294,6 +1348,19 @@ abstract class UploadBase {
}
/**
+ * Divide the element name passed by the xml parser to the callback into URI and prifix.
+ * @param $name string
+ * @return array containing the namespace URI and prefix
+ */
+ private static function splitXmlNamespace( $element ) {
+ // 'http://www.w3.org/2000/svg:script' -> array( 'http://www.w3.org/2000/svg', 'script' )
+ $parts = explode( ':', strtolower( $element ) );
+ $name = array_pop( $parts );
+ $ns = implode( ':', $parts );
+ return array( $ns, $name );
+ }
+
+ /**
* @param $name string
* @return string
*/