From 0b3d1477f245eda143c5b55a57d106001e73d6b9 Mon Sep 17 00:00:00 2001 From: gorhill Date: Sat, 22 Apr 2017 12:57:56 -0400 Subject: [PATCH] add basic mitigation to potential abuse of IDN --- src/css/popup.css | 62 ++++++++++++++++++++++++++--------------------- src/js/popup.js | 24 +++++++++++++++--- src/popup.html | 2 +- 3 files changed, 55 insertions(+), 33 deletions(-) diff --git a/src/css/popup.css b/src/css/popup.css index 2d47a0a95..66cbc3a9b 100644 --- a/src/css/popup.css +++ b/src/css/popup.css @@ -33,7 +33,7 @@ h2 { padding: 0.2em; text-align: center; } -h2:nth-of-type(1) { +h2:first-of-type { margin-top: 0; } a { @@ -124,7 +124,7 @@ body.portrait[dir="ltr"] #panes > div:nth-of-type(2) { #panes:not(.dfEnabled) > div:nth-of-type(2) { display: none; } -#panes > div:nth-of-type(1) { +#panes > div:first-of-type { min-width: 11em; padding: 0; } @@ -304,24 +304,30 @@ body[dir="rtl"] #tooltip { color: #000; display: inline-block; height: 1.9em; - line-height: 1.9em; + line-height: 1.9; overflow: hidden; position: relative; vertical-align: top; } -#firewallContainer > div:nth-of-type(1) > span:nth-of-type(1) { +#firewallContainer > div:first-of-type > span:first-of-type { cursor: pointer; } -#firewallContainer > div > span:nth-of-type(1) { +#firewallContainer > div > span:first-of-type { padding-right: 2px; position: relative; text-overflow: ellipsis; width: calc(100% - 4em); } +#firewallContainer > div.isDomain > span.isIDN:first-of-type > sup:before { + color: #666; + content: 'idn\2002'; + font-size: 80%; + font-weight: normal; + } #firewallContainer > div > span:nth-of-type(2) { display: none; } -#firewallContainer > div > span:nth-of-type(1) ~ span { +#firewallContainer > div > span:first-of-type ~ span { border-left: 1px solid white; width: 4em; } @@ -333,15 +339,15 @@ body[dir="rtl"] #tooltip { #firewallContainer > div > span:nth-of-type(4) { display: none; } -#firewallContainer > div.isDomain > span:nth-of-type(1) { +#firewallContainer > div.isDomain > span:first-of-type { font-weight: bold; } -#firewallContainer > div:nth-of-type(1) > span:nth-of-type(1):before { +#firewallContainer > div:first-of-type > span:first-of-type:before { color: #aaa; content: '\2012'; padding-right: 0.25em; } -#firewallContainer.minimized > div:nth-of-type(1) > span:nth-of-type(1):before { +#firewallContainer.minimized > div:first-of-type > span:first-of-type:before { content: '+'; } #firewallContainer.minimized > div.isDomain > span:nth-of-type(3) { @@ -379,7 +385,7 @@ body[dir="rtl"] #tooltip { content: '\2212\2212\2212'; } -body.advancedUser #firewallContainer > div > span:nth-of-type(1) { +body.advancedUser #firewallContainer > div > span:first-of-type { width: calc(100% - 8em); } body.advancedUser #firewallContainer > div > span:nth-of-type(2) { @@ -388,17 +394,17 @@ body.advancedUser #firewallContainer > div > span:nth-of-type(2) { body.advancedUser #firewallContainer > div:first-child ~ div:not([class]) { display: block; } -body.advancedUser #firewallContainer > div > span:nth-of-type(1) ~ span { +body.advancedUser #firewallContainer > div > span:first-of-type ~ span { cursor: pointer; } /** Small coloured label at the left of a row */ -#firewallContainer > div.allowed > span:nth-of-type(1):before, -#firewallContainer > div.blocked > span:nth-of-type(1):before, -#firewallContainer.minimized > div.isDomain.totalAllowed > span:nth-of-type(1):before, -#firewallContainer.minimized > div.isDomain.totalBlocked > span:nth-of-type(1):before { +#firewallContainer > div.allowed > span:first-of-type:before, +#firewallContainer > div.blocked > span:first-of-type:before, +#firewallContainer.minimized > div.isDomain.totalAllowed > span:first-of-type:before, +#firewallContainer.minimized > div.isDomain.totalBlocked > span:first-of-type:before { box-sizing: border-box; content: ''; display: inline-block; @@ -412,24 +418,24 @@ body.advancedUser #firewallContainer > div > span:nth-of-type(1) ~ span { Source for color-blind color scheme from https://github.com/WyohKnott: https://github.com/chrisaljoudi/uBlock/issues/467#issuecomment-95177219 */ -#firewallContainer > div.allowed > span:nth-of-type(1):before, -#firewallContainer.minimized > div.isDomain.totalAllowed > span:nth-of-type(1):before { +#firewallContainer > div.allowed > span:first-of-type:before, +#firewallContainer.minimized > div.isDomain.totalAllowed > span:first-of-type:before { background-color: rgb(0, 160, 0); } -#firewallContainer.colorBlind > div.allowed > span:nth-of-type(1):before, -#firewallContainer.colorBlind.minimized > div.isDomain.totalAllowed > span:nth-of-type(1):before { +#firewallContainer.colorBlind > div.allowed > span:first-of-type:before, +#firewallContainer.colorBlind.minimized > div.isDomain.totalAllowed > span:first-of-type:before { background-color: rgb(255, 194, 57); } -#firewallContainer > div.blocked > span:nth-of-type(1):before, -#firewallContainer.minimized > div.isDomain.totalBlocked > span:nth-of-type(1):before { +#firewallContainer > div.blocked > span:first-of-type:before, +#firewallContainer.minimized > div.isDomain.totalBlocked > span:first-of-type:before { background-color: rgb(192, 0, 0); } -#firewallContainer.colorBlind > div.blocked > span:nth-of-type(1):before, -#firewallContainer.colorBlind.minimized > div.isDomain.totalBlocked > span:nth-of-type(1):before { +#firewallContainer.colorBlind > div.blocked > span:first-of-type:before, +#firewallContainer.colorBlind.minimized > div.isDomain.totalBlocked > span:first-of-type:before { background-color: rgb(0, 19, 110); } -#firewallContainer > div.allowed.blocked > span:nth-of-type(1):before, -#firewallContainer.minimized > div.isDomain.totalAllowed.totalBlocked > span:nth-of-type(1):before { +#firewallContainer > div.allowed.blocked > span:first-of-type:before, +#firewallContainer.minimized > div.isDomain.totalAllowed.totalBlocked > span:first-of-type:before { background-color: rgb(192, 160, 0); } /* Rule cells */ @@ -483,7 +489,7 @@ body.advancedUser #firewallContainer > div > span.nRule.ownRule { height: 100%; opacity: 0.2; } -#actionSelector > span:nth-of-type(1) { +#actionSelector > span:first-of-type { width: 33%; } #actionSelector > span:nth-of-type(2) { @@ -495,10 +501,10 @@ body.advancedUser #firewallContainer > div > span.nRule.ownRule { #actionSelector > span:hover { opacity: 0.75; } -#actionSelector > span:nth-of-type(1) { +#actionSelector > span:first-of-type { background-color: rgb(0, 160, 0); } -#actionSelector.colorBlind > span:nth-of-type(1) { +#actionSelector.colorBlind > span:first-of-type { background-color: rgb(255, 194, 57); } #actionSelector > span:nth-of-type(2) { diff --git a/src/js/popup.js b/src/js/popup.js index f99747c7b..f88627802 100644 --- a/src/js/popup.js +++ b/src/js/popup.js @@ -1,7 +1,7 @@ /******************************************************************************* uBlock Origin - a browser extension to block requests. - Copyright (C) 2014-2016 Raymond Hill + Copyright (C) 2014-2017 Raymond Hill This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -94,6 +94,7 @@ var rowsToRecycle = uDom(); var cachedPopupHash = ''; var statsStr = vAPI.i18n('popupBlockedStats'); var domainsHitStr = vAPI.i18n('popupHitDomainCount'); +var reHasAsciiAndUnicode = /[A-Za-z]+[^\x00-\x7F]|[^\x00-\x7F]+[A-Za-z]/; /******************************************************************************/ @@ -196,10 +197,25 @@ var addFirewallRow = function(des) { } row.descendants('[data-des]').attr('data-des', des); - row.descendants('span:nth-of-type(1)').text(punycode.toUnicode(des)); - var hnDetails = popupData.hostnameDict[des] || {}; - var isDomain = des === hnDetails.domain; + var hnDetails = popupData.hostnameDict[des] || {}, + isDomain = des === hnDetails.domain; + + var prettyDomainName = punycode.toUnicode(des), + isPunycoded = prettyDomainName !== des, + mixedDomainName = false; + if ( isDomain && isPunycoded ) { + var pos = prettyDomainName.indexOf('.'); + if ( pos !== -1 ) { + mixedDomainName = reHasAsciiAndUnicode.test(prettyDomainName.slice(0, pos)); + } + } + + var span = row.nodeAt(0).querySelector('span:first-of-type'); + span.classList.toggle('isIDN', mixedDomainName); + span.querySelector('span').textContent = prettyDomainName; + span.title = isDomain && isPunycoded ? des : ''; + row.toggleClass('isDomain', isDomain) .toggleClass('isSubDomain', !isDomain) .toggleClass('allowed', hnDetails.allowCount !== 0) diff --git a/src/popup.html b/src/popup.html index e27f253e1..5f8f17ef7 100644 --- a/src/popup.html +++ b/src/popup.html @@ -48,7 +48,7 @@