0
0
mirror of https://github.com/ezyang/htmlpurifier.git synced 2024-09-18 18:25:18 +00:00

[3.1.1] Round up imagecrash support with HTML.MaxImgLength

- Add $max to AttrDef/HTML/Pixels.php
- Add %HTML.MaxImgLength
- CSS width/height allows percents when MaxImgLength is disabled


git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1762 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
Edward Z. Yang 2008-05-23 02:09:43 +00:00
parent fcebb7731d
commit eb9f9bc7f6
11 changed files with 142 additions and 24 deletions

4
NEWS
View File

@ -10,7 +10,8 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
==========================
3.1.1, unknown release date
! More robust imagecrash protection with height/width CSS with %CSS.MaxImgLength.
! More robust imagecrash protection with height/width CSS with %CSS.MaxImgLength,
and height/width HTML with %HTML.MaxImgLength.
- Disable percent height/width attributes for img
- AttrValidator operations are now atomic; updates to attributes are not
manifest in token until end of operations. This prevents naughty internal
@ -29,6 +30,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
use this rather than __construct(), although legacy code using constructors
will still work--the new format, however, lets modules access the
configuration object for HTML namespace dependant tweaks.
. AttrDef_HTML_Pixels now takes a single construction parameter, pixels.
3.1.0, released 2008-05-18
# Unnecessary references to objects (vestiges of PHP4) removed from method

View File

@ -23,22 +23,22 @@
</directive>
<directive id="CSS.Proprietary">
<file name="HTMLPurifier/CSSDefinition.php">
<line>209</line>
<line>214</line>
</file>
</directive>
<directive id="CSS.AllowTricky">
<file name="HTMLPurifier/CSSDefinition.php">
<line>213</line>
<line>218</line>
</file>
</directive>
<directive id="CSS.AllowImportant">
<file name="HTMLPurifier/CSSDefinition.php">
<line>217</line>
<line>222</line>
</file>
</directive>
<directive id="CSS.AllowedProperties">
<file name="HTMLPurifier/CSSDefinition.php">
<line>269</line>
<line>274</line>
</file>
</directive>
<directive id="Cache.DefinitionImpl">
@ -151,6 +151,9 @@
<file name="HTMLPurifier/Lexer.php">
<line>238</line>
</file>
<file name="HTMLPurifier/HTMLModule/Image.php">
<line>27</line>
</file>
<file name="HTMLPurifier/Lexer/DirectLex.php">
<line>34</line>
</file>
@ -310,6 +313,11 @@
<line>123</line>
</file>
</directive>
<directive id="HTML.MaxImgLength">
<file name="HTMLPurifier/HTMLModule/Image.php">
<line>14</line>
</file>
</directive>
<directive id="HTML.TidyLevel">
<file name="HTMLPurifier/HTMLModule/Tidy.php">
<line>45</line>

View File

@ -6,6 +6,12 @@
class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef
{
protected $max;
public function __construct($max = null) {
$this->max = $max;
}
public function validate($string, $config, $context) {
$string = trim($string);
@ -24,11 +30,18 @@ class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef
// crash operating systems, see <http://ha.ckers.org/imagecrash.html>
// WARNING, above link WILL crash you if you're using Windows
if ($int > 1200) return '1200';
if ($this->max !== null && $int > $this->max) return (string) $this->max;
return (string) $int;
}
public function make($string) {
if ($string === '') $max = null;
else $max = (int) $string;
$class = get_class($this);
return new $class($max);
}
}

View File

@ -149,21 +149,26 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
new HTMLPurifier_AttrDef_CSS_Percentage()
));
$trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite(array(
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(array('auto'))
));
$max = $config->get('CSS', 'MaxImgLength');
$this->info['width'] =
$this->info['height'] =
new HTMLPurifier_AttrDef_Switch('img',
// For img tags:
new HTMLPurifier_AttrDef_CSS_Composite(array(
new HTMLPurifier_AttrDef_CSS_Length('0', $config->get('CSS', 'MaxImgLength')),
new HTMLPurifier_AttrDef_Enum(array('auto'))
)),
// For everyone else:
new HTMLPurifier_AttrDef_CSS_Composite(array(
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(array('auto'))
))
);
$max === null ?
$trusted_wh :
new HTMLPurifier_AttrDef_Switch('img',
// For img tags:
new HTMLPurifier_AttrDef_CSS_Composite(array(
new HTMLPurifier_AttrDef_CSS_Length('0', $max),
new HTMLPurifier_AttrDef_Enum(array('auto'))
)),
// For everyone else:
$trusted_wh
);
$this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration();

File diff suppressed because one or more lines are too long

View File

@ -8,4 +8,8 @@ VERSION: 3.1.1
effectively the <code>width</code> and <code>height</code> properties.
Only absolute units of measurement (in, pt, pc, mm, cm) and pixels (px) are allowed. This is
in place to prevent imagecrash attacks, disable with null at your own risk.
This directive is similar to %HTML.MaxImgLength, and both should be
concurrently edited, although there are
subtle differences in the input format (the CSS max is a number with
a unit).
</p>

View File

@ -0,0 +1,13 @@
HTML.MaxImgLength
TYPE: int/null
DEFAULT: 1200
VERSION: 3.1.1
--DESCRIPTION--
<p>
This directive controls the maximum number of pixels in the width and
height attributes in <code>img</code> tags. This is
in place to prevent imagecrash attacks, disable with null at your own risk.
This directive is similar to %CSS.MaxImgLength, and both should be
concurrently edited, although there are
subtle differences in the input format (the HTML max is an integer).
</p>

View File

@ -11,19 +11,24 @@ class HTMLPurifier_HTMLModule_Image extends HTMLPurifier_HTMLModule
public $name = 'Image';
public function setup($config) {
$max = $config->get('HTML', 'MaxImgLength');
$img = $this->addElement(
'img', 'Inline', 'Empty', 'Common',
array(
'alt*' => 'Text',
// According to the spec, it's Length, but percents can
// be abused, so we allow only Pixels. A trusted module
// could overload this with the real value.
'height' => 'Pixels',
'width' => 'Pixels',
// be abused, so we allow only Pixels.
'height' => 'Pixels#' . $max,
'width' => 'Pixels#' . $max,
'longdesc' => 'URI',
'src*' => new HTMLPurifier_AttrDef_URI(true), // embedded
)
);
if ($max === null || $config->get('HTML', 'Trusted')) {
$img->attr['height'] =
$img->attr['width'] = 'Length';
}
// kind of strange, but splitting things up would be inefficient
$img->attr_transform_pre[] =
$img->attr_transform_post[] =

View File

@ -33,5 +33,12 @@ class HTMLPurifier_AttrDef_HTML_PixelsTest extends HTMLPurifier_AttrDefHarness
}
function test_make() {
$factory = new HTMLPurifier_AttrDef_HTML_Pixels();
$this->def = $factory->make('30');
$this->assertDef('25');
$this->assertDef('35', '30');
}
}

View File

@ -0,0 +1,54 @@
<?php
class HTMLPurifier_HTMLModule_ImageTest extends HTMLPurifier_HTMLModuleHarness
{
function testNormal() {
$this->assertResult('<img height="40" width="40" src="" alt="" />');
}
function testLengthTooLarge() {
$this->assertResult(
'<img height="40000" width="40000" src="" alt="" />',
'<img height="1200" width="1200" src="" alt="" />'
);
}
function testLengthPercentage() {
$this->assertResult(
'<img height="100%" width="100%" src="" alt="" />',
'<img src="" alt="" />'
);
}
function testLengthCustomMax() {
$this->config->set('HTML', 'MaxImgLength', 20);
$this->assertResult(
'<img height="30" width="30" src="" alt="" />',
'<img height="20" width="20" src="" alt="" />'
);
}
function testLengthCrashFixDisabled() {
$this->config->set('HTML', 'MaxImgLength', null);
$this->assertResult(
'<img height="100%" width="100%" src="" alt="" />'
);
$this->assertResult(
'<img height="40000" width="40000" src="" alt="" />'
);
}
function testLengthTrusted() {
$this->config->set('HTML', 'Trusted', true);
$this->assertResult(
'<img height="100%" width="100%" src="" alt="" />'
);
$this->assertResult(
'<img height="40000" width="40000" src="" alt="" />'
);
}
}

View File

@ -205,6 +205,13 @@ class HTMLPurifier_Strategy_ValidateAttributesTest extends
);
}
function testKeepPercentCSSWidthAndHeightOnImgWhenToldTo() {
$this->config->set('CSS', 'MaxImgLength', null);
$this->assertResult(
'<img src="" alt="" style="width:100%;height:100%;border:1px solid #000;" />'
);
}
function testRemoveRelativeCSSWidthAndHeightOnImg() {
$this->assertResult(
'<img src="" alt="" style="width:10em;height:10em;border:1px solid #000;" />',