安全相关功能
XWiki提供了保障安全的一些功能而某些功能还存在安全隐患。
Admin 密码
Admin用户的默认密码为admin。请确保您更改密码。
您还可以删除Admin用户,但首先你需要确保它不是任何页面的author,因为它可能会产生的问题 (一些标准页面需要它的author有足够的权限).
Superadmin 账号
XWiki提供了一个超级管理员帐户。它是特殊的,因为:
- Superadmin不存储在数据库中
- Superadmin不能以任何方式被修改
- Superadmin具有所有访问权限,不管权限设置
因为超级管理员帐户是如此强大,所以不建议长期启动这个账号
默认情况下,该帐户被禁用。要启用它,你必须编辑<xwiki-dir>/WEB-INF/xwiki.cfg,取消对#xwiki.superadminpassword=system的注释,并设置了正确的密码。要禁用它,只要注释此行即可。记住修改xwiki.cfg之后需要重新启动servlet容器。
某些情况下,超级管理员帐户是可以被启动,举例来说,如果当你忘记您的管理员用户密码、搞乱了一些权限,或者不小心删除了管理员用户。
Cookies
默认情况下XWiki(和大多数web项目一样)用户登录后会在Cookie里保存信息。这些可以是被攻击者利用。
Cookie 加密密钥
当用户登录时,cookies在他的机器上保存用户名,密码和一个“nothing up my sleeve”散列值。cookies是被加密的,使得没有人对它访问能看到用户名/密码。加密是根据用位于xwiki.cfg(位于WEB-INF下面)配置文件的2个配置参数。
编辑xwiki.cfg文件,修改Cookie身份验证和加密密钥的默认值,因为这些预定义的值可以被攻击者利用来破译用户名和密码,这一点很重要。为了防止这种情况,请更改以下2配置参数:
- xwiki.authentication.validationKey
- xwiki.authentication.encryptionKey
在未来的版本中,我们希望在安装xwiki时产生随机以及和主机相关的密钥对
使用IP地址加密cookies
即使密码不能从cookie提取,但是cookie还是可能被窃取(XSS攻击)
通过设置xwiki.cfg参数xwiki.authentication.useip为true可以被用来阻止窃取cookie,因为设置为只有相同的IP地址的才能获取。
覆盖版本信息
默认情况下,XWiki Enterprise的版本会显示在每一页的页脚。这本身不是有害的,但对于攻击者,可以通过此信息获得相应版本的已知的漏洞
您可以使用Administration Application(后台管理应用程序)来修改页脚显示版本的字符串。点击Presentaton图标,在更改版本字段中修改。
如果你想确保版本信息不会泄露在任何地方,你可以通过WEB-INF/version.properties替换version内容:version=your version string here
讨论攻击媒介
完美的安全性通常被认为是不可能的。通过简单的静态HTML,我们实现可以近乎完美的安全性,但这些都不是非常有用的。本文讨论了不同的威胁模型,以及如何对付每一个。这些攻击是由访问类型分组。比较危险的攻击请从头开始看,最常见的攻击危险性较低(和更容易执行)的请直接看底部。
服务器攻击
在操作系统中这种攻击的特征很大程度上超出了本文档的范围,因为这是操作系统的责任防止用户提升权限。
可能/已知问题
不是一个非常常见的攻击方法。
缓解方法
- 运行在一个像样的操作系统
- Java虚拟机上运行XWiki用自己的用户名,只能给该用户分配XWiki需要操作文件的权限,并确保该用户不能通过sudo执行一些命令。
- 请不要在服务器上运行无关的进程
- 在非标准端口上运行的服务(如SSH,把22改为2222)
- 防火墙上只对一些需要的端口开放
Java VM 攻击
这种攻击的特征是攻击者利用Java执行任意代码,可能使用Java级别的安全漏洞来执行本地代码(Native Code)从而获得在Java虚拟机进程的用户级访问。
可能/已知问题
- XWiki需要反射机制来获取component module的私有成员变量和变量,这意味着JSR223 scripts比如Groovy和Python可以通过 Java Native Access,运行native代码(原生代码)来读写系统任何字段或变量。虚拟wikis无法防御这种攻击方法,因此没有给分配虚拟wiki管理员programming权限(注意还有另外一个原因,一个farm不给wiki管理员programming的权限,那是因为你可以在另一个wiki访问任何没有权限访问的文件)。这个漏洞可能导致备份出系统所连接的数据库,不过用户密码是以SHA-512散列算法加密。
- 这种攻击方法需要注册的用户有编程(programming )权限
缓解方法
- 启用SecurityManager,如果component manager调用时,只允许未经检查的反射
- 禁用groovy
- 保护规划programming权限,设置有一个特殊的用户名保存包含Groovy脚本的文件
数据库注入攻击
这种攻击发生在一些不安全脚本,利用数据库抛出报错信息。
可能/已知问题
- XWiki使用Hibernate作为数据库控制器所以一些注入方法会得到缓解。 XWiki给予你创建安全的脚本和不安全脚本的能力
- 通常可以不通过注册的用户名进行这种攻击方法。
缓解方法
- 你可以使用这个groovy代码来测试你的数据库,看看它是否支持堆叠查询(Stacking Queries)。如果你的数据库不支持堆查询,则SELECT注入只能做SELECT查询:
{{groovy}}
try {
session = xcontext.getContext().getWiki().getHibernateStore().getSessionFactory().openSession();
session.connection().createStatement().execute("begin transaction; rollback;");
println("Your database supports stacked queries.")
} catch (Exception e) {
println("Your database does not support stacked queries.");
} finally {
try {
session.close()
} catch (Exception e) {}
}
{{/groovy}} - 配置数据库日志或者如果可能的话禁用注释语法 -- /* */ and # 。Hibernate不使用注释以及注释是SQL注入可以利用的一种方式。
- 在脚本设计需避免将用户输入带到数据库查询
错误:
#set($x = $xwiki.searchDocuments("where doc.fullName = '${userContent}'"))
如果用户输入: ' or doc.hidden = 1 or doc.fullName = ' 你的代码将执行Hibernate查询: where doc.fullName = '' or doc.hidden = 1 or doc.fullName = ''.
上面例子可能不会导致一个可怕的后果,但攻击者一定可以拼接出更为危险的注入。
幸运的是Hibernate本身防止最严重的注入如:
Embarrassing Mistake'); DROP TABLE xwikidoc;--
这是因为hibernate一次不允许多个命令,不允许--注释语法
正确:
## We are passing a ? in the query and then passing the parameter as a list (Velocity notation for list is [element, element] )
#set($x = $xwiki.searchDocuments("where doc.fullName = ?", [$userContent]))
使用named parameter方式进行参数绑定。以名为userContent参数,传递到数据库。上述注入将无法正常工作。
- 避免“Privileged API”只要有可能,避免使用。如果你的每一个调用,需要你通过上下文作为一个参数,那你就错了。
欲了解更多信息,请查看XWiki API。
Cross Site Scripting
跨站脚本攻击或者XSS是所有攻击方法里危害最小的,但是也是最常见的。
XSS可以导致网站挂马或者盗取用户cookie。XSS也可以利用Web浏览器和插件,如PDF或ActiveX。这类漏洞往往安装恶意软件。
Persistent injection
Persistent injection(存储型XSS)的特征在于内容保存在系统中,当用户不知情下加载,在浏览器执行如JavaScript。这是比较危险的种类,因为它坐落在一个页面等待受害者。
- 通过编辑文档进行Persistent injection
2. 通过发布评论进行Persistent injection
可能/已知问题
- XWiki 1.0语法没有过滤掉HTML,导致脚本注入可能
- XWiki 2.0语法包含HTML宏,当被调用允许注入原生HTML和脚本。目前还没有安全的方法来解决
- 这种攻击方法需要攻击者拥有一个注册的用户(除非允许匿名编辑或允许评论)
缓解方法
- 只有这样,才能确保脚本无法在内容上注入(XWiki/1.0或XWiki/2.0)如下:
{{html}}
然而有一些方法可以尽量减少风险::
$escapetool.html($userContent)
{{/html}} - 禁止创建页面使用1.0语法。注:如果已经是1.0语法的页面仍然可以更新到语法2.0,否则必须对页面的编辑加锁,以便只有授权的用户可以对其进行编辑。
- 强制未经授权的用户通过发布脚本逃避{{(双括号内),因为目前还没有办法对未经授权的用户HTML宏注入进行预防。
- 设置ObservationManager扫描所有网页的内容和对象属性当HTML宏更新时,进行提醒。
reflective injection
Reflective injection(反射型XSS)特征是通过诱使用户点击特制链接,该链接会导致页面生成JavaScript。
- Reflective injection通过表单字段来进行攻击。
缓解方法
管理员可以使用一些插件,如noscript,能检测反射注入攻击,当检测到XSS攻击时提醒用户不要点击可疑链接。
- 当内容从请求参数加载到一个表单字段,确保其使用EscapeTool进行转义
错误:
<input type=text value="$request.get('name')" />
正确:
<input type=text value="$escapetool.html($request.get('name'))" />
Cross site request forgery (CSRF)
跨站请求伪造是一个外部网站制作一个恶意链接或表单指向你的系统中的一些操作比如保存文章,当一个登录过你的系统的用户点击后会导致进行这个操作,既保存了文章。
可能/已知问题
目前还没有实现以防止表单提交外部网站系统。请参阅有关实现secret tokens的邮件列表的讨论。
缓解方法
管理员可以使用一些插件,如noscript ,能防止攻击的网站自动提交表单到你的系统。