Bug 1157810 - Enforce that tile images are loaded from mozilla.net [r=adw, f=bsmedberg]

This commit is contained in:
Ed Lee 2015-05-14 16:46:39 -07:00
parent 73e89e4286
commit 735df0f80c
3 changed files with 50 additions and 9 deletions

View File

@ -90,7 +90,9 @@ Users can turn off the ping with in-new-tab-page controls.
As the new tab page is rendered, any images for tiles are downloaded if not
already cached. The default servers hosting the images are Mozilla CDN that
don't use cookies: https://tiles.cdn.mozilla.net/
don't use cookies: https://tiles.cdn.mozilla.net/ and Firefox enforces that the
images come from mozilla.net or data URIs when using the default directory
source.
Source JSON Format

View File

@ -85,6 +85,9 @@ const ALLOWED_LINK_SCHEMES = new Set(["http", "https"]);
// Only allow link image urls that are https or data
const ALLOWED_IMAGE_SCHEMES = new Set(["https", "data"]);
// Only allow urls to Mozilla's CDN or empty (for data URIs)
const ALLOWED_URL_BASE = new Set(["mozilla.net", ""]);
// The frecency of a directory link
const DIRECTORY_FRECENCY = 1000;
@ -159,6 +162,7 @@ let DirectoryLinksProvider = {
if (!this.__linksURL) {
try {
this.__linksURL = Services.prefs.getCharPref(this._observedPrefs["linksURL"]);
this.__linksURLModified = Services.prefs.prefHasUserValue(this._observedPrefs["linksURL"]);
}
catch (e) {
Cu.reportError("Error fetching directory links url from prefs: " + e);
@ -576,21 +580,30 @@ let DirectoryLinksProvider = {
},
/**
* Check if a url's scheme is in a Set of allowed schemes
* Check if a url's scheme is in a Set of allowed schemes and if the base
* domain is allowed.
* @param url to check
* @param allowed Set of allowed schemes
* @param checkBase boolean to check the base domain
*/
isURLAllowed: function DirectoryLinksProvider_isURLAllowed(url, allowed) {
isURLAllowed(url, allowed, checkBase) {
// Assume no url is an allowed url
if (!url) {
return true;
}
let scheme = "";
let scheme = "", base = "";
try {
// A malformed url will not be allowed
scheme = Services.io.newURI(url, null, null).scheme;
let uri = Services.io.newURI(url, null, null);
scheme = uri.scheme;
// URIs without base domains will be allowed
base = Services.eTLD.getBaseDomain(uri);
}
catch(ex) {}
return allowed.has(scheme);
// Require a scheme match and the base only if desired
return allowed.has(scheme) && (!checkBase || ALLOWED_URL_BASE.has(base));
},
/**
@ -604,11 +617,13 @@ let DirectoryLinksProvider = {
this._suggestedLinks.clear();
this._clearCampaignTimeout();
// Only check base domain for images when using the default pref
let checkBase = !this.__linksURLModified;
let validityFilter = function(link) {
// Make sure the link url is allowed and images too if they exist
return this.isURLAllowed(link.url, ALLOWED_LINK_SCHEMES) &&
this.isURLAllowed(link.imageURI, ALLOWED_IMAGE_SCHEMES) &&
this.isURLAllowed(link.enhancedImageURI, ALLOWED_IMAGE_SCHEMES);
return this.isURLAllowed(link.url, ALLOWED_LINK_SCHEMES, false) &&
this.isURLAllowed(link.imageURI, ALLOWED_IMAGE_SCHEMES, checkBase) &&
this.isURLAllowed(link.enhancedImageURI, ALLOWED_IMAGE_SCHEMES, checkBase);
}.bind(this);
rawLinks.suggested.filter(validityFilter).forEach((link, position) => {

View File

@ -1118,6 +1118,30 @@ add_task(function test_DirectoryLinksProvider_getAllowedImages() {
do_check_eq(links[1].imageURI, data["directory"][5].imageURI);
});
add_task(function test_DirectoryLinksProvider_getAllowedImages_base() {
let data = {"directory": [
{url: "http://example1.com", imageURI: "https://example.com"},
{url: "http://example2.com", imageURI: "https://tiles.cdn.mozilla.net"},
{url: "http://example3.com", imageURI: "https://tiles2.cdn.mozilla.net"},
{url: "http://example4.com", enhancedImageURI: "https://mozilla.net"},
{url: "http://example5.com", imageURI: "data:text/plain,hi"},
]};
let dataURI = 'data:application/json,' + JSON.stringify(data);
yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
// Pretend we're using the default pref to trigger base matching
DirectoryLinksProvider.__linksURLModified = false;
let links = yield fetchData();
do_check_eq(links.length, 4);
// The only remaining images should be https with mozilla.net or data URI
do_check_eq(links[0].url, data["directory"][1].url);
do_check_eq(links[1].url, data["directory"][2].url);
do_check_eq(links[2].url, data["directory"][3].url);
do_check_eq(links[3].url, data["directory"][4].url);
});
add_task(function test_DirectoryLinksProvider_getAllowedEnhancedImages() {
let data = {"directory": [
{url: "http://example.com", enhancedImageURI: "ftp://example.com"},