mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-04 07:40:42 +00:00
Bug 994134 - Warn first time users on pasting code into the console. r=bgrins
--HG-- rename : browser/devtools/webconsole/test/browser_webconsole_bug_642615_autocomplete.js => browser/devtools/webconsole/test/browser_webconsole_autocomplete_and_selfxss.js
This commit is contained in:
parent
41a099d157
commit
de4be8677c
@ -1396,6 +1396,10 @@ pref("devtools.browserconsole.filter.secwarn", true);
|
||||
// Text size in the Web Console. Use 0 for the system default size.
|
||||
pref("devtools.webconsole.fontSize", 0);
|
||||
|
||||
// Number of usages of the web console or scratchpad.
|
||||
// If this is less than 10, then pasting code into the web console or scratchpad is disabled
|
||||
pref("devtools.selfxss.count", 0);
|
||||
|
||||
// Persistent logging: |true| if you want the Web Console to keep all of the
|
||||
// logged messages after reloading the page, |false| if you want the output to
|
||||
// be cleared each time page navigation happens.
|
||||
|
@ -69,9 +69,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "EnvironmentClient",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ObjectClient",
|
||||
"resource://gre/modules/devtools/dbg-client.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "WebConsoleUtils",
|
||||
"resource://gre/modules/devtools/WebConsoleUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DebuggerServer",
|
||||
"resource://gre/modules/devtools/dbg-server.jsm");
|
||||
|
||||
@ -92,6 +89,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "Reflect",
|
||||
let telemetry = new Telemetry();
|
||||
telemetry.toolOpened("scratchpad");
|
||||
|
||||
let WebConsoleUtils = require("devtools/toolkit/webconsole/utils").Utils;
|
||||
|
||||
/**
|
||||
* The scratchpad object handles the Scratchpad window functionality.
|
||||
*/
|
||||
@ -494,6 +493,7 @@ var Scratchpad = {
|
||||
*/
|
||||
execute: function SP_execute()
|
||||
{
|
||||
WebConsoleUtils.usageCount++;
|
||||
let selection = this.editor.getSelection() || this.getText();
|
||||
return this.evaluate(selection);
|
||||
},
|
||||
@ -1613,11 +1613,16 @@ var Scratchpad = {
|
||||
};
|
||||
|
||||
this.editor = new Editor(config);
|
||||
this.editor.appendTo(document.querySelector("#scratchpad-editor")).then(() => {
|
||||
let editorElement = document.querySelector("#scratchpad-editor");
|
||||
this.editor.appendTo(editorElement).then(() => {
|
||||
var lines = initialText.split("\n");
|
||||
|
||||
this.editor.setupAutoCompletion();
|
||||
this.editor.on("change", this._onChanged);
|
||||
this._onPaste = WebConsoleUtils.pasteHandlerGen(this.editor.container.contentDocument.body,
|
||||
document.querySelector('#scratchpad-notificationbox'));
|
||||
editorElement.addEventListener("paste", this._onPaste);
|
||||
editorElement.addEventListener("drop", this._onPaste);
|
||||
this.editor.on("save", () => this.saveFile());
|
||||
this.editor.focus();
|
||||
this.editor.setCursor({ line: lines.length, ch: lines.pop().length });
|
||||
@ -1689,7 +1694,12 @@ var Scratchpad = {
|
||||
|
||||
PreferenceObserver.uninit();
|
||||
CloseObserver.uninit();
|
||||
|
||||
if (this._onPaste) {
|
||||
let editorElement = document.querySelector("#scratchpad-editor");
|
||||
editorElement.removeEventListener("paste", this._onPaste);
|
||||
editorElement.removeEventListener("drop", this._onPaste);
|
||||
this._onPaste = null;
|
||||
}
|
||||
this.editor.off("change", this._onChanged);
|
||||
this.editor.destroy();
|
||||
this.editor = null;
|
||||
|
@ -5,10 +5,11 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
let WebConsoleUtils = require("devtools/toolkit/webconsole/utils").Utils;
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
@ -56,6 +57,21 @@ function runTests()
|
||||
let anchor = doc.documentElement;
|
||||
let isContextMenu = false;
|
||||
|
||||
let oldVal = sp.editor.getText();
|
||||
|
||||
let testSelfXss = function (oldVal) {
|
||||
// Self xss prevention tests (bug 994134)
|
||||
info("Self xss paste tests")
|
||||
is(WebConsoleUtils.usageCount, 0, "Test for usage count getter")
|
||||
let notificationbox = doc.getElementById("scratchpad-notificationbox");
|
||||
let notification = notificationbox.getNotificationWithValue('selfxss-notification');
|
||||
ok(notification, "Self-xss notification shown");
|
||||
is(oldVal, sp.editor.getText(), "Paste blocked by self-xss prevention");
|
||||
Services.prefs.setIntPref("devtools.selfxss.count", 10);
|
||||
notificationbox.removeAllNotifications(true);
|
||||
openMenu(10, 10, firstShow);
|
||||
};
|
||||
|
||||
let openMenu = function(aX, aY, aCallback) {
|
||||
if (!editMenu || OS != "Darwin") {
|
||||
menuPopup.addEventListener("popupshown", function onPopupShown() {
|
||||
@ -137,8 +153,8 @@ function runTests()
|
||||
};
|
||||
|
||||
let hideAfterCut = function() {
|
||||
sp.editor.on("change", onPaste);
|
||||
waitForFocus(function () {
|
||||
sp.editor.on("change", onPaste);
|
||||
EventUtils.synthesizeKey("v", {accelKey: true}, gScratchpadWindow);
|
||||
}, gScratchpadWindow);
|
||||
};
|
||||
@ -179,6 +195,9 @@ function runTests()
|
||||
sp.setText("bug 699130: hello world! (context menu)");
|
||||
openMenu(10, 10, firstShow);
|
||||
};
|
||||
|
||||
openMenu(10, 10, firstShow);
|
||||
waitForFocus(function(){
|
||||
WebConsoleUtils.usageCount = 0;
|
||||
EventUtils.synthesizeKey("v", {accelKey: true}, gScratchpadWindow);
|
||||
testSelfXss(oldVal);
|
||||
}, gScratchpadWindow)
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ run-if = os == "win"
|
||||
[browser_webconsole_bug_632347_iterators_generators.js]
|
||||
[browser_webconsole_bug_632817.js]
|
||||
[browser_webconsole_bug_642108_pruneTest.js]
|
||||
[browser_webconsole_bug_642615_autocomplete.js]
|
||||
[browser_webconsole_autocomplete_and_selfxss.js]
|
||||
[browser_webconsole_bug_644419_log_limits.js]
|
||||
[browser_webconsole_bug_646025_console_file_location.js]
|
||||
[browser_webconsole_bug_651501_document_body_autocomplete.js]
|
||||
|
@ -7,6 +7,7 @@ const TEST_URI = "data:text/html;charset=utf-8,<p>test for bug 642615";
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "clipboardHelper",
|
||||
"@mozilla.org/widget/clipboardhelper;1",
|
||||
"nsIClipboardHelper");
|
||||
let WebConsoleUtils = require("devtools/toolkit/webconsole/utils").Utils;
|
||||
|
||||
function consoleOpened(HUD) {
|
||||
let jsterm = HUD.jsterm;
|
||||
@ -35,13 +36,48 @@ function consoleOpened(HUD) {
|
||||
}
|
||||
|
||||
function onClipboardCopy() {
|
||||
info("wait for completion update after clipboard paste");
|
||||
jsterm.once("autocomplete-updated", onClipboardPaste);
|
||||
testSelfXss();
|
||||
|
||||
jsterm.setInputValue("docu");
|
||||
info("wait for completion update after clipboard paste");
|
||||
updateEditUIVisibility();
|
||||
jsterm.once("autocomplete-updated", onClipboardPaste);
|
||||
goDoCommand("cmd_paste");
|
||||
}
|
||||
|
||||
|
||||
// Self xss prevention tests (bug 994134)
|
||||
function testSelfXss(){
|
||||
info("Self-xss paste tests")
|
||||
WebConsoleUtils.usageCount = 0;
|
||||
is(WebConsoleUtils.usageCount, 0, "Test for usage count getter")
|
||||
// Input some commands to check if usage counting is working
|
||||
for(let i = 0; i <= 5; i++){
|
||||
jsterm.setInputValue(i);
|
||||
jsterm.execute();
|
||||
}
|
||||
is(WebConsoleUtils.usageCount, 6, "Usage count incremented")
|
||||
WebConsoleUtils.usageCount = 0;
|
||||
updateEditUIVisibility();
|
||||
|
||||
let oldVal = jsterm.inputNode.value;
|
||||
goDoCommand("cmd_paste");
|
||||
let notificationbox = jsterm.hud.document.getElementById("webconsole-notificationbox");
|
||||
let notification = notificationbox.getNotificationWithValue('selfxss-notification');
|
||||
ok(notification, "Self-xss notification shown");
|
||||
is(oldVal, jsterm.inputNode.value, "Paste blocked by self-xss prevention");
|
||||
|
||||
// Allow pasting
|
||||
jsterm.inputNode.value = "allow pasting";
|
||||
var evt = document.createEvent("KeyboardEvent");
|
||||
evt.initKeyEvent ("keyup", true, true, window,
|
||||
0, 0, 0, 0,
|
||||
0, " ".charCodeAt(0));
|
||||
jsterm.inputNode.dispatchEvent(evt);
|
||||
jsterm.inputNode.value = "";
|
||||
goDoCommand("cmd_paste");
|
||||
isnot("", jsterm.inputNode.value, "Paste works");
|
||||
}
|
||||
function onClipboardPaste() {
|
||||
ok(!jsterm.completeNode.value, "no completion value after paste");
|
||||
|
@ -3133,7 +3133,10 @@ JSTerm.prototype = {
|
||||
inputContainer.style.display = "none";
|
||||
}
|
||||
else {
|
||||
this._onPaste = WebConsoleUtils.pasteHandlerGen(this.inputNode, doc.getElementById("webconsole-notificationbox"));
|
||||
this.inputNode.addEventListener("keypress", this._keyPress, false);
|
||||
this.inputNode.addEventListener("paste", this._onPaste);
|
||||
this.inputNode.addEventListener("drop", this._onPaste);
|
||||
this.inputNode.addEventListener("input", this._inputEventHandler, false);
|
||||
this.inputNode.addEventListener("keyup", this._inputEventHandler, false);
|
||||
this.inputNode.addEventListener("focus", this._focusEventHandler, false);
|
||||
@ -3272,6 +3275,7 @@ JSTerm.prototype = {
|
||||
// value that was not evaluated yet.
|
||||
this.history[this.historyIndex++] = aExecuteString;
|
||||
this.historyPlaceHolder = this.history.length;
|
||||
WebConsoleUtils.usageCount++;
|
||||
this.setInputValue("");
|
||||
this.clearCompletion();
|
||||
},
|
||||
@ -4524,6 +4528,12 @@ JSTerm.prototype = {
|
||||
popup.parentNode.removeChild(popup);
|
||||
}
|
||||
|
||||
if (this._onPaste) {
|
||||
this.inputNode.removeEventListener("paste", this._onPaste, false);
|
||||
this.inputNode.removeEventListener("drop", this._onPaste, false);
|
||||
this._onPaste = null;
|
||||
}
|
||||
|
||||
this.inputNode.removeEventListener("keypress", this._keyPress, false);
|
||||
this.inputNode.removeEventListener("input", this._inputEventHandler, false);
|
||||
this.inputNode.removeEventListener("keyup", this._inputEventHandler, false);
|
||||
|
@ -173,15 +173,16 @@ function goUpdateConsoleCommands() {
|
||||
<hbox id="output-wrapper" flex="1" context="output-contextmenu" tooltip="aHTMLTooltip">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" id="output-container" tabindex="1" />
|
||||
</hbox>
|
||||
|
||||
<hbox class="jsterm-input-container" style="direction:ltr">
|
||||
<stack class="jsterm-stack-node" flex="1">
|
||||
<textbox class="jsterm-complete-node devtools-monospace"
|
||||
multiline="true" rows="1" tabindex="-1"/>
|
||||
<textbox class="jsterm-input-node devtools-monospace"
|
||||
multiline="true" rows="1" tabindex="0"/>
|
||||
</stack>
|
||||
</hbox>
|
||||
<notificationbox id="webconsole-notificationbox">
|
||||
<hbox class="jsterm-input-container" style="direction:ltr">
|
||||
<stack class="jsterm-stack-node" flex="1">
|
||||
<textbox class="jsterm-complete-node devtools-monospace"
|
||||
multiline="true" rows="1" tabindex="-1"/>
|
||||
<textbox class="jsterm-input-node devtools-monospace"
|
||||
multiline="true" rows="1" tabindex="0"/>
|
||||
</stack>
|
||||
</hbox>
|
||||
</notificationbox>
|
||||
</vbox>
|
||||
|
||||
<splitter class="devtools-side-splitter"/>
|
||||
|
@ -223,6 +223,16 @@ openNodeInInspector=Click to select the node in the inspector
|
||||
# cd() is invoked with an invalid argument.
|
||||
cdFunctionInvalidArgument=Cannot cd() to the given window. Invalid argument.
|
||||
|
||||
# LOCALIZATION NOTE (selfxss.msg): the text that is displayed when
|
||||
# a new user of the developer tools pastes code into the console
|
||||
# %1 is the text of selfxss.okstring
|
||||
selfxss.msg=Scam Warning: Take care when pasting things you don't understand. This could allow attackers to steal your identity or take control of your computer. Please type '%S' below (no need to press enter) to allow pasting.
|
||||
|
||||
# LOCALIZATION NOTE (selfxss.msg): the string to be typed
|
||||
# in by a new user of the developer tools when they receive the sefxss.msg prompt.
|
||||
# Please avoid using non-keyboard characters here
|
||||
selfxss.okstring=allow pasting
|
||||
|
||||
# LOCALIZATION NOTE (messageToggleDetails): the text that is displayed when
|
||||
# you hover the arrow for expanding/collapsing the message details. For
|
||||
# console.error() and other messages we show the stacktrace.
|
||||
|
@ -31,6 +31,8 @@ const REGEX_MATCH_FUNCTION_NAME = /^\(?function\s+([^(\s]+)\s*\(/;
|
||||
// Match the function arguments from the result of toString() or toSource().
|
||||
const REGEX_MATCH_FUNCTION_ARGS = /^\(?function\s*[^\s(]*\s*\((.+?)\)/;
|
||||
|
||||
// Number of terminal entries for the self-xss prevention to go away
|
||||
const CONSOLE_ENTRY_THRESHOLD = 10
|
||||
let WebConsoleUtils = {
|
||||
/**
|
||||
* Convenience function to unwrap a wrapped object.
|
||||
@ -530,7 +532,77 @@ let WebConsoleUtils = {
|
||||
{
|
||||
return aGrip && typeof(aGrip) == "object" && aGrip.actor;
|
||||
},
|
||||
/**
|
||||
* Value of devtools.selfxss.count preference
|
||||
*
|
||||
* @type number
|
||||
* @private
|
||||
*/
|
||||
_usageCount: 0,
|
||||
get usageCount() {
|
||||
if (WebConsoleUtils._usageCount < CONSOLE_ENTRY_THRESHOLD) {
|
||||
WebConsoleUtils._usageCount = Services.prefs.getIntPref("devtools.selfxss.count")
|
||||
}
|
||||
return WebConsoleUtils._usageCount;
|
||||
},
|
||||
set usageCount(newUC) {
|
||||
if (newUC <= CONSOLE_ENTRY_THRESHOLD) {
|
||||
WebConsoleUtils._usageCount = newUC;
|
||||
Services.prefs.setIntPref("devtools.selfxss.count", newUC);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* The inputNode "paste" event handler generator. Helps prevent self-xss attacks
|
||||
*
|
||||
* @param nsIDOMElement inputField
|
||||
* @param nsIDOMElement notificationBox
|
||||
* @returns A function to be added as a handler to 'paste' and 'drop' events on the input field
|
||||
*/
|
||||
pasteHandlerGen: function WCU_pasteHandlerGen(inputField, notificationBox){
|
||||
let handler = function WCU_pasteHandler(aEvent) {
|
||||
if (WebConsoleUtils.usageCount >= CONSOLE_ENTRY_THRESHOLD) {
|
||||
inputField.removeEventListener("paste", handler);
|
||||
inputField.removeEventListener("drop", handler);
|
||||
return true;
|
||||
}
|
||||
if (notificationBox.getNotificationWithValue("selfxss-notification")) {
|
||||
aEvent.preventDefault();
|
||||
aEvent.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
let l10n = new WebConsoleUtils.l10n("chrome://browser/locale/devtools/webconsole.properties");
|
||||
let okstring = l10n.getStr("selfxss.okstring");
|
||||
let msg = l10n.getFormatStr("selfxss.msg", [okstring]);
|
||||
|
||||
let notification = notificationBox.appendNotification(msg,
|
||||
"selfxss-notification", null, notificationBox.PRIORITY_WARNING_HIGH, null,
|
||||
function(eventType) {
|
||||
// Cleanup function if notification is dismissed
|
||||
if (eventType == "removed") {
|
||||
inputField.removeEventListener("keyup", pasteKeyUpHandler);
|
||||
}
|
||||
});
|
||||
|
||||
function pasteKeyUpHandler(aEvent2) {
|
||||
let value = inputField.value || inputField.textContent;
|
||||
if (value.contains(okstring)) {
|
||||
notificationBox.removeNotification(notification);
|
||||
inputField.removeEventListener("keyup", pasteKeyUpHandler);
|
||||
WebConsoleUtils.usageCount = CONSOLE_ENTRY_THRESHOLD;
|
||||
}
|
||||
}
|
||||
inputField.addEventListener("keyup", pasteKeyUpHandler);
|
||||
|
||||
aEvent.preventDefault();
|
||||
aEvent.stopPropagation();
|
||||
return false;
|
||||
};
|
||||
return handler;
|
||||
},
|
||||
|
||||
|
||||
};
|
||||
|
||||
exports.Utils = WebConsoleUtils;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
x
Reference in New Issue
Block a user