前言
Collabora 是一家专注于开源软件的公司,主要提供与文档协作、办公套件和企业解决方案相关的服务。
Collabora 提供了 Collabora Online,这是一个基于 Web 的在线办公套件,允许用户在浏览器中实时编辑文档。这种服务特别适合团队协作和远程工作,可以与各种云存储服务集成,如 Nextcloud、ownCloud 和其他企业云解决方案。
正文
与大多数文档解决方案类似,Collabora 提供了交叉引用功能。该功能允许用户引用其他页面上的文档部分内容,并能自动更新这些引用。当我们将鼠标悬停在引用上时,会出现一个工具提示菜单,显示有关引用内容的更多上下文信息。
为了探究将鼠标悬停在引用上时会发生什么,我们使用 BurpSuite 开始拦截网络流量。将鼠标悬停在引用上时,浏览器会通过 WebSocket 发送一条消息,该消息包含我们设定的工具提示内容:
在工具提示内容中添加XSS Payload,点击发送后,再将鼠标悬停在引用上,触发XSS:
代码审计
现在让我们探究其漏洞成因。
CollaboraOnline在Git存储的代码库为:
https://github.com/CollaboraOnline/online
在/browser/src/layer/tile/CanvasTileLayer.js目录下找到对应的 websocket 消息处理程序代码:
_onMessage: function (textMsg, img) {
this._saveMessageForReplay(textMsg);
...
else if (textMsg.startsWith('tooltip:')) {
var tooltipInfo = JSON.parse(textMsg.substring('tooltip:'.length + 1));
if (tooltipInfo.type === 'formulausage') {
this._onCalcFunctionUsageMsg(tooltipInfo.text);
}
else if (tooltipInfo.type === 'generaltooltip') {
var tooltipInfo = JSON.parse(textMsg.substring(textMsg.indexOf('{')));
this._map.uiManager.showDocumentTooltip(tooltipInfo); // [1]
}
else {
console.error('unknown tooltip type');
}
}
...
}
我们使用的是通用工具提示,即上面代码中对应的这一部分:
else if (tooltipInfo.type === 'generaltooltip') {
var tooltipInfo = JSON.parse(textMsg.substring(textMsg.indexOf('{')));
this._map.uiManager.showDocumentTooltip(tooltipInfo); // [1]
}
总的来说,即鼠标悬停在引用上时,工具提示的信息通过 WebSocket 发送,并在 _onMessage 函数中使用JSON.parse() 方法将信息转换为JavaScript 对象。然后调用showDocumentTooltip()函数,将工具提示展示出来。
showDocumentTooltip()函数位于
/browser/src/control/Control.UIManager.js中,跟进该函数:
showDocumentTooltip: function(tooltipInfo) {
var split = tooltipInfo.rectangle.split(',');
var latlng = this.map._docLayer._twipsToLatLng(new L.Point(+split[0], +split[1]));
var pt = this.map.latLngToContainerPoint(latlng);
var elem = $('.leaflet-layer');
elem.tooltip();
elem.tooltip('enable');
elem.tooltip('option', 'content', tooltipInfo.text);
elem.tooltip('option', 'items', elem[0]);
elem.tooltip('option', 'position', { my: 'left bottom', at: 'left+' + pt.x + ' top+' + pt.y, collision: 'fit fit' });
elem.tooltip('open');
document.addEventListener('mousemove', function() {
elem.tooltip('close');
elem.tooltip('disable');
}, {once: true});
},
该函数的功能主要是解析位置坐标、计算容器位置、初始化和配置工具提示等,在这其中调用了.tooltip(...) ,其应用于 $('.leaflet-layer') 元素上
在 leafletjs API文档的工具提示中,跟进tooltip(...) :
其使用示例如下:
可以看到,content中允许包含 HTML 标签。
接着,我们访问有关工具提示组件的存储库,查看后端是怎么对content进行处理的:
https://github.com/Leaflet/Leaflet/blob/f46286311a7e3bc691034a349edf765e8b14f71a/src/layer/Tooltip.js
该文件并没有对content进行处理,它扩展了 DivOverlay 组件:
import {DivOverlay} from './DivOverlay.js';
...
export const Tooltip = DivOverlay.extend({
...
});
跟进该DivOverlay组件,其位于src/layer/DivOverlay.js下,而该文件中的_updateContent函数实现了对content的处理:
_updateContent() {
if (!this._content) { return; }
const node = this._contentNode;
const content = (typeof this._content === 'function') ? this._content(this._source || this) : this._content;
if (typeof content === 'string') {
node.innerHTML = content;
} else {
...
}
...
},
可以看到,如果 content 是 string 类型,则会将其赋值node.innerHTML,最终浏览器解析HTML时,导致储存型XSS。
原文出处:
https://cyllective.com/blog/posts/cve-2024-29182-collabora
SRC漏洞挖掘培训
往期漏洞分享
CVSS 10信息披露+图片元数据不适当处理+大小写绕过速率限制
Oracle Apiary:SSRF获取元数据
SSRF 之 Azure Digital Twins Explorer
玲珑安全交流群
玲珑安全B站免费公开课
https://space.bilibili.com/602205041
原文始发于微信公众号(芳华绝代安全团队):Collabora在线存储型XSS(CVE-2024-29182)+代码审计
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论