mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-04-20 23:46:14 -04:00
Create and use the Security module.
Use it to replace code on the client and server side.
This commit is contained in:
parent
363e168561
commit
e0d23e3c5d
6 changed files with 74 additions and 65 deletions
|
@ -19,6 +19,7 @@ var async = require("async");
|
||||||
var Changeset = CommonCode.require("/Changeset");
|
var Changeset = CommonCode.require("/Changeset");
|
||||||
var padManager = require("../db/PadManager");
|
var padManager = require("../db/PadManager");
|
||||||
var ERR = require("async-stacktrace");
|
var ERR = require("async-stacktrace");
|
||||||
|
var Security = CommonCode.require('/security');
|
||||||
|
|
||||||
function getPadPlainText(pad, revNum)
|
function getPadPlainText(pad, revNum)
|
||||||
{
|
{
|
||||||
|
@ -270,7 +271,7 @@ function getHTMLFromAtext(pad, atext)
|
||||||
//from but they break the abiword parser and are completly useless
|
//from but they break the abiword parser and are completly useless
|
||||||
s = s.replace(String.fromCharCode(12), "");
|
s = s.replace(String.fromCharCode(12), "");
|
||||||
|
|
||||||
assem.append(_escapeHTML(s));
|
assem.append(_encodeWhitespace(Security.escapeHTML(s)));
|
||||||
} // end iteration over spans in line
|
} // end iteration over spans in line
|
||||||
|
|
||||||
var tags2close = [];
|
var tags2close = [];
|
||||||
|
@ -293,7 +294,7 @@ function getHTMLFromAtext(pad, atext)
|
||||||
var url = urlData[1];
|
var url = urlData[1];
|
||||||
var urlLength = url.length;
|
var urlLength = url.length;
|
||||||
processNextChars(startIndex - idx);
|
processNextChars(startIndex - idx);
|
||||||
assem.append('<a href="' + _escapeHTML(url) + '">');
|
assem.append('<a href="' + Security.escapeHTMLAttribute(url) + '">');
|
||||||
processNextChars(urlLength);
|
processNextChars(urlLength);
|
||||||
assem.append('</a>');
|
assem.append('</a>');
|
||||||
});
|
});
|
||||||
|
@ -494,25 +495,7 @@ exports.getPadHTMLDocument = function (padId, revNum, noDocType, callback)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function _escapeHTML(s)
|
function _encodeWhitespace(s) {
|
||||||
{
|
|
||||||
var re = /[&"<>]/g;
|
|
||||||
if (!re.MAP)
|
|
||||||
{
|
|
||||||
// persisted across function calls!
|
|
||||||
re.MAP = {
|
|
||||||
'&': '&',
|
|
||||||
'"': '"',
|
|
||||||
'<': '<',
|
|
||||||
'>': '>'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
s = s.replace(re, function (c)
|
|
||||||
{
|
|
||||||
return re.MAP[c];
|
|
||||||
});
|
|
||||||
|
|
||||||
return s.replace(/[^\x21-\x7E\s\t\n\r]/g, function(c)
|
return s.replace(/[^\x21-\x7E\s\t\n\r]/g, function(c)
|
||||||
{
|
{
|
||||||
return "&#" +c.charCodeAt(0) + ";"
|
return "&#" +c.charCodeAt(0) + ";"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"pad.js": [
|
"pad.js": [
|
||||||
"jquery.js"
|
"jquery.js"
|
||||||
|
, "security.js"
|
||||||
, "pad.js"
|
, "pad.js"
|
||||||
, "ace2_common.js"
|
, "ace2_common.js"
|
||||||
, "pad_utils.js"
|
, "pad_utils.js"
|
||||||
|
@ -25,6 +26,7 @@
|
||||||
]
|
]
|
||||||
, "timeslider.js": [
|
, "timeslider.js": [
|
||||||
"jquery.js"
|
"jquery.js"
|
||||||
|
, "security.js"
|
||||||
, "plugins.js"
|
, "plugins.js"
|
||||||
, "undo-xpopup.js"
|
, "undo-xpopup.js"
|
||||||
, "json2.js"
|
, "json2.js"
|
||||||
|
@ -53,6 +55,7 @@
|
||||||
"ace2_common.js"
|
"ace2_common.js"
|
||||||
, "AttributePoolFactory.js"
|
, "AttributePoolFactory.js"
|
||||||
, "Changeset.js"
|
, "Changeset.js"
|
||||||
|
, "security.js"
|
||||||
, "skiplist.js"
|
, "skiplist.js"
|
||||||
, "virtual_lines.js"
|
, "virtual_lines.js"
|
||||||
, "cssmanager.js"
|
, "cssmanager.js"
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var Security = require('/security');
|
||||||
|
|
||||||
function isNodeText(node)
|
function isNodeText(node)
|
||||||
{
|
{
|
||||||
|
@ -137,14 +138,7 @@ function binarySearchInfinite(expectedLength, func)
|
||||||
|
|
||||||
function htmlPrettyEscape(str)
|
function htmlPrettyEscape(str)
|
||||||
{
|
{
|
||||||
return str.replace(/[&"<>]/g, function (c) {
|
return Security.escapeHTML(str).replace(/\r?\n/g, '\\n');
|
||||||
return {
|
|
||||||
'&': '&',
|
|
||||||
'"': '"',
|
|
||||||
'<': '<',
|
|
||||||
'>': '>'
|
|
||||||
}[c] || c;
|
|
||||||
}).replace(/\r?\n/g, '\\n');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.isNodeText = isNodeText;
|
exports.isNodeText = isNodeText;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
// requires: plugins
|
// requires: plugins
|
||||||
// requires: undefined
|
// requires: undefined
|
||||||
|
|
||||||
|
var Security = require('/security');
|
||||||
var plugins = require('/plugins').plugins;
|
var plugins = require('/plugins').plugins;
|
||||||
var map = require('/ace2_common').map;
|
var map = require('/ace2_common').map;
|
||||||
|
|
||||||
|
@ -103,17 +104,17 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
|
||||||
if (listType)
|
if (listType)
|
||||||
{
|
{
|
||||||
listType = listType[1];
|
listType = listType[1];
|
||||||
start = start?'start="'+start[1]+'"':'';
|
start = start?'start="'+Security.escapeHTMLAttribute(start[1])+'"':'';
|
||||||
if (listType)
|
if (listType)
|
||||||
{
|
{
|
||||||
if(listType.indexOf("number") < 0)
|
if(listType.indexOf("number") < 0)
|
||||||
{
|
{
|
||||||
preHtml = '<ul class="list-' + listType + '"><li>';
|
preHtml = '<ul class="list-' + Security.escapeHTMLAttribute(listType) + '"><li>';
|
||||||
postHtml = '</li></ul>';
|
postHtml = '</li></ul>';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
preHtml = '<ol '+start+' class="list-' + listType + '"><li>';
|
preHtml = '<ol '+start+' class="list-' + Security.escapeHTMLAttribute(listType) + '"><li>';
|
||||||
postHtml = '</li></ol>';
|
postHtml = '</li></ol>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,7 +169,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
|
||||||
{
|
{
|
||||||
href = "http://"+href;
|
href = "http://"+href;
|
||||||
}
|
}
|
||||||
extraOpenTags = extraOpenTags + '<a href="' + domline.escapeHTML(href) + '">';
|
extraOpenTags = extraOpenTags + '<a href="' + Security.escapeHTMLAttribute(href) + '">';
|
||||||
extraCloseTags = '</a>' + extraCloseTags;
|
extraCloseTags = '</a>' + extraCloseTags;
|
||||||
}
|
}
|
||||||
if (simpleTags)
|
if (simpleTags)
|
||||||
|
@ -178,7 +179,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
|
||||||
simpleTags.reverse();
|
simpleTags.reverse();
|
||||||
extraCloseTags = '</' + simpleTags.join('></') + '>' + extraCloseTags;
|
extraCloseTags = '</' + simpleTags.join('></') + '>' + extraCloseTags;
|
||||||
}
|
}
|
||||||
html.push('<span class="', cls || '', '">', extraOpenTags, perTextNodeProcess(domline.escapeHTML(txt)), extraCloseTags, '</span>');
|
html.push('<span class="', Security.escapeHTMLAttribute(cls || ''), '">', extraOpenTags, perTextNodeProcess(Security.escapeHTML(txt)), extraCloseTags, '</span>');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
result.clearSpans = function()
|
result.clearSpans = function()
|
||||||
|
@ -224,27 +225,6 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
domline.escapeHTML = function(s)
|
|
||||||
{
|
|
||||||
var re = /[&<>'"]/g;
|
|
||||||
/']/; // stupid indentation thing
|
|
||||||
if (!re.MAP)
|
|
||||||
{
|
|
||||||
// persisted across function calls!
|
|
||||||
re.MAP = {
|
|
||||||
'&': '&',
|
|
||||||
'<': '<',
|
|
||||||
'>': '>',
|
|
||||||
'"': '"',
|
|
||||||
"'": '''
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return s.replace(re, function(c)
|
|
||||||
{
|
|
||||||
return re.MAP[c];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
domline.processSpaces = function(s, doesWrap)
|
domline.processSpaces = function(s, doesWrap)
|
||||||
{
|
{
|
||||||
if (s.indexOf("<") < 0 && !doesWrap)
|
if (s.indexOf("<") < 0 && !doesWrap)
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var Security = require('/security');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a random String with the given length. Is needed to generate the Author, Group, readonly, session Ids
|
* Generates a random String with the given length. Is needed to generate the Author, Group, readonly, session Ids
|
||||||
*/
|
*/
|
||||||
|
@ -69,14 +71,7 @@ function readCookie(name)
|
||||||
var padutils = {
|
var padutils = {
|
||||||
escapeHtml: function(x)
|
escapeHtml: function(x)
|
||||||
{
|
{
|
||||||
return String(x).replace(/[&"<>]/g, function (c) {
|
return Security.escapeHTML(String(x));
|
||||||
return {
|
|
||||||
'&': '&',
|
|
||||||
'"': '"',
|
|
||||||
'<': '<',
|
|
||||||
'>': '>'
|
|
||||||
}[c] || c;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
uniqueId: function()
|
uniqueId: function()
|
||||||
{
|
{
|
||||||
|
@ -205,7 +200,7 @@ var padutils = {
|
||||||
{
|
{
|
||||||
if (i > idx)
|
if (i > idx)
|
||||||
{
|
{
|
||||||
pieces.push(padutils.escapeHtml(text.substring(idx, i)));
|
pieces.push(Security.escapeHTML(text.substring(idx, i)));
|
||||||
idx = i;
|
idx = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,7 +211,7 @@ var padutils = {
|
||||||
var startIndex = urls[j][0];
|
var startIndex = urls[j][0];
|
||||||
var href = urls[j][1];
|
var href = urls[j][1];
|
||||||
advanceTo(startIndex);
|
advanceTo(startIndex);
|
||||||
pieces.push('<a ', (target ? 'target="' + target + '" ' : ''), 'href="', padutils.escapeHtml(href), '">');
|
pieces.push('<a ', (target ? 'target="' + Security.escapeHTMLAttribute(target) + '" ' : ''), 'href="', Security.escapeHTMLAttribute(href), '">');
|
||||||
advanceTo(startIndex + href.length);
|
advanceTo(startIndex + href.length);
|
||||||
pieces.push('</a>');
|
pieces.push('</a>');
|
||||||
}
|
}
|
||||||
|
|
54
static/js/security.js
Normal file
54
static/js/security.js
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2009 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS-IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var HTML_ENTITY_MAP = {
|
||||||
|
'&': '&'
|
||||||
|
, '<': '<'
|
||||||
|
, '>': '>'
|
||||||
|
, '"': '"'
|
||||||
|
, "'": '''
|
||||||
|
, '/': '/'
|
||||||
|
};
|
||||||
|
|
||||||
|
// OSWASP Guidlines: &, <, >, ", ' plus forward slash.
|
||||||
|
var HTML_CHARACTERS_EXPRESSION = /[&"'<>\/]/g;
|
||||||
|
function escapeHTML(text) {
|
||||||
|
return text && text.replace(HTML_CHARACTERS_EXPRESSION, function (c) {
|
||||||
|
return HTML_ENTITY_MAP[c] || c;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// OSWASP Guidlines: escape all non alphanumeric characters in ASCII space.
|
||||||
|
var HTML_ATTRIBUTE_CHARACTERS_EXPRESSION =
|
||||||
|
/[\x00-\x2F\x3A-\x40\5B-\x60\x7B-\xFF]/g;
|
||||||
|
function escapeHTMLAttribute(text) {
|
||||||
|
return text && text.replace(HTML_ATTRIBUTE_CHARACTERS_EXPRESSION, function (c) {
|
||||||
|
return "&#x" + ('00' + c.charCodeAt(0).toString(16)).slice(-2) + ";";
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// OSWASP Guidlines: escape all non alphanumeric characters in ASCII space.
|
||||||
|
var JAVASCRIPT_CHARACTERS_EXPRESSION =
|
||||||
|
/[\x00-\x2F\x3A-\x40\5B-\x60\x7B-\xFF]/g;
|
||||||
|
function escapeJavaScriptData(text) {
|
||||||
|
return text && text.replace(JAVASCRIPT_CHARACTERS_EXPRESSION, function (c) {
|
||||||
|
return "\\x" + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.escapeHTML = escapeHTML;
|
||||||
|
exports.escapeHTMLAttribute = escapeHTMLAttribute;
|
||||||
|
exports.escapeJavaScriptData = escapeJavaScriptData;
|
Loading…
Add table
Add a link
Reference in a new issue