diff options
author | diosmosis <diosmosis@users.noreply.github.com> | 2018-11-13 08:57:02 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-13 08:57:02 +0300 |
commit | e6a7ace51248f43d0ffa10e2e833bb79b1010182 (patch) | |
tree | 530d71cd3c854a18b77c8f754f0378ec6bb52c52 /tests/PHPUnit/Fixtures | |
parent | 50040d5874cd7831f1a90e9e52f8861a444e0d30 (diff) |
Regenerate OmniFixture dump w/ more xss payloads (#13556)
* Buffing xss testing system.
* More testing changes.
* Finish adding more xss test data.
* Update ui-test.php file.
* Use DI\add in test container override.
* Update OmniFixture.
* Get fixture to setup properly.
* Make xss sanity check work w/ persist fixture data option.
* Another sanity check tweak.
* Trying to debug xss sanity check.
* removing duplicates
* Fix xss testing JS.
* Escape widget category text.
* deal w/ angular input in goal name
* Ensure privacy manager links are safe and add automated test for dangerous links to UI tests.
* Create dangerous link method in xsstesting class.
* Make xss test failures a bit easier to debug and escape metric documentation for angular.
* Tweak quickaccess test.
* Try to get pviot by dimension test to pass.
* Tweak QuickAccess test and try to get xss reports to show.
* Fix exception message.
* Tweaks to fake xss report (cannot currently be displayed).
* Updating screenshots.
* In check for dangerous links test allow empty links that use dangerous prefix.
* fix a cou0le more tests.
* update more screenshots
* Update a couple more screenshots.
* Updated screenshot.
* update screenshots
* update two more screenshots
* Use ng-bind-html to sanitize report documentation which can potentially have HTML.
* update screenshots
Diffstat (limited to 'tests/PHPUnit/Fixtures')
-rw-r--r-- | tests/PHPUnit/Fixtures/ManySitesImportedLogsWithXssAttempts.php | 82 | ||||
-rw-r--r-- | tests/PHPUnit/Fixtures/UITestFixture.php | 225 |
2 files changed, 286 insertions, 21 deletions
diff --git a/tests/PHPUnit/Fixtures/ManySitesImportedLogsWithXssAttempts.php b/tests/PHPUnit/Fixtures/ManySitesImportedLogsWithXssAttempts.php index bdf0af01a7..72ba5ed6b6 100644 --- a/tests/PHPUnit/Fixtures/ManySitesImportedLogsWithXssAttempts.php +++ b/tests/PHPUnit/Fixtures/ManySitesImportedLogsWithXssAttempts.php @@ -8,10 +8,10 @@ namespace Piwik\Tests\Fixtures; use Piwik\Date; -use Piwik\Db; use Piwik\Plugins\Annotations\API as APIAnnotations; use Piwik\Plugins\Goals\API as APIGoals; -use Piwik\Tests\Framework\Fixture; +use Piwik\Tests\Framework\XssTesting; +use Piwik\Plugins\CustomDimensions\API as CustomDimensionsAPI; require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/Fixtures/ManySitesImportedLogs.php'; @@ -32,6 +32,7 @@ class ManySitesImportedLogsWithXssAttempts extends ManySitesImportedLogs { parent::setUp(); + $this->addCustomDimensions(); $this->trackVisitWithActionsXss(); $this->trackVisitsForRealtimeMap(Date::factory('2012-08-11 11:22:33'), $createSeperateVisitors = false); @@ -40,24 +41,49 @@ class ManySitesImportedLogsWithXssAttempts extends ManySitesImportedLogs $this->trackVisitsForRealtimeMap($this->now); } + public function addCustomDimensions() + { + if (!self::customDimensionExists($idSite = 1, $idCustomDimension = 1)) { + CustomDimensionsAPI::getInstance()->configureNewCustomDimension($idSite = 1, 'test dim', 'visit', true); + } + } + + private function customDimensionExists($idSite, $idCustomDimension) + { + $configured = CustomDimensionsAPI::getInstance()->getConfiguredCustomDimensions($idSite); + foreach ($configured as $dimension) { + if ($idCustomDimension == $dimension['idcustomdimension']) { + return true; + } + } + return false; + } + public function setUpWebsitesAndGoals() { + $xssTesting = new XssTesting(); + // for conversion testing if (!self::siteCreated($idSite = 1)) { - $siteName = self::makeXssContent("site name", $sanitize = true); + $siteName = $xssTesting->forTwig("site name", $sanitize = true); self::createWebsite($this->dateTime, $ecommerce = 1, $siteName); } if (!self::goalExists($idSite = 1, $idGoal = 1)) { APIGoals::getInstance()->addGoal( - $this->idSite, self::makeXssContent("goal name"), 'url', 'http', 'contains', false, 5, false, self::makeXssContent("goal description")); + $this->idSite, $xssTesting->forTwig("goal name"), 'url', 'http', 'contains', false, 5, false, $xssTesting->forTwig("goal description")); } if (!self::siteCreated($idSite = 2)) { - self::createWebsite($this->dateTime, $ecommerce = 0, $siteName = 'Piwik test two', + self::createWebsite($this->dateTime, $ecommerce = 0, $siteName = $xssTesting->forAngular('Piwik test two'), $siteUrl = 'http://example-site-two.com'); } + if (!self::goalExists($idSite = 2, $idGoal = 2)) { + APIGoals::getInstance()->addGoal( + $this->idSite, $xssTesting->forAngular("second goal"), 'url', 'http', 'contains', false, 5, false, $xssTesting->forAngular("goal description")); + } + if (!self::siteCreated($idSite = 3)) { self::createWebsite($this->dateTime, $ecommerce = 0, $siteName = 'Piwik test three', $siteUrl = 'http://example-site-three.com'); @@ -66,10 +92,11 @@ class ManySitesImportedLogsWithXssAttempts extends ManySitesImportedLogs public function addAnnotations() { + $xssTesting = new XssTesting(); APIAnnotations::getInstance()->add($this->idSite, '2012-08-09', "Note 1", $starred = 1); APIAnnotations::getInstance()->add( - $this->idSite, '2012-08-08', self::makeXssContent("annotation"), $starred = 0); - APIAnnotations::getInstance()->add($this->idSite, '2012-08-10', "Note 3", $starred = 1); + $this->idSite, '2012-08-08', $xssTesting->forTwig("annotation"), $starred = 0); + APIAnnotations::getInstance()->add($this->idSite, '2012-08-10', $xssTesting->forAngular("Annotation note 3"), $starred = 1); } public function trackVisitsForRealtimeMap($date, $createSeperateVisitors = true) @@ -130,15 +157,36 @@ class ManySitesImportedLogsWithXssAttempts extends ManySitesImportedLogs private function trackVisitWithActionsXss() { - $urlXss = self::makeXssContent('page url'); - $titleXss = self::makeXssContent('page title'); - - $t = self::getTracker($this->idSite, $this->dateTime, $defaultInit= true); - $t->setUrl('http://example.org/' . urlencode($urlXss)); - self::checkResponse($t->doTrackPageView(urlencode($titleXss))); - - $t->setForceVisitDateTime(Date::factory($this->dateTime)->addHour(1)->getDateTime()); - $t->setUrl('http://example.org/' . $urlXss); - self::checkResponse($t->doTrackPageView($titleXss)); + $xssTesting = new XssTesting(); + + $baseDay = Date::factory($this->dateTime)->addDay(10); + + $xssTypes = ['forTwig', 'forAngular']; + foreach ($xssTypes as $index => $type) { + $urlXss = $xssTesting->$type('pageurl'); + $titleXss = $xssTesting->$type('page title'); + $referrerUrlXss = 'http://referrer.com/' . $xssTesting->$type('referrerUrl'); + $referrerUrlSearchEngineXss = 'http://google.com/search?q=' . urlencode($xssTesting->$type('keyword')); + + $dateTime = $baseDay->addDay($index); + + $t = self::getTracker($this->idSite, $dateTime, $defaultInit= true); + $t->setUrl('http://example.org/' . urlencode($urlXss)); + $t->setUrlReferrer($referrerUrlXss); + $t->setCustomTrackingParameter('dimension1', $xssTesting->$type('customdimension')); + $t->setCustomVariable(1, $xssTesting->$type('customvarname'), $xssTesting->$type('customvarval')); + $t->setUserId($xssTesting->$type('userid')); + $t->setBrowserLanguage($xssTesting->$type('lang')); + $t->setCity($xssTesting->$type('city')); + $t->setRegion($xssTesting->$type('region')); + $t->setCountry($xssTesting->$type('country')); + $t->setUserAgent($xssTesting->$type('useragent')); + self::checkResponse($t->doTrackPageView(urlencode($titleXss))); + + $t->setForceVisitDateTime(Date::factory($dateTime)->addHour(1)->getDateTime()); + $t->setUrlReferrer($referrerUrlSearchEngineXss); + $t->setUrl('http://example.org/' . $urlXss); + self::checkResponse($t->doTrackPageView($titleXss)); + } } }
\ No newline at end of file diff --git a/tests/PHPUnit/Fixtures/UITestFixture.php b/tests/PHPUnit/Fixtures/UITestFixture.php index a5797e85a4..dbbe19a97d 100644 --- a/tests/PHPUnit/Fixtures/UITestFixture.php +++ b/tests/PHPUnit/Fixtures/UITestFixture.php @@ -9,20 +9,32 @@ namespace Piwik\Tests\Fixtures; use Exception; use Piwik\API\Request; +use Piwik\Columns\Dimension; use Piwik\Common; +use Piwik\DataTable; +use Piwik\DataTable\Row; use Piwik\Date; use Piwik\Db; use Piwik\DbHelper; use Piwik\FrontController; use Piwik\Option; use Piwik\Piwik; +use Piwik\Plugin\Dimension\VisitDimension; +use Piwik\Plugin\ProcessedMetric; +use Piwik\Plugin\Report; +use Piwik\Plugin\ViewDataTable; use Piwik\Plugins\GeoIp2\LocationProvider\GeoIp2; use Piwik\Plugins\PrivacyManager\IPAnonymizer; +use Piwik\Plugins\PrivacyManager\SystemSettings; +use Piwik\Plugins\ScheduledReports\ScheduledReports; use Piwik\Plugins\SegmentEditor\API as APISegmentEditor; use Piwik\Plugins\UserCountry\LocationProvider; use Piwik\Plugins\UsersManager\API as UsersManagerAPI; use Piwik\Plugins\SitesManager\API as SitesManagerAPI; use Piwik\Plugins\VisitsSummary\API as VisitsSummaryAPI; +use Piwik\ReportRenderer; +use Piwik\Tests\Framework\XssTesting; +use Piwik\Plugins\ScheduledReports\API as APIScheduledReports; /** * Fixture for UI tests. @@ -31,10 +43,16 @@ class UITestFixture extends SqlDump { const FIXTURE_LOCATION = '/tests/resources/OmniFixture-dump.sql'; + /** + * @var XssTesting + */ + private $xssTesting; + public function __construct() { $this->dumpUrl = PIWIK_INCLUDE_PATH . self::FIXTURE_LOCATION; $this->tablesPrefix = ''; + $this->xssTesting = new XssTesting(); } public function setUp() @@ -64,8 +82,36 @@ class UITestFixture extends SqlDump SitesManagerAPI::getInstance()->updateSite(1, null, null, true); // create non super user - UsersManagerAPI::getInstance()->addUser('oliverqueen', 'smartypants', 'oli@queenindustries.com'); + UsersManagerAPI::getInstance()->addUser('oliverqueen', 'smartypants', 'oli@queenindustries.com', $this->xssTesting->forTwig('useralias')); UsersManagerAPI::getInstance()->setUserAccess('oliverqueen', 'view', array(1)); + + // another non super user + UsersManagerAPI::getInstance()->addUser('anotheruser', 'anotheruser', 'someemail@email.com', $this->xssTesting->forAngular('useralias')); + UsersManagerAPI::getInstance()->setUserAccess('anotheruser', 'view', array(1)); + + // add xss scheduled report + APIScheduledReports::getInstance()->addReport( + $idSite = 1, + $this->xssTesting->forTwig('scheduledreport'), + 'month', + 0, + ScheduledReports::EMAIL_TYPE, + ReportRenderer::HTML_FORMAT, + ['ExampleAPI_xssReportforTwig', 'ExampleAPI_xssReportforAngular'], + array(ScheduledReports::DISPLAY_FORMAT_PARAMETER => ScheduledReports::DISPLAY_FORMAT_TABLES_ONLY) + ); + APIScheduledReports::getInstance()->addReport( + $idSite = 1, + $this->xssTesting->forAngular('scheduledreport'), + 'month', + 0, + ScheduledReports::EMAIL_TYPE, + ReportRenderer::HTML_FORMAT, + ['ExampleAPI_xssReportforTwig', 'ExampleAPI_xssReportforAngular'], + array(ScheduledReports::DISPLAY_FORMAT_PARAMETER => ScheduledReports::DISPLAY_FORMAT_TABLES_ONLY) + ); + + $this->addDangerousLinks(); } public function performSetUp($setupEnvironmentOnly = false) @@ -95,6 +141,8 @@ class UITestFixture extends SqlDump $this->testEnvironment->forcedNowTimestamp = $forcedNowTimestamp; $this->testEnvironment->save(); + $this->xssTesting->sanityCheck(); + // launch archiving so tests don't run out of time print("Archiving in fixture set up..."); VisitsSummaryAPI::getInstance()->get('all', 'year', '2012-08-09'); @@ -296,7 +344,9 @@ class UITestFixture extends SqlDump foreach ($dashboards as $id => $layout) { if ($id == 0) { - $_GET['name'] = self::makeXssContent('dashboard name' . $id); + $_GET['name'] = $this->xssTesting->forTwig('dashboard name' . $id); + } else if ($id == 1) { + $_GET['name'] = $this->xssTesting->forAngular('dashboard name' . $id); } else { $_GET['name'] = 'dashboard name' . $id; } @@ -335,15 +385,182 @@ class UITestFixture extends SqlDump { Db::exec("TRUNCATE TABLE " . Common::prefixTable('segment')); - $segmentName = self::makeXssContent('segment'); + $segmentName = $this->xssTesting->forTwig('segment'); $segmentDefinition = "browserCode==FF"; APISegmentEditor::getInstance()->add( $segmentName, $segmentDefinition, $idSite = 1, $autoArchive = true, $enabledAllUsers = true); // create two more segments + $segmentName = $this->xssTesting->forAngular("From Europe segment"); APISegmentEditor::getInstance()->add( - "From Europe", "continentCode==eur", $idSite = 1, $autoArchive = false, $enabledAllUsers = true); + 'From Europe ' . $segmentName, "continentCode==eur", $idSite = 1, $autoArchive = false, $enabledAllUsers = true); APISegmentEditor::getInstance()->add( "Multiple actions", "actions>=2", $idSite = 1, $autoArchive = false, $enabledAllUsers = true); } + + public function provideContainerConfig() + { + return [ + 'observers.global' => \DI\add([ + ['Report.addReports', function (&$reports) { + $report = new XssReport(); + $report->initForXss('forTwig'); + $reports[] = $report; + + $report = new XssReport(); + $report->initForXss('forAngular'); + $reports[] = $report; + }], + ['Dimension.addDimensions', function (&$instances) { + $instances[] = new XssDimension(); + }], + ['API.Request.intercept', function (&$result, $finalParameters, $pluginName, $methodName) { + if ($pluginName != 'ExampleAPI' && $methodName != 'xssReportforTwig' && $methodName != 'xssReportforAngular') { + return; + } + + $dataTable = new DataTable(); + $dataTable->addRowFromSimpleArray([ + 'label' => $this->xssTesting->forAngular('datatablerow'), + 'nb_visits' => 10, + ]); + $dataTable->addRowFromSimpleArray([ + 'label' => $this->xssTesting->forTwig('datatablerow'), + 'nb_visits' => 15, + ]); + $result = $dataTable; + }], + ]), + ]; + } + + public function addDangerousLinks() + { + $privacyManagerSettings = new SystemSettings(); + $privacyManagerSettings->termsAndConditionUrl->setValue($this->xssTesting->dangerousLink("termsandconditions")); + $privacyManagerSettings->termsAndConditionUrl->save(); + $privacyManagerSettings->privacyPolicyUrl->setValue($this->xssTesting->dangerousLink("privacypolicyurl")); + $privacyManagerSettings->privacyPolicyUrl->save(); + } +} + +class XssReport extends Report +{ + private $xssType; + + protected function init() + { + parent::init(); + + $this->metrics = array('nb_visits'); + $this->order = 10; + + $action = Common::getRequestVar('actionToWidgetize', false) ?: Common::getRequestVar('action', false); + if ($action == 'xssReportforTwig') { + $this->initForXss('forTwig'); + } else if ($action == 'xssReportforAngular') { + $this->initForXss('forAngular'); + } + } + + public function initForXss($type) + { + $this->xssType = $type; + + $xssTesting = new XssTesting(); + $this->dimension = new XssDimension(); + $this->dimension->initForXss($type); + $this->name = $xssTesting->$type('reportname'); + $this->documentation = $xssTesting->$type('reportdoc'); + $this->categoryId = $xssTesting->$type('category'); + $this->subcategoryId = $xssTesting->$type('subcategory'); + $this->processedMetrics = [new XssProcessedMetric($type)]; + $this->module = 'ExampleAPI'; + $this->action = 'xssReport' . $type; + $this->id = 'ExampleAPI.xssReport' . $type; + } + + public function configureView(ViewDataTable $view) + { + parent::configureView($view); + + $type = $this->xssType; + + $xssTesting = new XssTesting(); + $view->config->show_footer_message = $xssTesting->$type('footermessage'); + } +} + +class XssDimension extends VisitDimension +{ + public $type = Dimension::TYPE_NUMBER; + + private $xssType; + + public function initForXss($type) + { + $xssTesting = new XssTesting(); + + $this->xssType = $type; + $this->nameSingular = $xssTesting->$type('dimensionname'); + $this->columnName = 'xsstestdim'; + $this->category = $xssTesting->$type('category'); + } + + public function getId() + { + return 'XssTest.XssDimension.' . $this->xssType; + } +} + +class XssProcessedMetric extends ProcessedMetric +{ + /** + * @var string + */ + private $xssType; + + /** + * @var string + */ + private $name; + + /** + * @var string + */ + private $docs; + + public function __construct($type) + { + $xssTesting = new XssTesting(); + + $this->xssType = $type; + $this->name = $xssTesting->$type('processedmetricname'); + $this->docs = $xssTesting->$type('processedmetricdocs'); + } + + public function getName() + { + return 'xssmetric'; + } + + public function getTranslatedName() + { + return $this->name; + } + + public function getDocumentation() + { + return $this->docs; + } + + public function compute(Row $row) + { + return 5; + } + + public function getDependentMetrics() + { + return []; + } } |