Skip to content

Commit

Permalink
minor #46062 [HtmlSanitizer] Add HtmlSanitizerConfig::withMaxInputLen…
Browse files Browse the repository at this point in the history
…gth() (nicolas-grekas)

This PR was merged into the 6.1 branch.

Discussion
----------

[HtmlSanitizer] Add HtmlSanitizerConfig::withMaxInputLength()

| Q             | A
| ------------- | ---
| Branch?       | 6.1
| Bug fix?      | no
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix ##44798 (review)
| License       | MIT
| Doc PR        | -

Commits
-------

070f2cf [HtmlSanitizer] Add HtmlSanitizerConfig::withMaxInputLength()
  • Loading branch information
fabpot committed Apr 16, 2022
2 parents a25483f + 070f2cf commit ea96c13
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2243,6 +2243,10 @@ private function addHtmlSanitizerSection(ArrayNodeDefinition $rootNode, callable
->info('Unregisters custom attribute sanitizers.')
->scalarPrototype()->end()
->end()
->integerNode('max_input_length')
->info('The maximum length allowed for the sanitized input.')
->defaultValue(0)
->end()
->end()
->end()
->end()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2734,6 +2734,10 @@ private function registerHtmlSanitizerConfiguration(array $config, ContainerBuil
$def->addMethodCall('withoutAttributeSanitizer', [new Reference($serviceName)], true);
}

if ($sanitizerConfig['max_input_length']) {
$def->addMethodCall('withMaxInputLength', [$sanitizerConfig['max_input_length']], true);
}

// Create the sanitizer and link its config
$sanitizerId = 'html_sanitizer.sanitizer.'.$sanitizerName;
$container->register($sanitizerId, HtmlSanitizer::class)->addArgument(new Reference($configId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,7 @@
<xsd:attribute name="force-https-urls" type="xsd:boolean" />
<xsd:attribute name="allow-relative-links" type="xsd:boolean" />
<xsd:attribute name="allow-relative-medias" type="xsd:boolean" />
<xsd:attribute name="max-input-length" type="xsd:positiveInteger" />
</xsd:complexType>

<xsd:complexType name="element-option">
Expand Down
8 changes: 3 additions & 5 deletions src/Symfony/Component/HtmlSanitizer/HtmlSanitizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,16 @@
final class HtmlSanitizer implements HtmlSanitizerInterface
{
private HtmlSanitizerConfig $config;
private int $maxInputLength;
private ParserInterface $parser;

/**
* @var array<string, DomVisitor>
*/
private array $domVisitors = [];

public function __construct(HtmlSanitizerConfig $config, int $maxInputLength = 20000, ParserInterface $parser = null)
public function __construct(HtmlSanitizerConfig $config, ParserInterface $parser = null)
{
$this->config = $config;
$this->maxInputLength = $maxInputLength;
$this->parser = $parser ?? new MastermindsParser();
}

Expand Down Expand Up @@ -64,8 +62,8 @@ private function sanitizeWithContext(string $context, string $input): string
$this->domVisitors[$context] ??= $this->createDomVisitorForContext($context);

// Prevent DOS attack induced by extremely long HTML strings
if (\strlen($input) > $this->maxInputLength) {
$input = substr($input, 0, $this->maxInputLength);
if (\strlen($input) > $this->config->getMaxInputLength()) {
$input = substr($input, 0, $this->config->getMaxInputLength());
}

// Only operate on valid UTF-8 strings. This is necessary to prevent cross
Expand Down
15 changes: 15 additions & 0 deletions src/Symfony/Component/HtmlSanitizer/HtmlSanitizerConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ class HtmlSanitizerConfig
*/
private array $attributeSanitizers;

private int $maxInputLength = 20_000;

public function __construct()
{
$this->attributeSanitizers = [
Expand Down Expand Up @@ -405,6 +407,19 @@ public function withoutAttributeSanitizer(AttributeSanitizerInterface $sanitizer
return $clone;
}

public function withMaxInputLength(int $maxInputLength): static
{
$clone = clone $this;
$clone->maxInputLength = $maxInputLength;

return $clone;
}

public function getMaxInputLength(): int
{
return $this->maxInputLength;
}

/**
* @return array<string, array<string, true>>
*/
Expand Down

0 comments on commit ea96c13

Please sign in to comment.