How to find attributes of a <script ...> tag which written in a text string

Viewed 47

I have a textarea where website admins can insert their own JS. I need to take their JS, re-format it and output it in my own JS function.

Unfortunately, I need to do this in both JS and PHP (as a security measure).

Example of what the admin puts in the textarea:

<script async src="https://www.googletagmanager.com/gtag/js?id=UA-11111111-1" id="someID" data-param="someValue"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-11111111-1');
</script>

I need to turn it into:

myCallback(){
  getScript(https://www.googletagmanager.com/gtag/js?id=UA-11111111-1, {"async":true, "id": "someID", "data-param": "someValue"));
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'UA-11111111-1');
}

I can remove <script> tags with a simple txt.replace('<script>','');

The problem is however with scripts that download other scripts and contain some attributes like that:

<script src="https://example.com/script.js" id="someID" data-par="123" data-par2="abc">

Can anyone tell me how to find them in the text and grab put their parameters into my own function getScript(src, {params}).

As an added complication, I need to have it in both JS and PHP. JS is for running the code on the browser when the admin enters the code and PHP is for code sanitisation.

1 Answers

You can extract the data with DOMDocument and process easily.

$script = <<<'_SCRIPT'
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-11111111-1" id="someID" data-param="someValue"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-11111111-1');
</script>
_SCRIPT;

$doc = new DOMDocument();
$doc->loadHTML($script);
$scripts = $doc->getElementsByTagName('script');

echo 'myCallback(){', PHP_EOL;

foreach($scripts as $script) {
    if ($script->hasAttribute('src')) {
        $attributes = [];
        foreach($script->attributes as $attribute) {
            $name = $attribute->name;
            if ('async' === $name) {
                $attributes[$name] = 'true';
                continue;
            }
            if ('src' === $name) {
                $src = $attribute->value;
                continue;
            }
            $attributes[$name] = $attribute->value;
        }
        echo "getScript('{$src}', ", json_encode($attributes), ");", PHP_EOL;
        continue;
    }
    echo $script->textContent, PHP_EOL;
}
echo '}', PHP_EOL;

Output

myCallback(){
getScript('https://www.googletagmanager.com/gtag/js?id=UA-11111111-1', {"async":"true","id":"someID","data-param":"someValue"});

  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-11111111-1');
}
Related