Chromium Code Reviews| Index: chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java |
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java b/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java |
| index 6b6d07a3fa6620310bc2b4716e1851141934c4e4..340a2ba599238de46ec48bb01895aef4d2532cc4 100644 |
| --- a/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java |
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java |
| @@ -9,6 +9,7 @@ import android.content.Context; |
| import android.content.DialogInterface; |
| import android.graphics.Color; |
| import android.graphics.drawable.ColorDrawable; |
| +import android.net.Uri; |
| import android.text.Layout; |
| import android.text.Spannable; |
| import android.text.SpannableStringBuilder; |
| @@ -164,6 +165,13 @@ public class WebsiteSettingsPopup implements OnClickListener, OnItemSelectedList |
| private static final int MAX_TABLET_DIALOG_WIDTH_DP = 400; |
| + // This is the "reserved" character set from RFC 3986, plus the '%' character. |
| + private static final String URI_RESERVED_CHARACTERS = "!*'();:@&=+$,/?#[]%"; |
| + |
| + private static final char FIRST_UNICODE_WHITESPACE = '\u2000'; |
| + private static final char FINAL_UNICODE_WHITESPACE = '\u200F'; |
| + private static final char UNICODE_NBSP = '\u00A0'; |
| + |
| private final Context mContext; |
| private final Profile mProfile; |
| private final WebContents mWebContents; |
| @@ -289,7 +297,8 @@ public class WebsiteSettingsPopup implements OnClickListener, OnItemSelectedList |
| } |
| mSecurityLevel = ToolbarModel.getSecurityLevelForWebContents(mWebContents); |
| - SpannableStringBuilder urlBuilder = new SpannableStringBuilder(mFullUrl); |
| + String displayUrl = encodeSuspiciousFragment(mFullUrl); |
| + SpannableStringBuilder urlBuilder = new SpannableStringBuilder(displayUrl); |
| OmniboxUrlEmphasizer.emphasizeUrl(urlBuilder, mContext.getResources(), mProfile, |
| mSecurityLevel, mIsInternalPage, true); |
| mUrlTitle.setText(urlBuilder); |
| @@ -300,6 +309,35 @@ public class WebsiteSettingsPopup implements OnClickListener, OnItemSelectedList |
| } |
| /** |
| + * Percent-encodes a URL fragment if it contains suspicious unicode whitespace characters. |
|
Matt Giuca
2015/03/24 06:28:37
nit: Unicode is a proper noun (always capitalize w
tsergeant
2015/03/25 01:55:24
Done.
|
| + * Otherwise, returns the original URL. All parts of the URL other than the fragment will |
| + * already be encoded. |
| + */ |
| + public static String encodeSuspiciousFragment(String urlStr) { |
|
Matt Giuca
2015/03/24 06:28:37
What do you mean by "fragment" here? Do you mean s
tsergeant
2015/03/25 01:55:24
The intention was that even though we're working o
Matt Giuca
2015/03/25 03:23:24
You should remove the last sentence of the documen
|
| + if (isSuspiciousUrl(urlStr)) { |
|
Matt Giuca
2015/03/24 06:28:37
I'm not too keen on this behaviour, as you will be
tsergeant
2015/03/25 01:55:24
Makes sense, Done.
|
| + // Explicitly pass the set of reserved characters to prevent them from being escaped. |
| + return Uri.encode(urlStr, URI_RESERVED_CHARACTERS); |
| + } |
| + return urlStr; |
| + } |
| + |
| + /** |
| + * Returns true if the fragment string contains characters that could be used to inject a |
| + * phishing attack into the popup. We filter based on any unicode whitespace character. |
| + */ |
| + public static boolean isSuspiciousUrl(String urlStr) { |
| + for (int i = 0; i < urlStr.length(); i++) { |
| + char fragmentChar = urlStr.charAt(i); |
| + if ((fragmentChar >= FIRST_UNICODE_WHITESPACE |
| + && fragmentChar <= FINAL_UNICODE_WHITESPACE) |
| + || fragmentChar == ' ' |
| + || fragmentChar == UNICODE_NBSP) |
| + return true; |
| + } |
| + return false; |
| + } |
| + |
| + /** |
| * Sets the visibility of the lower area of the dialog (containing the permissions and 'Site |
| * Settings' button). |
| * |