-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Summary
User-controlled img src allows loading untrusted frames, enabling internal service probe & info gathering, content manipulation within trusted contexts.
Details
ruoyi-admin\src\main\resources\static\ajax\libs\summernote\summernote.js
Taint Analysis
- The entry point is in the click event of the toolbar image button:
click: _this2.context.createInvokeHandler('imageDialog.show')
- This click event calls the
show
method of theImageDialog
class:
show() {
var _this = this;
this.context.invoke('editor.saveRange');
this.showImageDialog().then(function (data) {
_this.ui.hideDialog(_this.$dialog);
_this.context.invoke('editor.restoreRange');
if (typeof data === 'string') {
if (_this.options.callbacks.onImageLinkInsert) {
_this.context.triggerEvent('image.link.insert', data);
} else {
_this.context.invoke('editor.insertImage', data);
- The
show
method calls theshowImageDialog
method to display the image dialog and get user input:
key: "showImageDialog",
value: function showImageDialog() {
var _this2 = this;
return external_root_jQuery_commonjs2_jquery_commonjs_jquery_amd_jquery_default.a.Deferred(function (deferred) {
var $imageUrl = _this2.$dialog.find('.note-image-url');
var $imageBtn = _this2.$dialog.find('.note-image-btn');
$imageBtn.click(function (event) {
event.preventDefault();
deferred.resolve($imageUrl.val()); // 获取用户输入的URL并通过deferred返回
- When the user clicks the insert button,
deferred.resolve($imageUrl.val())
inshowImageDialog
returns the URL to the then callback of theshow
method, which then calls theinsertImage
method of theEditor
class throughcontext.invoke('editor.insertImage', data)
:
key: "insertImage",
value: function insertImage(src, param) {
var _this3 = this;
return createImage(src, param).then(function ($image) {
_this3.beforeCommand();
if (typeof param === 'function') {
param($image);
} else {
if (typeof param === 'string') {
$image.attr('data-filename', param);
}
$image.css('width', Math.min(_this3.$editable.width(), $image.width()));
}
$image.show();
_this3.getLastRange().insertNode($image[0]); // 将图片插入到编辑器中
The complete data flow is:
-> User clicks the image button in the toolbar -> triggers imageDialog.show
-> calls the ImageDialog.show()
method
-> the show()
method calls showImageDialog()
to display the dialog
-> user enters URL in the dialog and clicks the insert
button
-> deferred.resolve($imageUrl.val())
in showImageDialog()
returns the URL
-> URL is passed to context.invoke('editor.insertImage', data)
through the then callback of the show()
method
-> finally calls the Editor.insertImage()
method to insert the URL into the src attribute of the img tag
POC

