mirror of
https://github.com/paradoxxxzero/butterfly.git
synced 2026-06-01 01:49:44 +00:00
Allow html by default by using the google caja sanitizer
This commit is contained in:
@@ -41,9 +41,6 @@ tornado.options.define("cmd",
|
||||
help="Command to run instead of shell, f.i.: 'ls -l'")
|
||||
tornado.options.define("unsecure", default=False,
|
||||
help="Don't use ssl not recommended")
|
||||
tornado.options.define("allow_html_escapes", default=False,
|
||||
help="Allow use of HTML escapes. "
|
||||
"Really unsafe as it is now.")
|
||||
tornado.options.define("force_unicode_width",
|
||||
default=False,
|
||||
help="Force all unicode characters to the same width."
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
w = sys.stdout.write
|
||||
print('Image injection test')
|
||||
injection = 'R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" onload="alert(\'pwnd\')" /><img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='
|
||||
w('\x1bP;IMAGE|image/gif;%s' % injection)
|
||||
w('\x1bP')
|
||||
|
||||
|
||||
print('HTML script execution test')
|
||||
w('\x1bP;HTML|<img src="https://imgs.xkcd.com/comics/hack.png" onload="alert(\'pwnd\')" />')
|
||||
w('\x1bP')
|
||||
|
||||
2
butterfly/static/ext.min.js
vendored
2
butterfly/static/ext.min.js
vendored
File diff suppressed because one or more lines are too long
1
butterfly/static/html-sanitizer.js
Normal file
1
butterfly/static/html-sanitizer.js
Normal file
File diff suppressed because one or more lines are too long
@@ -148,7 +148,6 @@
|
||||
this.ctl = ctl1 != null ? ctl1 : function() {};
|
||||
this.document = this.parent.ownerDocument;
|
||||
this.body = this.document.getElementsByTagName('body')[0];
|
||||
this.htmlEscapesEnabled = this.body.getAttribute('data-allow-html') === 'yes';
|
||||
this.forceWidth = this.body.getAttribute('data-force-unicode-width') === 'yes';
|
||||
this.body.className = 'terminal focus';
|
||||
this.body.style.outline = 'none';
|
||||
@@ -184,11 +183,15 @@
|
||||
return _this.resize();
|
||||
};
|
||||
})(this));
|
||||
this.body.addEventListener('load', (function(_this) {
|
||||
return function() {
|
||||
return _this.nativeScrollTo();
|
||||
};
|
||||
})(this), true);
|
||||
if (typeof InstallTrigger !== "undefined") {
|
||||
this.body.contentEditable = 'true';
|
||||
}
|
||||
this.initmouse();
|
||||
setTimeout(this.resize.bind(this), 100);
|
||||
}
|
||||
|
||||
Terminal.prototype.cloneAttr = function(a, char) {
|
||||
@@ -521,7 +524,7 @@
|
||||
data = line.chars[i];
|
||||
if (data.html) {
|
||||
out += data.html;
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (skipnext) {
|
||||
skipnext = false;
|
||||
@@ -615,7 +618,7 @@
|
||||
if (!this.equalAttr(attr, this.defAttr)) {
|
||||
out += "</span>";
|
||||
}
|
||||
if (j !== this.y + this.shift) {
|
||||
if (!(j === this.y + this.shift || data.html)) {
|
||||
out = this.linkify(out);
|
||||
}
|
||||
if (line.wrap) {
|
||||
@@ -753,7 +756,7 @@
|
||||
};
|
||||
|
||||
Terminal.prototype.write = function(data) {
|
||||
var attr, b64, c, ch, content, cs, i, k, l, len, line, m, mime, num, pt, ref, ref1, ref2, ref3, type, valid;
|
||||
var attr, b64, c, ch, content, cs, i, k, l, len, line, m, mime, num, pt, ref, ref1, ref2, ref3, safe, type, valid;
|
||||
i = 0;
|
||||
l = data.length;
|
||||
while (i < l) {
|
||||
@@ -1189,15 +1192,15 @@
|
||||
}
|
||||
switch (type) {
|
||||
case "HTML":
|
||||
if (!this.htmlEscapesEnabled) {
|
||||
console.log("HTML escapes are disabled");
|
||||
break;
|
||||
}
|
||||
safe = html_sanitize(content, function(l) {
|
||||
return l;
|
||||
});
|
||||
attr = this.cloneAttr(this.curAttr);
|
||||
attr.html = "<div class=\"inline-html\">" + content + "</div>";
|
||||
attr.html = "<div class=\"inline-html\">" + safe + "</div>";
|
||||
this.screen[this.y + this.shift].chars[this.x] = attr;
|
||||
this.screen[this.y + this.shift].dirty = true;
|
||||
this.screen[this.y + this.shift].wrap = false;
|
||||
this.nextLine();
|
||||
break;
|
||||
case "IMAGE":
|
||||
content = encodeURI(content);
|
||||
@@ -1739,7 +1742,7 @@
|
||||
}
|
||||
return {
|
||||
chars: line,
|
||||
dirty: true,
|
||||
dirty: false,
|
||||
wrap: false
|
||||
};
|
||||
};
|
||||
|
||||
6
butterfly/static/main.min.js
vendored
6
butterfly/static/main.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -14,8 +14,8 @@
|
||||
</head>
|
||||
|
||||
<body spellcheck="false"
|
||||
data-allow-html="{{ 'yes' if options.allow_html_escapes else 'no' }}"
|
||||
data-force-unicode-width="{{ 'yes' if options.force_unicode_width else 'no' }}">
|
||||
<script src="{{ static_url('html-sanitizer.js') }}"></script>
|
||||
<script src="{{ static_url('main.%sjs' % (
|
||||
'' if options.unminified else 'min.')) }}"></script>
|
||||
<script src="{{ static_url('ext.%sjs' % (
|
||||
|
||||
@@ -50,7 +50,6 @@ class Terminal
|
||||
# Global elements
|
||||
@document = @parent.ownerDocument
|
||||
@body = @document.getElementsByTagName('body')[0]
|
||||
@htmlEscapesEnabled = @body.getAttribute('data-allow-html') is 'yes'
|
||||
@forceWidth = @body.getAttribute(
|
||||
'data-force-unicode-width') is 'yes'
|
||||
|
||||
@@ -92,14 +91,16 @@ class Terminal
|
||||
addEventListener 'focus', @focus.bind(@)
|
||||
addEventListener 'blur', @blur.bind(@)
|
||||
addEventListener 'resize', => @resize()
|
||||
@body.addEventListener 'load', =>
|
||||
@nativeScrollTo()
|
||||
, true
|
||||
|
||||
# # Horrible Firefox paste workaround
|
||||
if typeof InstallTrigger isnt "undefined"
|
||||
@body.contentEditable = 'true'
|
||||
|
||||
@initmouse()
|
||||
|
||||
setTimeout(@resize.bind(@), 100)
|
||||
# setTimeout(@resize.bind(@), 100)
|
||||
|
||||
cloneAttr: (a, char=null) ->
|
||||
bg: a.bg
|
||||
@@ -407,7 +408,7 @@ class Terminal
|
||||
data = line.chars[i]
|
||||
if data.html
|
||||
out += data.html
|
||||
continue
|
||||
break
|
||||
if skipnext
|
||||
skipnext = false
|
||||
continue
|
||||
@@ -486,7 +487,7 @@ class Terminal
|
||||
out += "</span>" if i is x
|
||||
attr = data
|
||||
out += "</span>" unless @equalAttr attr, @defAttr
|
||||
out = @linkify(out) unless j is @y + @shift
|
||||
out = @linkify(out) unless j is @y + @shift or data.html
|
||||
out += '\u23CE' if line.wrap
|
||||
if @children[j]
|
||||
@children[j].innerHTML = out
|
||||
@@ -1085,16 +1086,14 @@ class Terminal
|
||||
|
||||
switch type
|
||||
when "HTML"
|
||||
unless @htmlEscapesEnabled
|
||||
console.log "HTML escapes are disabled"
|
||||
break
|
||||
|
||||
safe = html_sanitize(content, (l) -> l)
|
||||
attr = @cloneAttr @curAttr
|
||||
attr.html = (
|
||||
"<div class=\"inline-html\">#{content}</div>")
|
||||
"<div class=\"inline-html\">#{safe}</div>")
|
||||
@screen[@y + @shift].chars[@x] = attr
|
||||
@screen[@y + @shift].dirty = true
|
||||
@screen[@y + @shift].wrap = false
|
||||
@nextLine()
|
||||
|
||||
when "IMAGE"
|
||||
# Prevent injection
|
||||
@@ -1595,7 +1594,7 @@ class Terminal
|
||||
i++
|
||||
|
||||
chars: line
|
||||
dirty: true
|
||||
dirty: false
|
||||
wrap: false
|
||||
|
||||
ch: (cur) ->
|
||||
|
||||
Reference in New Issue
Block a user