| 1 file.test | public FileUploadSvgTestCase::testSVGFileUploadValidation() |
Test SVG upload validation.
File
- core/
modules/ file/ tests/ file.test, line 3040 - Tests for file.module.
Class
- FileUploadSvgTestCase
- Tests validation of SVG uploads.
Code
public function testSVGFileUploadValidation() {
$default_content = '<rect width="400" height="400" fill="#93a7ac"/>';
$default_open_tag = '<svg width="400" height="400" version="1.1" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">';
// cspell:disable-next-line
$a_tag_svg_href_content = '%3Csvg+xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22+onload%3D%22alert%281%29%22%3E%3C%2Fsvg%3E';
$samples = array(
'valid' => array(
'contents' => $default_open_tag . $default_content . '</svg>',
'message' => 'was uploaded.',
),
'no_dimensions' => array(
'contents' => '<svg version="1.1" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">' . $default_content . '</svg>',
'message' => 'was uploaded.',
),
'no_namespace_script' => array(
'contents' => '<svg><script>alert(1)</script>' . $default_content . '</svg>',
'message' => 'could not be uploaded. Invalid SVG namespace.',
),
'invalid_namespace' => array(
'contents' => $default_open_tag . '<g xmlns="invalid ns"/>' . $default_content . '</svg>',
'message' => 'could not be uploaded. Invalid SVG file.',
),
'broken' => array(
'contents' => $default_open_tag . '<g>' . $default_content . '</svg>',
'message' => 'could not be uploaded. Invalid SVG file.',
),
'not_svg' => array(
'contents' => '<xml><foobar/></xml>',
'message' => 'could not be uploaded. Invalid SVG namespace.',
),
'onevent' => array(
'contents' => $default_open_tag . '<rect width="400" height="400" onload="alert(1)" fill="#93a7ac"/></svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'iframe' => array(
'contents' => $default_open_tag . $default_content . '<foreignObject x="20" y="20" width="220" height="220"><iframe src="https://example.org/" width="220" height="220"></iframe></foreignObject></svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'script' => array(
'contents' => $default_open_tag . $default_content . '<script>alert(1)</script></svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'xlink_script' => array(
'contents' => '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><a xlink:href="javascript:alert(1)">test</a>' . $default_content . '</svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'link_data' => array(
'contents' => $default_open_tag . $default_content . '<a href="data:image/svg+xml,' . $a_tag_svg_href_content . '"></a></svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'link_safe' => array(
'contents' => '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><a href="https://example.com/?a=1&b=2"><text>test</text></a><a xlink:href="#test">test</a>' . $default_content . '</svg>',
'message' => 'was uploaded.',
),
'cdata_style' => array(
'contents' => $default_open_tag . '<style><![CDATA[ rect { fill: #93a7ac; } ]]></style>' . $default_content . '</svg>',
'message' => 'was uploaded.',
),
'embedded_image' => array(
'contents' => '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><image xlink:href="data:image/png;base64,iVBORw0KGgo=" width="1" height="1"/></svg>',
'message' => 'was uploaded.',
),
'link_whitespace_script' => array(
'contents' => $default_open_tag . $default_content . '<a href="jav	ascript:alert(1)"><text>test</text></a></svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'xlink_nested_namespace_script' => array(
'contents' => $default_open_tag . $default_content . '<a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="javascript:alert(1)"><text>test</text></a></svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'xlink_prefix_script' => array(
'contents' => '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:foo="http://www.w3.org/1999/xlink"><a foo:href="javascript:alert(1)"><text>test</text></a>' . $default_content . '</svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'encoded_comment_script' => array(
'contents' => $default_open_tag . $default_content . '<text><!--</text><script>alert(1)</script><text>--></text></svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'animate_script' => array(
'contents' => '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><a id="test" xlink:href="#"><text>test</text></a><animate xlink:href="#test" attributeName="href" values="javascript:alert(1)" begin="0s"/>' . $default_content . '</svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'animate_child_script' => array(
'contents' => $default_open_tag . '<a><animate attributeName="href" dur="10s" begin="0s" fill="freeze" values="javascript:alert(1)"/>' . $default_content . '</a></svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'set_script' => array(
'contents' => $default_open_tag . '<a><set attributeName="href" begin="0s" to="javascript:alert(1)"/>' . $default_content . '</a></svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'xhtml_namespace_script' => array(
'contents' => '<?xml version="1.0"?>' . $default_open_tag . '<script xmlns="http://www.w3.org/1999/xhtml">alert(1)</script>' . $default_content . '</svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'animate_transform' => array(
'contents' => $default_open_tag . $default_content . '<animateTransform attributeName="transform" type="rotate" from="0" to="360"/></svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'comments_metadata' => array(
'contents' => '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"><!-- Generator: Test --><title>Test</title><desc>A test image</desc><metadata><rdf:RDF><rdf:Description><dc:title><rdf:Alt><rdf:li>Test</rdf:li></rdf:Alt></dc:title></rdf:Description></rdf:RDF></metadata>' . $default_content . '</svg>',
'message' => 'was uploaded.',
),
'processing_instruction' => array(
'contents' => $default_open_tag . '<?x ><img src onerror=alert(1)><?x?>' . $default_content . '</svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'abrupt_comment' => array(
'contents' => $default_open_tag . '<!--><img src=x onerror=alert(1)>-->' . $default_content . '</svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'html_breakout' => array(
'contents' => $default_open_tag . '<p/><style><![CDATA[</style><img src=x onerror=alert(1)>]]></style>' . $default_content . '</svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'desc_element' => array(
'contents' => $default_open_tag . '<desc><style><![CDATA[</style><img src=x onerror=alert(1)>]]></style></desc>' . $default_content . '</svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'doctype_breakout' => array(
'contents' => '<!DOCTYPE svg SYSTEM "><img src=x onerror=alert(1)>">' . $default_open_tag . $default_content . '</svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'title_cdata' => array(
'contents' => $default_open_tag . '<title><![CDATA[</title><script>alert(1)</script>]]></title>' . $default_content . '</svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'xml_events' => array(
'contents' => '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" id="test"><x xmlns="http://www.w3.org/2001/xml-events" event="load" observer="test" handler="#test"/>' . $default_content . '</svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'xinclude' => array(
'contents' => '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xi="http://www.w3.org/2001/XInclude"><text><xi:include href="/etc/passwd" parse="text"/></text>' . $default_content . '</svg>',
'message' => 'could not be uploaded. Dangerous content found.',
),
'entity_script' => array(
'contents' => '<!DOCTYPE svg [<!ENTITY a "javascript:">]>' . $default_open_tag . '<a href="&a;alert(1)"><text>test</text></a></svg>',
'message' => 'could not be uploaded. Invalid SVG file.',
),
);
foreach ($samples as $sample => $settings) {
$filename = $sample . '.svg';
$filepath = $this->createSvgFile($settings + array('filepath' => $filename));
// Upload an SVG file.
$edit = array();
$edit['files[upload][]'] = backdrop_realpath($filepath);
$this->backdropPost('file/add', $edit, t('Next'));
// Check that the file exists in the database.
$fid = $this->getLastFileId();
$file = file_load($fid);
$this->assertTrue($file, t('SVG file found in database.'));
// Check that the SVG file has been validated.
$this->assertRaw(t('%name ' . $settings['message'], array('%name' => $filename)), t('File validated.'));
}
}