Skip to content
This repository has been archived by the owner on Sep 5, 2020. It is now read-only.

ETH-01-cure fixes #1414

Merged
merged 14 commits into from
Nov 15, 2016
Merged

ETH-01-cure fixes #1414

merged 14 commits into from
Nov 15, 2016

Conversation

frozeman
Copy link
Contributor

@frozeman frozeman commented Nov 14, 2016

Fixes currently:

  • ETH-01-002
  • ETH-01-003
  • ETH-01-005

Questions here:
The question is do we want to avoid data:// URIs and what threat do they bring.

Note that these URIs are only prevent in the browserbar and as a possible full page load. Not as assets in a webpage

@mention-bot
Copy link

@frozeman, thanks for your PR! By analyzing the history of the files in this pull request, we identified @alexvandesande and @evertonfraga to be potential reviewers.

url = url.replace(/^(javascript:)?(data:)?\/\//i, 'http:');
}

return url;
Copy link

@holiman holiman Nov 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blacklist is not sufficient. javaScript:// is also valid, and maybe special characters such as %0A .

Also, why only handle strings?
If you expect anything other than strings, such as location-objects, you should filter them. If you expect string input, then cast the url to string and do the sanitation unconditionally. Otherwise, something like /javascript/ (regexp) or ["javascript://foo"] (array) or random object can be used to bypass this (depending on where the input comes from)

Copy link

@holiman holiman Nov 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I missed the /i . But javascript can still be broken up with tab or %0A. I'd rather see:

  1. Robust URL parsing, either using DOM anchor element to parse URL (example: https://gist.github.com/jlong/2428561) or a proper URL parsing library (example: https://nodejs.org/api/url.html) .
  2. Whitelist, only allowing the protocols we want to allow, instead of blacklisting a few.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will look into a proper JS library. Currently the URL is never a location object, but i can add checks for them too.

Whitelisting would make sense if we fully know what people will use and currently we don't want to restrict unknown URIs. E.g. ftp, etc.
As it looks only JavaScript is semi-dangerous as it can spawn ui actions, but this js has also not added privileges than the webpage itself.
So removing JavaScript seems to be the most dangerous one, can you think of any other?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@holiman i changed it now to use the parser object form your gist, but concerning the whitelisting im not yet convinced if we are not blocking uses cases. This current sanatizer should prevent spoofing. We can discuss in the future if we want to add more

@evertonfraga evertonfraga mentioned this pull request Nov 14, 2016
@evertonfraga
Copy link
Member

evertonfraga commented Nov 14, 2016

Testing

  • ETH-01-003
  • ETH-01-002
  • ETH-01-005

parser = url;
}

parser.protocol = parser.protocol.replace(/^(javascript:)?(data:)?(:)?/i, 'http:');
Copy link

@holiman holiman Nov 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See playground example. The code as it is written function will replace "https://" urls with "http://"

This is (I think) because the matches all, due to there only being optional capture groups. See here for a more robust example.

And I still think that any input not explicitly supported, should be coerced into a string. Otherwise it does not get filtered.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's an example which is even more robust, although I'd still prefer whitelisting protos instead of blacklisting

Copy link
Contributor Author

@frozeman frozeman Nov 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested you version and they didn't cover everything.
I found the best way which is:

sanatizeUrl = function(url){
// make sure location objects are string too
    url = String(url);

// remove whitespaces and tabs
    url = url.replace(/[\t\n\r\s]+/g, '');
// replace javascript:// data:// and  //
  url = url.replace(/^((?:javascript)?(?:data)?[:\/\/]{1,3})/i, 'http://');

    return url;
 };

Test yourself

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What specifically did not work with the DOM-anchor method ?
I like that you now force it to be a string, but dislike that it's gone back to regexp. URL parsing is by no means trivial, so I'd still advocate a proper URL parsing library if the DOM is insufficient.

url = String(url);

url = url.replace(/[\t\n\r\s]+/g, '');
url = url.replace(/^((?:javascript)?(?:data)?[:\/\/]{1,3})/i, 'http://');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we do the opposite? Have only some allowed prefixes and remove all the rest?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was a discussion above already. My point is that there are a lot of URI types and we don't want to restrict use cases. "Javascript:" is the most dangerous one. But even this cannot do any harm, besides annoy people or mislead them with alert windows.

@method sanatizeUrl
@param {String} url
**/
Helpers.sanatizeUrl = function(url){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's "san_i_tize"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks.

var titleFull = webview.getTitle(),
title;

if(titleFull && titleFull.length > 40) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you cropping it on javascript? This could be accomplished with css, using overflow:hidden; text-overflow: ellipsis; white-space:nowrap;. Word width is not the same as character count.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this text is used in a lot of places and it fixes: https://github.com/ethereum/security-issues/issues/14

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The point is we don't want to add the tex overflow on any element where we use that.
Titles more than 40 characters are uncommon and for that i added the property "nameFull"

@@ -5,7 +5,7 @@
require('./include/common')('mist');
const { ipcRenderer: ipc, remote, webFrame } = require('electron');
const { Menu, MenuItem } = remote;
const syncDb = require('../syncDb.js');
const dbSync = require('../dbSync.js');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the difference between syncDB and dbSync?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its just a name refactor. The reason is that now the files db.js and dbSync.js are next to each other, which helps with mental grouping.
Also we calle the nodeSync: nodeSync ;) so consistency.

This has actually northie todo with the vu.

@@ -337,14 +337,14 @@ class IpcProviderBackend {
})
.catch((err) => {

err = this._makeErrorResponsePayload(payload || {}, {
var returnErr = this._makeErrorResponsePayload(payload || {}, {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use let instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But thats actually part of another PR: #1421 i will change it there

url = String(url);

url = url.replace(/[\t\n\r\s]+/g, '');
url = url.replace(/^((?:javascript)?(?:data)?[:\/\/]{1,3})/i, 'http://');
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I've said, I dislike using naive regexps for parsing URLs. I don't have a bypass, but here's a simple false positive:

sanitizeUrl("javascript/jquery.js"); -> http://jquery.js

So if it's ever used to filter/sanitize relative URLs, it will fail if for data and javascript folders.

@evertonfraga evertonfraga added this to the 0.8.8 milestone Nov 16, 2016
@lock
Copy link

lock bot commented Mar 31, 2018

This thread has been automatically locked because it has not had recent activity. Please open a new issue for related bugs and link to relevant comments in this thread.

@lock lock bot locked and limited conversation to collaborators Mar 31, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants