Skip to main content
added 2 characters in body
Source Link
mickmackusa
  • 4.8k
  • 4
  • 18
  • 48

Using regular expressions to manipulate valid HTML is not advisable because regex is "DOM-unaware" meaning that it doesn't know if it is actually modifying a tag or just text that seems like a tag. Also, unless expressly told to replace only once, it will happily modify multiple matching strings (effectively damaging your content). Finally, using DomDocument is a superior technique because it will intelligently/reliably parse and modify a class attribute regardless of the position of the attribute in the tag and regardless of the character used to quote the value (single or double quotes).

Code: (PHP Demo)

$new_class = "new_class_attr";

$body = JFactory::getApplication()->getBody();

$dom = new DOMDocument; 
$dom->loadHTML($body, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$bodytag = $dom->getElementsByTagName('body')->item(0);
if ($bodytag->hasAttribute("class")) {
    $new_class = $bodytag->getAttribute("class") . " " . $new_class;
}
$bodytag->setAttribute("class", $new_class);
JFactory::getApplication()->setBody($dom->saveHTML());

And just in case anyone mistakes my endorsement of DOMDocument for fear of regular expressions, here is how I would code it up using refined regex calls.

Code: (PHP Demo) (First Regex Demo) (Second Regex Demo)

$new_class = "new_class_attr";

$body = JFactory::getApplication()->getBody();

$body = preg_replace('~<body[^>]*class *= *["\']\K~', "$new_class ", $body, 1, $count);  // add to existing class attribute
if (!$count) {
    $body = preg_replace('~<body\K~', " class=\"$new_class\"", $body, 1);  // create class with attribute
}
JFactory::getApplication()->setBody($body);

But, again, I don't recommend regex for this job because it will be less stable... Imagine if you had an attribute (and didn't realize it) like specialclass" or specialclassdata-class` or data-class. So look, let's not go down the tit-for-tat rabbit hole of creating a body string that will break the pattern then adjust the pattern to suit the vulnerability -- just use a DOM parser.

Using regular expressions to manipulate valid HTML is not advisable because regex is "DOM-unaware" meaning that it doesn't know if it is actually modifying a tag or just text that seems like a tag. Also, unless expressly told to replace only once, it will happily modify multiple matching strings (effectively damaging your content). Finally, using DomDocument is a superior technique because it will intelligently/reliably parse and modify a class attribute regardless of the position of the attribute in the tag and regardless of the character used to quote the value (single or double quotes).

Code: (PHP Demo)

$new_class = "new_class_attr";

$body = JFactory::getApplication()->getBody();

$dom = new DOMDocument; 
$dom->loadHTML($body, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$bodytag = $dom->getElementsByTagName('body')->item(0);
if ($bodytag->hasAttribute("class")) {
    $new_class = $bodytag->getAttribute("class") . " " . $new_class;
}
$bodytag->setAttribute("class", $new_class);
JFactory::getApplication()->setBody($dom->saveHTML());

And just in case anyone mistakes my endorsement of DOMDocument for fear of regular expressions, here is how I would code it up using refined regex calls.

Code: (PHP Demo) (First Regex Demo) (Second Regex Demo)

$new_class = "new_class_attr";

$body = JFactory::getApplication()->getBody();

$body = preg_replace('~<body[^>]*class *= *["\']\K~', "$new_class ", $body, 1, $count);  // add to existing class attribute
if (!$count) {
    $body = preg_replace('~<body\K~', " class=\"$new_class\"", $body, 1);  // create class with attribute
}
JFactory::getApplication()->setBody($body);

But, again, I don't recommend regex for this job because it will be less stable... Imagine if you had an attribute (and didn't realize it) like specialclass" or data-class`. So look, let's not go down the tit-for-tat rabbit hole of creating a body string that will break the pattern then adjust the pattern to suit the vulnerability -- just use DOM parser.

Using regular expressions to manipulate valid HTML is not advisable because regex is "DOM-unaware" meaning that it doesn't know if it is actually modifying a tag or just text that seems like a tag. Also, unless expressly told to replace only once, it will happily modify multiple matching strings (effectively damaging your content). Finally, using DomDocument is a superior technique because it will intelligently/reliably parse and modify a class attribute regardless of the position of the attribute in the tag and regardless of the character used to quote the value (single or double quotes).

Code: (PHP Demo)

$new_class = "new_class_attr";

$body = JFactory::getApplication()->getBody();

$dom = new DOMDocument; 
$dom->loadHTML($body, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$bodytag = $dom->getElementsByTagName('body')->item(0);
if ($bodytag->hasAttribute("class")) {
    $new_class = $bodytag->getAttribute("class") . " " . $new_class;
}
$bodytag->setAttribute("class", $new_class);
JFactory::getApplication()->setBody($dom->saveHTML());

And just in case anyone mistakes my endorsement of DOMDocument for fear of regular expressions, here is how I would code it up using refined regex calls.

Code: (PHP Demo) (First Regex Demo) (Second Regex Demo)

$new_class = "new_class_attr";

$body = JFactory::getApplication()->getBody();

$body = preg_replace('~<body[^>]*class *= *["\']\K~', "$new_class ", $body, 1, $count);  // add to existing class attribute
if (!$count) {
    $body = preg_replace('~<body\K~', " class=\"$new_class\"", $body, 1);  // create class with attribute
}
JFactory::getApplication()->setBody($body);

But, again, I don't recommend regex for this job because it will be less stable... Imagine if you had an attribute (and didn't realize it) like specialclass or data-class. So look, let's not go down the tit-for-tat rabbit hole of creating a body string that will break the pattern then adjust the pattern to suit the vulnerability -- just use a DOM parser.

Source Link
mickmackusa
  • 4.8k
  • 4
  • 18
  • 48

Using regular expressions to manipulate valid HTML is not advisable because regex is "DOM-unaware" meaning that it doesn't know if it is actually modifying a tag or just text that seems like a tag. Also, unless expressly told to replace only once, it will happily modify multiple matching strings (effectively damaging your content). Finally, using DomDocument is a superior technique because it will intelligently/reliably parse and modify a class attribute regardless of the position of the attribute in the tag and regardless of the character used to quote the value (single or double quotes).

Code: (PHP Demo)

$new_class = "new_class_attr";

$body = JFactory::getApplication()->getBody();

$dom = new DOMDocument; 
$dom->loadHTML($body, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$bodytag = $dom->getElementsByTagName('body')->item(0);
if ($bodytag->hasAttribute("class")) {
    $new_class = $bodytag->getAttribute("class") . " " . $new_class;
}
$bodytag->setAttribute("class", $new_class);
JFactory::getApplication()->setBody($dom->saveHTML());

And just in case anyone mistakes my endorsement of DOMDocument for fear of regular expressions, here is how I would code it up using refined regex calls.

Code: (PHP Demo) (First Regex Demo) (Second Regex Demo)

$new_class = "new_class_attr";

$body = JFactory::getApplication()->getBody();

$body = preg_replace('~<body[^>]*class *= *["\']\K~', "$new_class ", $body, 1, $count);  // add to existing class attribute
if (!$count) {
    $body = preg_replace('~<body\K~', " class=\"$new_class\"", $body, 1);  // create class with attribute
}
JFactory::getApplication()->setBody($body);

But, again, I don't recommend regex for this job because it will be less stable... Imagine if you had an attribute (and didn't realize it) like specialclass" or data-class`. So look, let's not go down the tit-for-tat rabbit hole of creating a body string that will break the pattern then adjust the pattern to suit the vulnerability -- just use DOM parser.