From 2787294ecfe5d005d836f08f724ced938ff14965 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Mon, 16 Mar 2015 16:20:21 +0100 Subject: JSON-encode error messages. This ensures that control characters are escaped and defeats injection attacks. --- xul-ext/README | 74 +++++++++++++++++++------------------- xul-ext/chrome/content/icevault.js | 4 +-- 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/xul-ext/README b/xul-ext/README index 1d08374..b29e2fd 100644 --- a/xul-ext/README +++ b/xul-ext/README @@ -1,34 +1,33 @@ Upon startup, Firefox creates and listens on a new UNIX socket (shared -accross all tabs and windows) on which commands can be thrown in to fill +between all tabs and windows) on which commands can be thrown in to fill HTML forms. The greeting message indicates that the server is ready to -accept commands. Each command and response are single UTF8-encoded -lines ending with a newline character `\n'. Each reponse consists of a -code (OK, ERROR, or BYE), together with an optional message. Each -command line yields to a single a response line, and commands may not be -sent in parallel: clients must wait for the response of a first command -before sending a second one. - -A OK response code indicates a successful greeting or client command, +accept commands. Each command and response are single UTF8 string lines +ending with a newline character `\n'. (JSON-encoding ensures that +control characters are escaped properly; decoding to a string rather +than an object is allowed here, although it extends RFC4627.) Each +response consists of a code (OK, ERROR, or BYE), together with a +JSON-encoded optional message. Each command line yields to a single a +response line, and commands may not be sent in parallel: clients must +wait for the response of a first command before sending a second one. + +An OK response code indicates a successful greeting or client command, and may be accompanied with a JSON-encoded message data. An ERROR response code indicates a server or client protocol error, the reason of -which may be given as an accompanying UTF8 string. A BYE response code -indicates an imminent end to client connection. +which may be given as an accompanying JSON-encoded UTF8 string. A BYE +response code indicates an imminent end to client connection. - OK [' ' JSON-encoded-data] - ERROR ' ' UTF8String - BYE + S: OK [' ' JSON-encoded-data] + S: ERROR ' ' JSON-encoded-string + S: BYE The greeting message consists of the the URI (scheme://hostname:port) of -the active tab of the active window. (":port" is ommited for default +the active tab of the active window. (":port" is omitted for default ports, e.g., 443 for https.) Said URI is then cached for the whole -session, utils the client disconnects or an REFRESH command is issued. +session, until the client disconnects or an REFRESH command is issued. Hence subsequent GETFORMS and FILL commands are always relative to the -greeting or the most recent REFRESH response URI, and not the possibly -new active tab. The URI is JSON-encoded (and decodes as a string not an -object, which is an extension to RFC4627) hence non-printable and -control characters are excaped properly (but they are not valid in a -hostname anyway). +greeting or the most recent REFRESH response URI, rather than the +possibly new active tab. The URI is a JSON-encoded string. S: OK ' ' JSON-encoded-URI @@ -41,10 +40,10 @@ the server replies with the URI of the currently (active) tab of the S: OK ' ' JSON-encoded-URI -The GETFORMS command yields a response message data consisting of the list of -all visible forms, with their method, action URI, and for each field of type -password, text or email, their name, type, value and maxLength (unless -1) -values: +The GETFORMS command yields a response message data consisting of the +list of all visible forms, with their method, action URI, and for each +field of type password, text or email, their name, type, value and +maxLength (unless -1) values: [ { @@ -67,41 +66,44 @@ values: ] The form list is kept in cache until the client closes the connection or -another GETFORMS command is issued. This ensure that subsequent FILL commands -are relatve to these forms even if the document has been modified. +another GETFORMS command is issued. This ensure that subsequent FILL +commands are relative to these forms even if the document has been +modified. C: GETFORMS S: OK JSON-encoded-array -The FILL command must be preceeded by a GETFORM command, and takes an index and -a JSON-encoded array of string as arguments. The index is that of the form one -wants to fill, and the array must be at most as long as there are of fields in -that form (as found in the most recent GETFORMS response). The value of -each such field is then updated with that found in the array (unless -null). +The FILL command must be preceded by a GETFORM command, and takes an +index and a JSON-encoded array of string as arguments. The index is +that of the form one wants to fill, and the array must be at most as +long as there are of fields in that form (as found in the most recent +GETFORMS response). The value of each such field is then updated with +that found in the array (unless null). C: FILL index JSON-encoded-array S: OK -The QUIT command yields a BYE response. +The QUIT command yields a BYE response, and terminates the connection. - R: QUIT + C: QUIT S: BYE Example: + # client initiates the connection S: OK "https://mail.fripost.org" C: GETFORMS S: OK [{"method":"POST","action":"https://mail.fripost.org/","fields":[{"name":"_user","type":"text","value":""},{"name":"_pass","type":"password","value":""}]}] C: FILL 0 ["guilhem","topsecret"] S: OK C: GETFORM - S: ERROR Invalid command: GETFORM + S: ERROR "Invalid command: GETFORM" C: GETFORMS S: OK [{"method":"POST","action":"https://mail.fripost.org/","fields":[{"name":"_user","type":"text","value":"guilhem"},{"name":"_pass","type":"password","value":"topsecret"}]}] C: QUIT S: BYE + # client is disconnected diff --git a/xul-ext/chrome/content/icevault.js b/xul-ext/chrome/content/icevault.js index 2006e3a..fe2cb50 100644 --- a/xul-ext/chrome/content/icevault.js +++ b/xul-ext/chrome/content/icevault.js @@ -131,7 +131,7 @@ var icevault = (function() { send(state.outStream, 'OK'); } catch (e if typeof e == "string" || e instanceof SyntaxError) { - send(state.outStream, 'ERROR ' + (typeof e == "string" ? e : e.message)); + send(state.outStream, 'ERROR ' + JSON.stringify(typeof e == "string" ? e : e.message)); } break; @@ -142,7 +142,7 @@ var icevault = (function() { break; default: - send(state.outStream, 'ERROR Invalid command: ' + command); + send(state.outStream, 'ERROR ' + JSON.stringify('Invalid command: ' + command)); } }; -- cgit v1.2.3