Skip to content
Browse files

WiP

  • Loading branch information...
1 parent 45aae93 commit a40583c6d3fed67cc99b2843ee2953c6059811cc @JoshyPHP JoshyPHP committed Feb 21, 2012
View
37 docs/testdox.txt
@@ -19,9 +19,44 @@ s9e\TextFormatter\Tests\ConfigBuilder\TemplateChecker
[x] Not safe: <b><xsl:copy-of select=" @ onclick "/></b>
[x] Safe: <b><xsl:copy-of select="@title"/></b>
[x] Safe: <b><xsl:copy-of select=" @ title "/></b>
- [x] Not safe: <a><xsl:copy-of select="@href"/></a>
+ [x] Not safe if attribute 'href' has no filter: <a><xsl:copy-of select="@href"/></a>
[x] Safe if attribute 'href' has filter '#url': <a><xsl:copy-of select="@href"/></a>
[x] Not safe: <xsl:copy-of select="script"/>
[x] Not safe: <xsl:copy-of select=" script "/>
[x] Not safe: <xsl:copy-of select="parent::*"/>
+ [x] Not safe: <script><xsl:apply-templates/></script>
+ [x] Not safe: <script><xsl:apply-templates select="st"/></script>
+ [x] Not safe: <script><xsl:value-of select="st"/></script>
+ [x] Not safe: <script><xsl:value-of select="@foo"/></script>
+ [x] Not safe if attribute 'foo' has no filter: <script><xsl:value-of select="@foo"/></script>
+ [x] Not safe if attribute 'foo' has no filter: <xsl:element name="script"><xsl:value-of select="@foo"/></xsl:element>
+ [x] Not safe if attribute 'foo' has no filter: <xsl:element name="SCRIPT"><xsl:value-of select="@foo"/></xsl:element>
+ [x] Not safe if attribute 'foo' has filter 'urlencode': <script><xsl:for-each select="/*"><xsl:value-of select="@foo"/></xsl:for-each></script>
+ [x] Not safe: <script><xsl:for-each select="/*"><xsl:apply-templates/></xsl:for-each></script>
+ [x] Safe if attribute 'foo' has filter 'urlencode': <script><xsl:value-of select="@foo"/></script>
+ [x] Safe if attribute 'foo' has filter 'rawurlencode': <script><xsl:value-of select="@foo"/></script>
+ [x] Safe if attribute 'foo' has filter '#url': <script><xsl:value-of select="@foo"/></script>
+ [x] Safe if attribute 'foo' has filter '#int': <script><xsl:value-of select="@foo"/></script>
+ [x] Safe if attribute 'foo' has filter '#uint': <script><xsl:value-of select="@foo"/></script>
+ [x] Safe if attribute 'foo' has filter '#float': <script><xsl:value-of select="@foo"/></script>
+ [x] Safe if attribute 'foo' has filter '#range': <script><xsl:value-of select="@foo"/></script>
+ [x] Safe if attribute 'foo' has filter '#number': <script><xsl:value-of select="@foo"/></script>
+ [x] Safe if attribute 'foo' has filter '#simpletext': <script><xsl:value-of select="@foo"/></script>
+ [x] Not safe: <style><xsl:apply-templates/></style>
+ [x] Not safe: <style><xsl:apply-templates select="st"/></style>
+ [x] Not safe: <style><xsl:value-of select="st"/></style>
+ [x] Not safe: <style><xsl:value-of select="@foo"/></style>
+ [x] Not safe if attribute 'foo' has no filter: <style><xsl:value-of select="@foo"/></style>
+ [x] Not safe if attribute 'foo' has no filter: <xsl:element name="style"><xsl:value-of select="@foo"/></xsl:element>
+ [x] Not safe if attribute 'foo' has no filter: <xsl:element name="STYLE"><xsl:value-of select="@foo"/></xsl:element>
+ [x] Not safe if attribute 'foo' has filter '#url': <style><xsl:for-each select="/*"><xsl:value-of select="@foo"/></xsl:for-each></style>
+ [x] Not safe: <style><xsl:for-each select="/*"><xsl:apply-templates/></xsl:for-each></style>
+ [x] Safe if attribute 'foo' has filter '#url': <style><xsl:value-of select="@foo"/></style>
+ [x] Safe if attribute 'foo' has filter '#int': <style><xsl:value-of select="@foo"/></style>
+ [x] Safe if attribute 'foo' has filter '#uint': <style><xsl:value-of select="@foo"/></style>
+ [x] Safe if attribute 'foo' has filter '#float': <style><xsl:value-of select="@foo"/></style>
+ [x] Safe if attribute 'foo' has filter '#color': <style><xsl:value-of select="@foo"/></style>
+ [x] Safe if attribute 'foo' has filter '#range': <style><xsl:value-of select="@foo"/></style>
+ [x] Safe if attribute 'foo' has filter '#number': <style><xsl:value-of select="@foo"/></style>
+ [x] Safe if attribute 'foo' has filter '#simpletext': <style><xsl:value-of select="@foo"/></style>
View
6 scripts/patchTemplateCheckerTest.php
@@ -66,7 +66,11 @@ function _array(array $arr)
$attrName = key($attributes);
$attribute = $attributes[$attrName];
- if (!empty($attribute['filterChain']))
+ if (empty($attribute['filterChain']))
+ {
+ $attributeInfo = " if attribute '$attrName' has no filter";
+ }
+ else
{
$filter = $attribute['filterChain'][0];
$attributeInfo = " if attribute '$attrName' has filter " . var_export($filter, true);
View
81 src/ConfigBuilder/TemplateChecker.php
@@ -278,13 +278,6 @@ static protected function checkUnsafeContent(DOMXPath $DOMXPath, Tag $tag)
continue;
}
- // Check for ancestor::xsl:for-each because it would prevent us from correctly
- // evaluating the context. IOW, we don't know what tag "@foo" belongs to
- if ($DOMXPath->query('ancestor::xsl:for-each', $node)->length)
- {
- throw new UnsafeTemplateException("Cannot assess context node due to 'xsl:for-each'", $node);
- }
-
// Check expressions from <xsl:copy-of select="{@onclick}"/> and
// <b onmouseover="this.title='{@title}';this.style.backgroundColor={@color}"/>
foreach ($checkExpr as $expr)
@@ -295,7 +288,7 @@ static protected function checkUnsafeContent(DOMXPath $DOMXPath, Tag $tag)
// Check for unsafe descendants if our node is an element (not an attribute)
if ($node instanceof DOMElement)
{
- self::checkUnsafeDescendants($node, $tag, $contentType);
+ self::checkUnsafeDescendants($DOMXPath, $node, $tag, $contentType);
}
}
}
@@ -304,17 +297,18 @@ static protected function checkUnsafeContent(DOMXPath $DOMXPath, Tag $tag)
/**
* Check the descendants of given node
*
- * @param DOMElement $element
- * @param Tag $tag
- * @param string $contentType
+ * @param DOMXPath $DOMXPath DOMXPath associated with the template being checked
+ * @param DOMElement $element
+ * @param Tag $tag
+ * @param string $contentType
*/
- static protected function checkUnsafeDescendants(DOMElement $element, Tag $tag, $contentType)
+ static protected function checkUnsafeDescendants(DOMXPath $DOMXPath, DOMElement $element, Tag $tag, $contentType)
{
- $DOMXPath = new DOMXPath($element->ownerDocument);
-
// <script><xsl:value-of/></script>
foreach ($DOMXPath->query('.//xsl:value-of[@select]', $element) as $valueOf)
{
+ self::checkUnsafeContext($DOMXPath, $valueOf);
+
self::checkUnsafeExpression(
$valueOf,
$valueOf->getAttribute('select'),
@@ -329,9 +323,11 @@ static protected function checkUnsafeDescendants(DOMElement $element, Tag $tag,
if ($applyTemplates)
{
+ self::checkUnsafeContext($DOMXPath, $applyTemplates);
+
if ($applyTemplates->hasAttribute('select'))
{
- $msg = "Cannot assess the safety 'xsl:apply-templates' select expression '" . $applyTemplates->getAttribute('select') . "'";
+ $msg = "Cannot assess the safety of 'xsl:apply-templates' select expression '" . $applyTemplates->getAttribute('select') . "'";
}
elseif ($element->namespaceURI === 'http://www.w3.org/1999/XSL/Transform')
{
@@ -347,6 +343,20 @@ static protected function checkUnsafeDescendants(DOMElement $element, Tag $tag,
}
/**
+ * Test whether the context of an element can be evaluated
+ *
+ * @param DOMXPath $DOMXPath DOMXPath associated with the template being checked
+ * @param DOMElement $element Element being checked
+ */
+ static protected function checkUnsafeContext(DOMXPath $DOMXPath, DOMElement $element)
+ {
+ if ($DOMXPath->query('//xsl:for-each', $element)->length)
+ {
+ throw new UnsafeTemplateException("Cannot evaluate context node due to 'xsl:for-each'", $element);
+ }
+ }
+
+ /**
* Check the safety of an XPath expression
*
* @param DOMNode $node Context node
@@ -359,7 +369,7 @@ static protected function checkUnsafeExpression(DOMNode $node, $expr, $contentTy
// We don't even try to assess its safety if it's not a single attribute value
if (!preg_match('#^@\\s*([a-z_0-9\\-]+)$#Di', $expr, $m))
{
- throw new UnsafeTemplateException("Cannot assess XPath expression '" . $expr . "'", $node);
+ throw new UnsafeTemplateException("Cannot assess the safety of XPath expression '" . $expr . "'", $node);
}
$attrName = $m[1];
@@ -413,42 +423,6 @@ static protected function isSafeInURL(Attribute $attribute)
}
}
- /* disabled until proven useful
- // Test if that attribute uses a regexp
- if (isset($attribute->regexp)
- && $attribute->filterChain->has('#regexp')
- && preg_match('#^(.)\\^.*\\$\\1[a-z]*$#Dis', $attribute->regexp))
- {
- // Test this regexp against a few possible vectors
- $unsafeValues = array(
- 'javascript:stuff',
- 'Javascript:stuff',
- 'javaScript:stuff',
- ' javascript: stuff',
- ' Javascript:stuff',
- ' javaScript:stuff',
- "\rjavaScript:stuff",
- "\tjavaScript:stuff",
- "\x00javaScript:stuff",
- 'data:stuff',
- ' data:stuff',
- ' DATA:stuff'
- );
-
- foreach ($unsafeValues as $value)
- {
- if (preg_match($attribute->regexp, $value))
- {
- // Left an unsafe value through; This attribute is unsafe
- return false;
- }
- }
-
- // It left none of our bad values through, so we'll assume it is safe
- return true;
- }
- */
-
return false;
}
@@ -509,6 +483,9 @@ static protected function isSafeInJS(Attribute $attribute)
{
// List of filters that make a value safe to be used in a script
$safeFilters = array(
+ // Those might see some usage
+ 'urlencode',
+ 'rawurlencode',
// URLs should be safe because characters ()'" are urlencoded
'#url',
'#int',
View
748 tests/ConfigBuilder/TemplateCheckerTest.php
@@ -234,7 +234,7 @@ public function testCheckUnsafe358E72E5()
}
/**
- * @testdox Not safe: <a><xsl:copy-of select="@href"/></a>
+ * @testdox Not safe if attribute 'href' has no filter: <a><xsl:copy-of select="@href"/></a>
*/
public function testCheckUnsafeE6B9D02C()
{
@@ -289,6 +289,416 @@ public function testCheckUnsafe1BDDD975()
"Cannot assess 'xsl:copy-of' select expression 'parent::*' to be safe"
);
}
+
+ /**
+ * @testdox Not safe: <script><xsl:apply-templates/></script>
+ */
+ public function testCheckUnsafe87044075()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:apply-templates/></script>',
+ "A 'script' element lets unfiltered data through"
+ );
+ }
+
+ /**
+ * @testdox Not safe: <script><xsl:apply-templates select="st"/></script>
+ */
+ public function testCheckUnsafeC968EED0()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:apply-templates select="st"/></script>',
+ "Cannot assess the safety of 'xsl:apply-templates' select expression 'st'"
+ );
+ }
+
+ /**
+ * @testdox Not safe: <script><xsl:value-of select="st"/></script>
+ */
+ public function testCheckUnsafe5D562F28()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:value-of select="st"/></script>',
+ "Cannot assess the safety of XPath expression 'st'"
+ );
+ }
+
+ /**
+ * @testdox Not safe: <script><xsl:value-of select="@foo"/></script>
+ */
+ public function testCheckUnsafeAA242A38()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:value-of select="@foo"/></script>',
+ "Undefined attribute 'foo'"
+ );
+ }
+
+ /**
+ * @testdox Not safe if attribute 'foo' has no filter: <script><xsl:value-of select="@foo"/></script>
+ */
+ public function testCheckUnsafeBD7323B9()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:value-of select="@foo"/></script>',
+ "Attribute 'foo' is not properly filtered to be used in JS",
+ array('attributes' => array('foo' => array()))
+ );
+ }
+
+ /**
+ * @testdox Not safe if attribute 'foo' has no filter: <xsl:element name="script"><xsl:value-of select="@foo"/></xsl:element>
+ */
+ public function testCheckUnsafeD7E78277()
+ {
+ $this->testCheckUnsafe(
+ '<xsl:element name="script"><xsl:value-of select="@foo"/></xsl:element>',
+ "Attribute 'foo' is not properly filtered to be used in JS",
+ array('attributes' => array('foo' => array()))
+ );
+ }
+
+ /**
+ * @testdox Not safe if attribute 'foo' has no filter: <xsl:element name="SCRIPT"><xsl:value-of select="@foo"/></xsl:element>
+ */
+ public function testCheckUnsafeF7D14089()
+ {
+ $this->testCheckUnsafe(
+ '<xsl:element name="SCRIPT"><xsl:value-of select="@foo"/></xsl:element>',
+ "Attribute 'foo' is not properly filtered to be used in JS",
+ array('attributes' => array('foo' => array()))
+ );
+ }
+
+ /**
+ * @testdox Not safe if attribute 'foo' has filter 'urlencode': <script><xsl:for-each select="/*"><xsl:value-of select="@foo"/></xsl:for-each></script>
+ */
+ public function testCheckUnsafeDD1F8AFC()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:for-each select="/*"><xsl:value-of select="@foo"/></xsl:for-each></script>',
+ "Cannot evaluate context node due to 'xsl:for-each'",
+ array('attributes' => array('foo' => array('filterChain' => array('urlencode'))))
+ );
+ }
+
+ /**
+ * @testdox Not safe: <script><xsl:for-each select="/*"><xsl:apply-templates/></xsl:for-each></script>
+ */
+ public function testCheckUnsafe7B26C45D()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:for-each select="/*"><xsl:apply-templates/></xsl:for-each></script>',
+ "Cannot evaluate context node due to 'xsl:for-each'"
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter 'urlencode': <script><xsl:value-of select="@foo"/></script>
+ */
+ public function testCheckUnsafe3E82294D()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:value-of select="@foo"/></script>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('urlencode'))))
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter 'rawurlencode': <script><xsl:value-of select="@foo"/></script>
+ */
+ public function testCheckUnsafe80E31E96()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:value-of select="@foo"/></script>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('rawurlencode'))))
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter '#url': <script><xsl:value-of select="@foo"/></script>
+ */
+ public function testCheckUnsafe66FA78F6()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:value-of select="@foo"/></script>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('#url'))))
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter '#int': <script><xsl:value-of select="@foo"/></script>
+ */
+ public function testCheckUnsafeBEC2826B()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:value-of select="@foo"/></script>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('#int'))))
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter '#uint': <script><xsl:value-of select="@foo"/></script>
+ */
+ public function testCheckUnsafe58430C01()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:value-of select="@foo"/></script>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('#uint'))))
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter '#float': <script><xsl:value-of select="@foo"/></script>
+ */
+ public function testCheckUnsafe196B1007()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:value-of select="@foo"/></script>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('#float'))))
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter '#range': <script><xsl:value-of select="@foo"/></script>
+ */
+ public function testCheckUnsafeF128A882()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:value-of select="@foo"/></script>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('#range'))))
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter '#number': <script><xsl:value-of select="@foo"/></script>
+ */
+ public function testCheckUnsafe585E44A6()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:value-of select="@foo"/></script>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('#number'))))
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter '#simpletext': <script><xsl:value-of select="@foo"/></script>
+ */
+ public function testCheckUnsafe61A72488()
+ {
+ $this->testCheckUnsafe(
+ '<script><xsl:value-of select="@foo"/></script>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('#simpletext'))))
+ );
+ }
+
+ /**
+ * @testdox Not safe: <style><xsl:apply-templates/></style>
+ */
+ public function testCheckUnsafe9332F4DA()
+ {
+ $this->testCheckUnsafe(
+ '<style><xsl:apply-templates/></style>',
+ "A 'style' element lets unfiltered data through"
+ );
+ }
+
+ /**
+ * @testdox Not safe: <style><xsl:apply-templates select="st"/></style>
+ */
+ public function testCheckUnsafeE7A11344()
+ {
+ $this->testCheckUnsafe(
+ '<style><xsl:apply-templates select="st"/></style>',
+ "Cannot assess the safety of 'xsl:apply-templates' select expression 'st'"
+ );
+ }
+
+ /**
+ * @testdox Not safe: <style><xsl:value-of select="st"/></style>
+ */
+ public function testCheckUnsafeF4114812()
+ {
+ $this->testCheckUnsafe(
+ '<style><xsl:value-of select="st"/></style>',
+ "Cannot assess the safety of XPath expression 'st'"
+ );
+ }
+
+ /**
+ * @testdox Not safe: <style><xsl:value-of select="@foo"/></style>
+ */
+ public function testCheckUnsafeFD7FAE5C()
+ {
+ $this->testCheckUnsafe(
+ '<style><xsl:value-of select="@foo"/></style>',
+ "Undefined attribute 'foo'"
+ );
+ }
+
+ /**
+ * @testdox Not safe if attribute 'foo' has no filter: <style><xsl:value-of select="@foo"/></style>
+ */
+ public function testCheckUnsafe2BEA39BA()
+ {
+ $this->testCheckUnsafe(
+ '<style><xsl:value-of select="@foo"/></style>',
+ "Attribute 'foo' is not properly filtered to be used in CSS",
+ array('attributes' => array('foo' => array()))
+ );
+ }
+
+ /**
+ * @testdox Not safe if attribute 'foo' has no filter: <xsl:element name="style"><xsl:value-of select="@foo"/></xsl:element>
+ */
+ public function testCheckUnsafeFC0D6B8F()
+ {
+ $this->testCheckUnsafe(
+ '<xsl:element name="style"><xsl:value-of select="@foo"/></xsl:element>',
+ "Attribute 'foo' is not properly filtered to be used in CSS",
+ array('attributes' => array('foo' => array()))
+ );
+ }
+
+ /**
+ * @testdox Not safe if attribute 'foo' has no filter: <xsl:element name="STYLE"><xsl:value-of select="@foo"/></xsl:element>
+ */
+ public function testCheckUnsafe9092B290()
+ {
+ $this->testCheckUnsafe(
+ '<xsl:element name="STYLE"><xsl:value-of select="@foo"/></xsl:element>',
+ "Attribute 'foo' is not properly filtered to be used in CSS",
+ array('attributes' => array('foo' => array()))
+ );
+ }
+
+ /**
+ * @testdox Not safe if attribute 'foo' has filter '#url': <style><xsl:for-each select="/*"><xsl:value-of select="@foo"/></xsl:for-each></style>
+ */
+ public function testCheckUnsafeD5AD8427()
+ {
+ $this->testCheckUnsafe(
+ '<style><xsl:for-each select="/*"><xsl:value-of select="@foo"/></xsl:for-each></style>',
+ "Cannot evaluate context node due to 'xsl:for-each'",
+ array('attributes' => array('foo' => array('filterChain' => array('#url'))))
+ );
+ }
+
+ /**
+ * @testdox Not safe: <style><xsl:for-each select="/*"><xsl:apply-templates/></xsl:for-each></style>
+ */
+ public function testCheckUnsafeB1E49022()
+ {
+ $this->testCheckUnsafe(
+ '<style><xsl:for-each select="/*"><xsl:apply-templates/></xsl:for-each></style>',
+ "Cannot evaluate context node due to 'xsl:for-each'"
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter '#url': <style><xsl:value-of select="@foo"/></style>
+ */
+ public function testCheckUnsafeA85C9010()
+ {
+ $this->testCheckUnsafe(
+ '<style><xsl:value-of select="@foo"/></style>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('#url'))))
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter '#int': <style><xsl:value-of select="@foo"/></style>
+ */
+ public function testCheckUnsafe70646A8D()
+ {
+ $this->testCheckUnsafe(
+ '<style><xsl:value-of select="@foo"/></style>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('#int'))))
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter '#uint': <style><xsl:value-of select="@foo"/></style>
+ */
+ public function testCheckUnsafe11E4EDA4()
+ {
+ $this->testCheckUnsafe(
+ '<style><xsl:value-of select="@foo"/></style>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('#uint'))))
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter '#float': <style><xsl:value-of select="@foo"/></style>
+ */
+ public function testCheckUnsafeBF9EE081()
+ {
+ $this->testCheckUnsafe(
+ '<style><xsl:value-of select="@foo"/></style>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('#float'))))
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter '#color': <style><xsl:value-of select="@foo"/></style>
+ */
+ public function testCheckUnsafe5B459886()
+ {
+ $this->testCheckUnsafe(
+ '<style><xsl:value-of select="@foo"/></style>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('#color'))))
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter '#range': <style><xsl:value-of select="@foo"/></style>
+ */
+ public function testCheckUnsafe57DD5804()
+ {
+ $this->testCheckUnsafe(
+ '<style><xsl:value-of select="@foo"/></style>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('#range'))))
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter '#number': <style><xsl:value-of select="@foo"/></style>
+ */
+ public function testCheckUnsafe5C239743()
+ {
+ $this->testCheckUnsafe(
+ '<style><xsl:value-of select="@foo"/></style>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('#number'))))
+ );
+ }
+
+ /**
+ * @testdox Safe if attribute 'foo' has filter '#simpletext': <style><xsl:value-of select="@foo"/></style>
+ */
+ public function testCheckUnsafe8D374457()
+ {
+ $this->testCheckUnsafe(
+ '<style><xsl:value-of select="@foo"/></style>',
+ NULL,
+ array('attributes' => array('foo' => array('filterChain' => array('#simpletext'))))
+ );
+ }
// End of content generated by ../scripts/patchTemplateCheckerTest.php
/**
@@ -419,7 +829,7 @@ public function getUnsafeContentTests()
{
return array_merge(
$this->getUnsafeCopyOfNodesTests(),
- array()
+ $this->getUnsafeElementsTests()
);
}
@@ -474,223 +884,143 @@ public function getUnsafeCopyOfNodesTests()
),
);
}
-/**
- array(
- '<xsl:element name="script"><xsl:apply-templates/></xsl:element>',
- "A dynamically generated 'script' element lets unfiltered data through"
- ),
- array(
- '<xsl:element name="SCRIPT"><xsl:apply-templates/></xsl:element>',
- "A dynamically generated 'SCRIPT' element lets unfiltered data through"
- ),
- array(
- '<script><xsl:apply-templates/></script>',
- "A 'script' element lets unfiltered data through"
- ),
- array(
- '<SCRIPT><xsl:apply-templates/></SCRIPT>',
- "A 'SCRIPT' element lets unfiltered data through"
- ),
- array(
- '<script src="http://localhost/{@foo}"/>',
- "Undefined attribute 'foo'"
- ),
- array(
- '<SCRIPT src="http://localhost/{@foo}"/>',
- "Undefined attribute 'foo'"
- ),
- array(
- '<script><xsl:value-of select="@foo"/></script>',
+
+ protected function getSafeFilters($type)
+ {
+ $filters = array(
+ 'CSS' => array(
+ '#url',
+ '#int',
+ '#uint',
+ '#float',
+ '#color',
+ '#range',
+ '#number',
+ '#simpletext'
+ ),
+ 'JS' => array(
+ 'urlencode',
+ 'rawurlencode',
+ '#url',
+ '#int',
+ '#uint',
+ '#float',
+ '#range',
+ '#number',
+ '#simpletext'
+ ),
+ 'URL' => array(
+ 'urlencode',
+ 'rawurlencode',
+ '#url',
+ '#id',
+ '#int',
+ '#uint',
+ '#float',
+ '#range',
+ '#number'
+ )
+ );
+
+ return $filters[$type];
+ }
+
+ public function getUnsafeElementsTests()
+ {
+ $elements = array(
+ 'script' => 'JS',
+ 'style' => 'CSS'
+ );
+
+ $tests = array();
+
+ foreach ($elements as $element => $type)
+ {
+ $filters = $this->getSafeFilters($type);
+
+ $tests[] = array(
+ '<' . $element . '><xsl:apply-templates/></' . $element . '>',
+ "A '" . $element . "' element lets unfiltered data through"
+ );
+
+ $tests[] = array(
+ '<' . $element . '><xsl:apply-templates select="st"/></' . $element . '>',
+ "Cannot assess the safety of 'xsl:apply-templates' select expression 'st'"
+ );
+
+ $tests[] = array(
+ '<' . $element . '><xsl:value-of select="st"/></' . $element . '>',
+ "Cannot assess the safety of XPath expression 'st'"
+ );
+
+ $tests[] = array(
+ '<' . $element . '><xsl:value-of select="@foo"/></' . $element . '>',
"Undefined attribute 'foo'"
- ),
- array(
- '<script><xsl:value-of select="@foo"/></script>',
- "Attribute 'foo' is not properly filtered to be used in JS",
- array(
- 'attributes' => array(
- 'foo' => array(
- 'filterChain' => array('#raw')
- )
- )
- )
- ),
- array(
- '<script><xsl:value-of select="@foo"/></script>',
- null,
- array(
- 'attributes' => array(
- 'foo' => array(
- 'filterChain' => array('#url')
- )
- )
- )
- ),
- array(
- '<script><xsl:value-of select="@foo"/></script>',
- null,
- array(
- 'attributes' => array(
- 'foo' => array(
- 'filterChain' => array('#int')
- )
- )
- )
- ),
- array(
- '<script><xsl:value-of select="@foo"/></script>',
- null,
- array(
- 'attributes' => array(
- 'foo' => array(
- 'filterChain' => array('#float')
- )
- )
- )
- ),
- array(
- '<script><xsl:value-of select="@foo"/></script>',
- null,
- array(
- 'attributes' => array(
- 'foo' => array(
- 'filterChain' => array('#range')
- )
- )
- )
- ),
- array(
- '<script><xsl:value-of select="@foo"/></script>',
- null,
- array(
- 'attributes' => array(
- 'foo' => array(
- 'filterChain' => array('#number')
- )
- )
- )
- ),
- array(
- '<script><xsl:value-of select="@foo"/></script>',
- null,
- array(
- 'attributes' => array(
- 'foo' => array(
- 'filterChain' => array('#simpletext')
- )
- )
- )
- ),
- array(
- '<xsl:element name="style"><xsl:apply-templates/></xsl:element>',
- "A dynamically generated 'style' element lets unfiltered data through"
- ),
- array(
- '<style><xsl:apply-templates/></style>',
- "A 'style' element lets unfiltered data through"
- ),
- array(
- '<style><xsl:value-of select="@foo"/></style>',
- ""
- ),
- array(
- '<style><xsl:value-of select="@foo"/></style>',
- "Attribute 'foo' is not properly filtered to be used in CSS",
- array(
- 'attributes' => array(
- 'foo' => array(
- 'filterChain' => array('#raw')
- )
- )
- )
- ),
- array(
- '<style><xsl:value-of select="@foo"/></style>',
- null,
- array(
- 'attributes' => array(
- 'foo' => array(
- 'filterChain' => array('#url')
- )
- )
- )
- ),
- array(
- '<style><xsl:value-of select="@foo"/></style>',
- null,
- array(
- 'attributes' => array(
- 'foo' => array(
- 'filterChain' => array('#int')
- )
- )
- )
- ),
- array(
- '<style><xsl:value-of select="@foo"/></style>',
- null,
- array(
- 'attributes' => array(
- 'foo' => array(
- 'filterChain' => array('#uint')
- )
- )
- )
- ),
- array(
- '<style><xsl:value-of select="@foo"/></style>',
- null,
- array(
- 'attributes' => array(
- 'foo' => array(
- 'filterChain' => array('#float')
- )
- )
- )
- ),
- array(
- '<style><xsl:value-of select="@foo"/></style>',
- null,
- array(
- 'attributes' => array(
- 'foo' => array(
- 'filterChain' => array('#color')
- )
- )
- )
- ),
- array(
- '<style><xsl:value-of select="@foo"/></style>',
- null,
- array(
- 'attributes' => array(
- 'foo' => array(
- 'filterChain' => array('#range')
- )
- )
+ );
+
+ // Try some variations to get around basic checks
+ $tagOptions = array(
+ 'attributes' => array(
+ 'foo' => array()
)
- ),
- array(
- '<style><xsl:value-of select="@foo"/></style>',
- null,
+ );
+
+ $tests[] = array(
+ '<' . $element . '><xsl:value-of select="@foo"/></' . $element . '>',
+ "Attribute 'foo' is not properly filtered to be used in " . $type,
+ $tagOptions
+ );
+
+ $tests[] = array(
+ '<xsl:element name="' . $element . '"><xsl:value-of select="@foo"/></xsl:element>',
+ "Attribute 'foo' is not properly filtered to be used in " . $type,
+ $tagOptions
+ );
+
+ $tests[] = array(
+ '<xsl:element name="' . strtoupper($element) . '"><xsl:value-of select="@foo"/></xsl:element>',
+ "Attribute 'foo' is not properly filtered to be used in " . $type,
+ $tagOptions
+ );
+
+ // Using xsl:for-each to subvert the context
+ $tests[] = array(
+ '<' . $element . '><xsl:for-each select="/*"><xsl:value-of select="@foo"/></xsl:for-each></' . $element . '>',
+ "Cannot evaluate context node due to 'xsl:for-each'",
array(
'attributes' => array(
'foo' => array(
- 'filterChain' => array('#number')
+ 'filterChain' => array($filters[0])
)
)
)
- ),
- array(
- '<style><xsl:value-of select="@foo"/></style>',
- null,
- array(
- 'attributes' => array(
- 'foo' => array(
- 'filterChain' => array('#simpletext')
+ );
+
+ $tests[] = array(
+ '<' . $element . '><xsl:for-each select="/*"><xsl:apply-templates/></xsl:for-each></' . $element . '>',
+ "Cannot evaluate context node due to 'xsl:for-each'"
+ );
+
+ // Test safe filters
+ foreach ($filters as $filter)
+ {
+ $tests[] = array(
+ '<' . $element . '><xsl:value-of select="@foo"/></' . $element . '>',
+ null,
+ array(
+ 'attributes' => array(
+ 'foo' => array(
+ 'filterChain' => array($filter)
+ )
)
)
- )
- ),
+ );
+ }
+ }
+
+ return $tests;
+ }
+/**
array(
'<b style="color:{@foo}"/>',
"Undefined attribute 'foo'"

0 comments on commit a40583c

Please sign in to comment.
Something went wrong with that request. Please try again.