mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
[ss-2015-021] Fix rewrite hash links XSS
This commit is contained in:
parent
e68eb7e45d
commit
97f21fddb3
@ -1,11 +1,30 @@
|
||||
<?php
|
||||
|
||||
class SSViewerTest extends SapphireTest {
|
||||
|
||||
/**
|
||||
* Backup of $_SERVER global
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $oldServer = array();
|
||||
|
||||
protected $extraDataObjects = array(
|
||||
'SSViewerTest_Object',
|
||||
);
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
Config::inst()->update('SSViewer', 'source_file_comments', false);
|
||||
Config::inst()->update('SSViewer_FromString', 'cache_template', false);
|
||||
$this->oldServer = $_SERVER;
|
||||
}
|
||||
|
||||
|
||||
public function tearDown() {
|
||||
$_SERVER = $this->oldServer;
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for {@link Config::inst()->get('SSViewer', 'theme')} for different behaviour
|
||||
* of user defined themes via {@link SiteConfig} and default theme
|
||||
@ -1160,10 +1179,13 @@ after')
|
||||
$orig = Config::inst()->get('SSViewer', 'rewrite_hash_links');
|
||||
Config::inst()->update('SSViewer', 'rewrite_hash_links', true);
|
||||
|
||||
$_SERVER['REQUEST_URI'] = 'http://path/to/file?foo"onclick="alert(\'xss\')""';
|
||||
$_SERVER['HTTP_HOST'] = 'www.mysite.com';
|
||||
$_SERVER['REQUEST_URI'] = '//file.com?foo"onclick="alert(\'xss\')""';
|
||||
|
||||
// Emulate SSViewer::process()
|
||||
$base = Convert::raw2att($_SERVER['REQUEST_URI']);
|
||||
// Note that leading double slashes have been rewritten to prevent these being mis-interepreted
|
||||
// as protocol-less absolute urls
|
||||
$base = Convert::raw2att('/file.com?foo"onclick="alert(\'xss\')""');
|
||||
|
||||
$tmplFile = TEMP_FOLDER . '/SSViewerTest_testRewriteHashlinks_' . sha1(rand()) . '.ss';
|
||||
|
||||
@ -1231,10 +1253,11 @@ after')
|
||||
$obj = new ViewableData();
|
||||
$obj->InsertedLink = '<a class="inserted" href="#anchor">InsertedLink</a>';
|
||||
$result = $tmpl->process($obj);
|
||||
$this->assertContains(
|
||||
'<a class="inserted" href="<?php echo Convert::raw2att(',
|
||||
$result
|
||||
);
|
||||
|
||||
$code = <<<'EOC'
|
||||
<a class="inserted" href="<?php echo Convert::raw2att(preg_replace("/^(\/)+/", "/", $_SERVER['REQUEST_URI'])); ?>#anchor">InsertedLink</a>
|
||||
EOC;
|
||||
$this->assertContains($code, $result);
|
||||
// TODO Fix inline links in PHP mode
|
||||
// $this->assertContains(
|
||||
// '<a class="inline" href="<?php echo str_replace(',
|
||||
|
@ -4681,11 +4681,15 @@ class SSTemplateParser extends Parser implements TemplateParser {
|
||||
|
||||
// TODO: This is pretty ugly & gets applied on all files not just html. I wonder if we can make this
|
||||
// non-dynamically calculated
|
||||
$code = <<<'EOC'
|
||||
(\Config::inst()->get('SSViewer', 'rewrite_hash_links')
|
||||
? \Convert::raw2att( preg_replace("/^(\\/)+/", "/", $_SERVER['REQUEST_URI'] ) )
|
||||
: "")
|
||||
EOC;
|
||||
// Because preg_replace replacement requires escaped slashes, addcslashes here
|
||||
$text = preg_replace(
|
||||
'/(<a[^>]+href *= *)"#/i',
|
||||
'\\1"\' . (Config::inst()->get(\'SSViewer\', \'rewrite_hash_links\') ?' .
|
||||
' Convert::raw2att( $_SERVER[\'REQUEST_URI\'] ) : "") .
|
||||
\'#',
|
||||
'\\1"\' . ' . addcslashes($code, '\\') . ' . \'#',
|
||||
$text
|
||||
);
|
||||
|
||||
|
@ -1135,11 +1135,15 @@ class SSTemplateParser extends Parser implements TemplateParser {
|
||||
|
||||
// TODO: This is pretty ugly & gets applied on all files not just html. I wonder if we can make this
|
||||
// non-dynamically calculated
|
||||
$code = <<<'EOC'
|
||||
(\Config::inst()->get('SSViewer', 'rewrite_hash_links')
|
||||
? \Convert::raw2att( preg_replace("/^(\\/)+/", "/", $_SERVER['REQUEST_URI'] ) )
|
||||
: "")
|
||||
EOC;
|
||||
// Because preg_replace replacement requires escaped slashes, addcslashes here
|
||||
$text = preg_replace(
|
||||
'/(<a[^>]+href *= *)"#/i',
|
||||
'\\1"\' . (Config::inst()->get(\'SSViewer\', \'rewrite_hash_links\') ?' .
|
||||
' Convert::raw2att( $_SERVER[\'REQUEST_URI\'] ) : "") .
|
||||
\'#',
|
||||
'\\1"\' . ' . addcslashes($code, '\\') . ' . \'#',
|
||||
$text
|
||||
);
|
||||
|
||||
|
@ -1110,10 +1110,10 @@ class SSViewer implements Flushable {
|
||||
$rewrite = Config::inst()->get('SSViewer', 'rewrite_hash_links');
|
||||
if($this->rewriteHashlinks && $rewrite) {
|
||||
if(strpos($output, '<base') !== false) {
|
||||
if($rewrite === 'php') {
|
||||
$thisURLRelativeToBase = "<?php echo Convert::raw2att(\$_SERVER['REQUEST_URI']); ?>";
|
||||
if($rewrite === 'php') {
|
||||
$thisURLRelativeToBase = "<?php echo Convert::raw2att(preg_replace(\"/^(\\\\/)+/\", \"/\", \$_SERVER['REQUEST_URI'])); ?>";
|
||||
} else {
|
||||
$thisURLRelativeToBase = Convert::raw2att($_SERVER['REQUEST_URI']);
|
||||
$thisURLRelativeToBase = Convert::raw2att(preg_replace("/^(\\/)+/", "/", $_SERVER['REQUEST_URI']));
|
||||
}
|
||||
|
||||
$output = preg_replace('/(<a[^>]+href *= *)"#/i', '\\1"' . $thisURLRelativeToBase . '#', $output);
|
||||
|
Loading…
Reference in New Issue
Block a user