如果你打算开发一个插件或者为Matomo(以前的Piwik) Core做出贡献代码必须是安全的.
本指南包含对抗某些漏洞的方法列表。在开发插件或贡献时,请遵循所有这些原则。
XSS恶意脚本(如JavaScript)注入用户界面。它允许攻击者获得应用程序的控制权或窃取信息。
攻击者可以通过以下方式实现:
在PHP代码中,如果需要访问变量$ _GET
或$ _POST
,总是使用常见的::getRequestVar ().
getRequestVar ()
将清除请求变量。如果攻击者传递一个包含脚本> <…> < /脚本
,它将被消毒& lt; script>……& lt; / script>
.这将有助于避免意外地在HTML输出中嵌入未转义的文本。
对于您知道可能包含特殊字符的文本,或者如果您需要以不需要XML/HTML处理的格式(如JSON)输出文本,请调用Piwik: unsanitizeInputValues ()解除消毒。
注意:可以使用。清除不在请求参数中的文本Piwik: sanitizeInputValues ().
使用是很重要的正确的逃生策略这取决于打印值的位置。例如,当在HTML属性中打印“title”或“label”等值时,我们需要使用| e(“html_attr”)
逃避策略。其他逃避策略包括js
,css
,url
而且超文本标记语言
(这是默认策略)。
|生
在Twig模板中很少使用当你写嫩枝模板,尽量避免使用|生
尽可能进行筛选。作为一种替代方法,将希望重用的HTML放在单独的模板和中{% include %}
它。
如果你使用|生
,确保您插入的内容已正确转义。
如果你必须使用|生
过滤器,您可能要考虑使用| rawSafeDecoded
过滤器,可能更安全。
jQuery.html ()
在JavaScript中,使用美元. html
方法将HTML插入到DOM中。确保您插入的字符串来自Matomo并且已经转义。
如果您知道您插入的文本不应该是HTML,那么不要使用$ . html ()
,而是使用美元。text ()
或$ .val ()
.例如:
var ajaxData = getDataFromAjax();$ (' # someLabel ')。text (ajaxData.labelToUse);
要转义JavaScript中的字符串,可以使用helper方法piwikHelper.escape
例如:
var safeString = piwikHelper.escape(userInputUnsafeString);$ (" # someLabel”)。text(safeString);
内容安全策略在Matomo中默认设置(从Matomo 4.6.0开始),插件可以根据需要使用$ this - > securityPolicy
方法,例如:
$ this - > securityPolicy - > addPolicy(‘image-src’,‘自我’);
或者通过创建依赖项注入插件/编写MyPlugin / config / config . php
像这样将更改应用到每个UI请求,而不仅仅是特定的请求:
返回array(\Piwik\View\SecurityPolicy::class => DI\ decoration (function ($previous) {/** @var \Piwik\View\SecurityPolicy $previous */ if (!\Piwik\SettingsPiwik::isMatomoInstalled()){返回$previous;} $previous->addPolicy('default-src', 'my-cdn.example.com');返回前一美元;}));
考虑使用默认值,或者在可能的情况下使用更严格的CSP,以防止某些XSS攻击。
CSRF攻击是指攻击者让Matomo用户不情愿地执行某个操作。为了达到这个目的,攻击者向用户发送一个链接。例如,该链接可以指向一个Matomo控制器方法,该方法可以更改用户的密码,或者删除一个站点。
可以使用以下技术防止这种攻击:
在你创建的每一个改变Matomo设置的控制器方法中,改变用户的设置或执行一些其他管理级别的函数,调用控制器:checkTokenInUrl ()方法。例如:
//方法在控制器公共函数doSomeAdminStuff() {$this->checkTokenInUrl();/ /……}
在执行某些管理级别函数的每个API方法中,请确保通过调用某个方法来检查适当的用户权限Piwik::检查…方法。例如:
//方法在API类公共函数changeSettingsForUser($userLogin) {Piwik::checkUserHasSuperUserAccessOrIsTheUser($userLogin);}
你的JavaScript应该发送token_auth到需要它的控制器和API方法,但是你应该确保token_auth永远不会出现在URL中.这样,它将永远不会被浏览器保存或缓存。
为了保持token_auth在浏览器缓存中,你可以使用POST请求。
SQL注入是通过注入恶意SQL语句来操纵应用程序的SQL查询。攻击者可以通过应用程序的输入注入恶意SQL:表单字段、请求参数、…
例如,如果一个应用程序构建了这样一个SQL查询:
$sql = 'SELECT * from mytable where id = '$ _GET [' id '];
攻击者可以通过“1或1”
为id
URL参数。这将导致执行以下查询:SELECT * from mytable where id = 1 OR 1
,输出的每一行mytable.
SQL注入可以通过做一件事来防止:
在编写SQL语句时,使用SQL准备语句,而不是直接在语句中插入变量。SQL准备语句意味着在SQL查询中使用占位符。
换句话说,不要这样做:
$idSite = Common::getRequestVar('idSite');//不要这样做!!$sql = "SELECT * FROM "。Common::prefixTable('site')。"WHERE idsite = "。idSite美元;数据库::查询($sql);
相反,这样做:
$idSite = Common::getRequestVar('idSite');$sql = "SELECT * FROM "。Common::prefixTable('site')。"WHERE idsite = ?";$rows = Db::query($sql,数组($idSite));
远程文件包含包含和执行不属于web应用程序的源代码。它发生在PHP中包括
或需要
使用用户确定路径的语句。
在Matomo中,防止远程文件包含攻击的最佳方法是永远不要需要
/包括
使用用户数据的文件。相反,把逻辑放到可以由Matomo的自动加载器加载的类中并根据从用户获得的数据实例化/使用不同的类。换句话说,不要这样做:
$clientToUse = Common::getRequestVar('seoClient');//不要这样做!!require_once PIWIK_INCLUDE。“编写MyPlugin /客户/ /插件/”。clientToUse美元。“。php”;$client = new $ clienttuse ();/ /……使用$client…
相反,这样做:
$clientToUse = Common::getRequestVar('seoClient');if ($clientToUse == 'mySeoProvider') {$client =新客户\ mySeoProvider ();} else if ($clientToUse == 'myOtherSeoProvider') {$client = new Clients\ myOtherSeoProvider ();} else{抛出新的异常("无效的SEO提供者客户端:$ clienttuse !");} //…使用$client…
这里有一些其他的编码指南,将有助于使您的代码更安全:
PHP文件应该以<?php
永不关闭的标签。
使用. php
扩展所有的PHP脚本。
避免使用下列函数之一执行php代码:eval,执行,passthru,系统,popen或preg_replace(“e”
修饰符)。
确保直接访问您的文件不会执行任何可能影响您的Matomo安装的代码。
确保您的代码不依赖于register_globals
设置为在
.注:PHP5套register_globals
来从
默认情况下。
用于定时攻击安全的相等比较常见的::hashEquals ()
方法
如果你的插件有管理功能(只有管理员或超级用户可以使用的功能),那么你的插件的控制器必须扩展Piwik \ \ ControllerAdmin插件.
绝不低于一个完整的清单。你总是会被要求想出任何其他我们不希望它被使用的情况。这只是一个最常见的检查列表。
常见的::hashEquals
使用rel = " noreferrer noopener”
(尽管新版本的浏览器会自动添加)。的noopener
是出于安全原因。的noreferrer
出于隐私考虑。看到rel = noreferrer而且rel = noopener非系列化
用户输入不安全。考虑使用常见的::safe_unserialize
或者可能用于用户输入JSON
而不是函数
不安全的时候,例如一个协议phar: / /
能传递给它吗