Login   Register  
PHP Classes
elePHPant
Icontem

File: dom_script_test.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Michael A. Peters  >  CSP Filter  >  dom_script_test.php  >  Download  
File: dom_script_test.php
Role: Example script
Content type: text/plain
Description: Class Playground
Class: CSP Filter
Filter HTML based on Content Security Policy
Author: By
Last change: use idna if available
Date: 2009-03-29 04:37
Size: 11,907 bytes
 

Contents

Class file image Download
<?php
// this code is a bit of a mess - it started as one thing and was morphed into something else.
//  Sorry about that - I'll clean it later.
require_once('cspfilter_class.php');
$xhtmldtd="<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">";
$htmldtd="<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">";

$http_host = $_SERVER['HTTP_HOST'];
// above should be sanitized

if (file_exists('idna_convert.class.php')) {
   include_once('idna_convert.class.php');
   }

// because we allow base tag to be set in the form
$thisdir = $http_host . dirname($_SERVER['PHP_SELF']);
// might be broken under IIS with ISAPI??
if (! isset($_SERVER['HTTPS'])) {
   $thisdir = 'http://' . $thisdir;
   } elseif (strcmp($_SERVER['HTTPS'],'off') == 0) {
   $thisdir = 'http://' . $thisdir;
   } else {
   $thisdir = 'https://' . $thisdir;
   }

function sendxhtmlheader($usexml) {
   if ($usexml == 1) {
      header("Content-Type: application/xhtml+xml; charset=utf-8");
      } else {
      header("Content-type: text/html; charset=utf-8");
      }
   }

if (isset($_POST['forcehtml'])) {
   $usexml=0;
   }

if (! isset($usexml)) {
   $usexml=1;
   }
if ($usexml == 1) {
   if (isset( $_SERVER['HTTP_ACCEPT'] )) {
      if(! strpos( $_SERVER['HTTP_ACCEPT'], "application/xhtml+xml" ) ) {
         $usexml=0;
         }
      } else {
      $usexml=0;
      }
   }

$def_csp = Array();
if (isset($_POST['allow'])) {
   $foo = trim($_POST['allow']);
   if (strlen($foo) > 0) {
      $def_csp['allow'] = $foo;
      } else {
      $def_csp['allow'] = "none";
      }
   } else {
   $def_csp['allow'] = "none";
   }
   
if (isset($_POST['img-src'])) {
   $foo = trim($_POST['img-src']);
   if (strlen($foo) > 0) {
      $def_csp['img-src'] = $foo;
      }
   }
   
if (isset($_POST['media-src'])) {
   $foo = trim($_POST['media-src']);
   if (strlen($foo) > 0) {
      $def_csp['media-src'] = $foo;
      }
   }
   
if (isset($_POST['script-src'])) {
   $foo = trim($_POST['script-src']);
   if (strlen($foo) > 0) {
      $def_csp['script-src'] = $foo;
      }
   }
   
if (isset($_POST['object-src'])) {
   $foo = trim($_POST['object-src']);
   if (strlen($foo) > 0) {
      $def_csp['object-src'] = $foo;
      }
   }
   
if (isset($_POST['frame-src'])) {
   $foo = trim($_POST['frame-src']);
   if (strlen($foo) > 0) {
      $def_csp['frame-src'] = $foo;
      }
   }

$myxhtml = new DOMDocument("1.0","UTF-8");
$myxhtml->preserveWhiteSpace = false;
$myxhtml->formatOutput = true;
if ($usexml == 0) {
   $xmlstring = $htmldtd . "<html></html>";
   } else {
   $xmlstring = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" . 
$xhtmldtd . "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\"></html>";
   }
$myxhtml->loadXML($xmlstring);
$foo = $myxhtml->getElementsByTagName("html");
foreach ($foo as $bar) {
   $xmlHtml = $bar;
   }
   
$xmlHead = $myxhtml->createElement("head");
$contentMeta = $myxhtml->createElement('meta');
$contentMeta->setAttribute('http-equiv','Content-type');
if ($usexml == 1) {
   $contentMeta->setAttribute('content','application/xhtml+xml; charset=utf-8');
   } else {
   $contentMeta->setAttribute('content','text/html; charset=utf-8');
   }
$xmlHead->appendChild($contentMeta);
$preStyle = "font-family: Monaco, 'Lucida Mono', 'Lucida Mono EFOP', 'Lucida Mono EF', Courier, monospace; color: blue;";
$xmlTitle = $myxhtml->createElement("title","script test");
$xmlHead->appendChild($xmlTitle);

$def_base="";
if (isset($_POST['base'])) {
   $def_base = trim($_POST['base']);
   if (strlen($def_base) > 0) {
      $xmlBase = $myxhtml->createElement("base");
      $xmlBase->setAttribute("href",$def_base);
      $xmlHead->appendChild($xmlBase);
      }
   }
   
$def_test="";
if (isset($_POST['foo'])) {
   $def_test=trim($_POST['foo']);
   $import_prepare = "<div>" . $def_test . "</div>";
   
   $newDom = new DOMDocument("1.0","UTF-8");
   $newDom->loadHTML($import_prepare);
   $elements = $newDom->getElementsByTagName("div");
   $imported_div = $elements->item(0);
   
   $testDiv = $myxhtml->importNode($imported_div,true);
   $testDiv->setAttribute("id","formPostData");
   }

$cspDiv = $myxhtml->createElement("div");
$cspDiv->setAttribute("id","cspsettings");
$cspDiv->setAttribute("style","float: left;");

$source = Array('allow','img-src','media-src','script-src','object-src','frame-src');
$inputDiv = $myxhtml->createElement("div");
$inputDiv->setAttribute("style","text-align: right;");
for ($i=0; $i<5; $i++) {
   $foo = $source[$i];
   $xmlString = $myxhtml->createTextNode($foo . ": ");
   $inputDiv->appendChild($xmlString);
   $xmlInput = $myxhtml->createElement("input");
   $xmlInput->setAttribute("type","text");
   $xmlInput->setAttribute("name",$source[$i]);
   $xmlInput->setAttribute("size","80");
   if (isset($def_csp[$foo])) {
      $value = $def_csp[$foo];
      $xmlInput->setAttribute("value",$value);
      }
   $inputDiv->appendChild($xmlInput);
   $xmlBr = $myxhtml->createElement("br");
   $inputDiv->appendChild($xmlBr);
   }
$cspDiv->appendChild($inputDiv);

$htmlSet = $myxhtml->createElement("div");
$htmlSet->setAttribute("id","htmlsettings");
$htmlSet->setAttribute("style","float: left;");
$xmlDiv = $myxhtml->createElement("div");
$xmlDiv->setAttribute("style","float: left;");
$xmlInput = $myxhtml->createElement("input");
$xmlInput->setAttribute("type","checkbox");
$xmlInput->setAttribute("id","forcehtml");
$xmlInput->setAttribute("name","forcehtml");
$xmlInput->setAttribute("value","1");
if ($usexml == 0) {
   $xmlInput->setAttribute("checked","checked");
   }
$xmlDiv->appendChild($xmlInput);
$xmlLabel = $myxhtml->createElement("label","Force HTML 4.01");
$xmlLabel->setAttribute("for","forcehtml");
$xmlDiv->appendChild($xmlLabel);
$htmlSet->appendChild($xmlDiv);
$xmlDiv = $myxhtml->createElement("div","&nbsp;");
$xmlDiv->setAttribute("style","float: left; width: 2em;");
$htmlSet->appendChild($xmlDiv);
$xmlDiv = $myxhtml->createElement("div");
$xmlDiv->setAttribute("style","float: left;");
$xmlString = $myxhtml->createTextNode("Contents of base tag href attribute: ");
$xmlDiv->appendChild($xmlString);
$xmlInput = $myxhtml->createElement("input");
$xmlInput->setAttribute("type","text");
$xmlInput->setAttribute("name","base");
$xmlInput->setAttribute("size","40");
$xmlInput->setAttribute("value",$def_base);
$xmlDiv->appendChild($xmlInput);
$htmlSet->appendChild($xmlDiv);


   
$xmlBody = $myxhtml->createElement("body");
$xmlBody->setAttribute("style","background-color: #eeeeee;");
if ($usexml == 0) {
   $xmlString = $myxhtml->createTextNode(" - HTML 4.01");
   } else {
   $xmlString = $myxhtml->createTextNode(" - XHTML 1.1");
   }
$xmlPar = $myxhtml->createElement("p","Test page for ");
$xmlAnchor = $myxhtml->createElement("a","CSP Output Filter Class");

$href = $thisdir . "/";
$xmlAnchor->setAttribute("href",$href);
$xmlPar->appendChild($xmlAnchor);
$xmlPar->appendChild($xmlString);
$xmlBody->appendChild($xmlPar);
$xmlForm = $myxhtml->createElement("form");
$xmlForm->setAttribute("id","form");
$xmlForm->setAttribute("method","post");
$action = $href . "dom_script_test.php";
$xmlForm->setAttribute("action",$action);
$xmlForm->appendChild($cspDiv);
$clear = $myxhtml->createElement("div");
$clear->setAttribute("style","clear: both;");
$xmlForm->appendChild($clear);

$xmlHr = $myxhtml->createElement("hr");
$xmlHr->setAttribute("style","width: 50%;");
$xmlForm->appendChild($xmlHr);

$xmlForm->appendChild($htmlSet);
$clear = $myxhtml->createElement("div");
$clear->setAttribute("style","clear: both;");
$xmlForm->appendChild($clear);
$xmlDiv  = $myxhtml->createElement("div");
$xmlPar = $myxhtml->createElement("p","Enter some well-formed html here: (it has to import into a DOMDocument)");
$xmlDiv->appendChild($xmlPar);
$xmlTextArea = $myxhtml->createElement("textarea",$def_test);
$xmlTextArea->setAttribute("id","textarea");
$xmlTextArea->setAttribute("name","foo");
$xmlTextArea->setAttribute("style","width: 65%; height: 14em;");
$xmlTextArea->setAttribute("rows","20");
$xmlTextArea->setAttribute("cols","80");
$xmlDiv->appendChild($xmlTextArea);
$xmlBreak = $myxhtml->createElement("br");
$xmlDiv->appendChild($xmlBreak);
$xmlInput = $myxhtml->createElement("input");
$xmlInput->setAttribute("type","submit");
$xmlInput->setAttribute("id","submit");
$xmlInput->setAttribute("name","submit");
$xmlInput->setAttribute("value","submit");
$xmlDiv->appendChild($xmlInput);
$xmlForm->appendChild($xmlDiv);
$xmlBody->appendChild($xmlForm);
if (isset($testDiv)) {
   $xmlBody->appendChild($testDiv);
   }
$xmlHr = $myxhtml->createElement("hr");
$xmlBody->appendChild($xmlHr);
$xmlAnchor = $myxhtml->createElement("a","filter class source");
$href = $thisdir . "/cspfilter_class.phps";
$xmlAnchor->setAttribute("href",$href);
$xmlPar = $myxhtml->createElement("p");
$xmlPar->appendChild($xmlAnchor);
$xmlBody->appendChild($xmlPar);
$xmlAnchor = $myxhtml->createElement("a","this page php source");
$href = $thisdir . "/dom_script_test.phps";
$xmlAnchor->setAttribute("href",$href);
$xmlPar = $myxhtml->createElement("p");
$xmlPar->appendChild($xmlAnchor);
$xmlBody->appendChild($xmlPar);

$xmlHtml->appendChild($xmlHead);
$xmlHtml->appendChild($xmlBody);

$sanitized = new cspfilter($myxhtml);
$sanitized->httphost = $http_host;
$sanitized->cspHeader = true;
$sanitized->csp['allow'] = $def_csp['allow'];
if (isset($def_csp['img-src'])) {
   $sanitized->csp['img-src'] = $def_csp['img-src'];
   }
if (isset($def_csp['media-src'])) {
   $sanitized->csp['media-src'] = $def_csp['media-src'];
   }
if (isset($def_csp['script-src'])) {
   $sanitized->csp['script-src'] = $def_csp['script-src'];
   }
if (isset($def_csp['object-src'])) {
   $sanitized->csp['object-src'] = $def_csp['object-src'];
   }
if (isset($def_csp['frame-src'])) {
   $sanitized->csp['frame-src'] = $def_csp['frame-src'];
   }
   
//$sanitized->inputDom($myxhtml);
$sanitized->processData();

$elements = $myxhtml->getElementsByTagName("div");
foreach ($elements as $element) {
   if ($element->hasAttribute("id")) {
      $divId = trim($element->getAttribute("id"));
      if ($divId == "formPostData") {
         $userInput = $element;
         }
      }
   }
if (isset($userInput)) {
   if ($userInput->hasChildNodes()) {
      $preXML = new DOMDocument("1.0","UTF-8");
      $preXML->preserveWhiteSpace = false;
      $preXML->formatOutput = true;
      $children = $userInput->childNodes;
      foreach ($children as $child) {
         $fooNode = $preXML->importNode($child,true);
         $preXML->appendChild($fooNode);
         }
      if ($usexml == 1) {
         $bar = $preXML->saveXML();
         $btype = "xml";
         } else {
         $bar = $preXML->saveHTML();
         $btype = "html";
         }
      $bar = preg_replace('/<\?xml[^>]*>\n/','',$bar,1);
      $bar = preg_replace('/^\s*$/','',$bar);
      $bar = preg_replace('/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/', '\n', $bar);
      $userSource = $myxhtml->createElement("pre",$bar);
      $userSource->setAttribute("style",$preStyle);
      $xmlHeader = $myxhtml->createElement("h3","Input after CSP Output Filtering (as $btype)");

      $elements = $myxhtml->getElementsByTagName("body");
      $xmlBody = $elements->item(0);
      $xmlBody->appendChild($xmlHeader);
      $xmlBody->appendChild($userSource);
      }
   }
   
$errorReport = $sanitized->displayViolationReport();
$xmlHeader = $myxhtml->createElement("h3","Policy Violation Report");
$preReport = $myxhtml->createElement("pre",$errorReport);
$preReport->setAttribute("style",$preStyle);
$elements = $myxhtml->getElementsByTagName("body");
$xmlBody = $elements->item(0);
$xmlBody->appendChild($xmlHeader);
$xmlBody->appendChild($preReport);

sendxhtmlheader($usexml);
$sanitized->makeCSP();   
   
if ($usexml == 0) {
   print $myxhtml->saveHTML();
   } else {
   print $myxhtml->saveXML();
   }

?>