Allow html by default by using the google caja sanitizer

This commit is contained in:
Florian Mounier
2015-05-12 10:56:45 +02:00
parent 78e3050387
commit 81d9fea01a
8 changed files with 36 additions and 30 deletions

View File

@@ -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."

View File

@@ -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')

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -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
};
};

File diff suppressed because one or more lines are too long

View File

@@ -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' % (

View File

@@ -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) ->