On 26/06/2021 14:47, Dan Ackroyd wrote:
There is a line of code that has a bad assumption of whether $color is
a literal string or not, and it's that line of code that needs to be
changed, to use something that understands HTML escaping, in
particular how to escape user input for html attribute context.


All we can say for sure is that the code is making an assertion about its input, and the assertion is failing. It may be that the assertion needs to be revised, and assume that the input is dangerous; or it may be that the assertion is correct and the calling code is violating the contract.

Consider this example:

function addBlockToSidebar(string $blockHtml): void {
    $this->sidebarHtml .= '<div class="block">' . $blockHtml . '</div>';
}

The contract of this function is that the input is a piece of HTML which isn't under an attacker's control. We can assert that the caller meets that contract either using assert(is_literal($blockHtml)) or by using literal_concat() instead of the . operator.

Either way, if that assertion fails, it indicates a bug somewhere else in the program, not in this function, and not necessarily in the call stack of the error:

public function getFooBlock(): string {
     // literal string, but no assertion is present
     $block = '<div>blah blah</div>';

     if ( isset($this->customBanner) ) {
         // $this->customBanner is user-controlled
         $block .= $this->customBanner;
     }
     return $block;
}

$block = getFooBlock();
addBlockToSidebar($block);


Here, the new code in getFooBlock() is at fault, but is not in the stack trace when the assertion fails. Clearing the flag on all concatenations makes no difference to this example: the concatenation is with a non-literal string, so clears it anyway.


Regards,

--
Rowan Tommins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to