Deprecate the isValidUrl utility function and replace it with createValidAbsoluteUrl/isValidProtocal functions instead, since the main URL validation is now done using the new URL constructor

This commit is contained in:
Jonas Jenwald 2016-10-03 14:35:29 +02:00
parent 42f07c6262
commit 71a781ee5c
7 changed files with 49 additions and 31 deletions

View File

@ -48,7 +48,7 @@ var shadow = sharedUtil.shadow;
var stringToPDFString = sharedUtil.stringToPDFString;
var stringToUTF8String = sharedUtil.stringToUTF8String;
var warn = sharedUtil.warn;
var isValidUrl = sharedUtil.isValidUrl;
var createValidAbsoluteUrl = sharedUtil.createValidAbsoluteUrl;
var Util = sharedUtil.Util;
var Ref = corePrimitives.Ref;
var RefSet = corePrimitives.RefSet;
@ -694,13 +694,9 @@ var Catalog = (function CatalogClosure() {
if (isString(url)) {
url = tryConvertUrlEncoding(url);
var absoluteUrl;
try {
absoluteUrl = new URL(url).href;
} catch (ex) { /* `new URL()` will throw on incorrect data. */ }
if (isValidUrl(absoluteUrl, /* allowRelative = */ false)) {
resultObj.url = absoluteUrl;
var absoluteUrl = createValidAbsoluteUrl(url);
if (absoluteUrl) {
resultObj.url = absoluteUrl.href;
}
resultObj.unsafeUrl = url;
}

View File

@ -28,6 +28,8 @@
var removeNullCharacters = sharedUtil.removeNullCharacters;
var warn = sharedUtil.warn;
var deprecated = sharedUtil.deprecated;
var createValidAbsoluteUrl = sharedUtil.createValidAbsoluteUrl;
/**
* Optimised CSS custom property getter/setter.
@ -229,9 +231,16 @@ function isExternalLinkTargetSet() {
}
}
function isValidUrl(url, allowRelative) {
deprecated('isValidUrl(), please use createValidAbsoluteUrl() instead.');
var baseUrl = allowRelative ? 'http://example.com' : null;
return createValidAbsoluteUrl(url, baseUrl) !== null;
}
exports.CustomStyle = CustomStyle;
exports.addLinkAttributes = addLinkAttributes;
exports.isExternalLinkTargetSet = isExternalLinkTargetSet;
exports.isValidUrl = isValidUrl;
exports.getFilenameFromUrl = getFilenameFromUrl;
exports.LinkTarget = LinkTarget;
exports.hasCanvasTypedArrays = hasCanvasTypedArrays;

View File

@ -76,7 +76,7 @@
PDFJS.VERBOSITY_LEVELS = sharedUtil.VERBOSITY_LEVELS;
PDFJS.OPS = sharedUtil.OPS;
PDFJS.UNSUPPORTED_FEATURES = sharedUtil.UNSUPPORTED_FEATURES;
PDFJS.isValidUrl = sharedUtil.isValidUrl;
PDFJS.isValidUrl = displayDOMUtils.isValidUrl;
PDFJS.shadow = sharedUtil.shadow;
PDFJS.createBlob = sharedUtil.createBlob;
PDFJS.createObjectURL = function PDFJS_createObjectURL(data, contentType) {

View File

@ -55,12 +55,12 @@
exports.UnexpectedResponseException = sharedUtil.UnexpectedResponseException;
exports.OPS = sharedUtil.OPS;
exports.UNSUPPORTED_FEATURES = sharedUtil.UNSUPPORTED_FEATURES;
exports.isValidUrl = sharedUtil.isValidUrl;
exports.isValidUrl = displayDOMUtils.isValidUrl;
exports.createValidAbsoluteUrl = sharedUtil.createValidAbsoluteUrl;
exports.createObjectURL = sharedUtil.createObjectURL;
exports.removeNullCharacters = sharedUtil.removeNullCharacters;
exports.shadow = sharedUtil.shadow;
exports.createBlob = sharedUtil.createBlob;
exports.getFilenameFromUrl = displayDOMUtils.getFilenameFromUrl;
exports.addLinkAttributes = displayDOMUtils.addLinkAttributes;
}));

View File

@ -64,7 +64,9 @@
exports.OPS = pdfjsLibs.pdfjsSharedUtil.OPS;
exports.UNSUPPORTED_FEATURES =
pdfjsLibs.pdfjsSharedUtil.UNSUPPORTED_FEATURES;
exports.isValidUrl = pdfjsLibs.pdfjsSharedUtil.isValidUrl;
exports.isValidUrl = pdfjsLibs.pdfjsDisplayDOMUtils.isValidUrl;
exports.createValidAbsoluteUrl =
pdfjsLibs.pdfjsSharedUtil.createValidAbsoluteUrl;
exports.createObjectURL = pdfjsLibs.pdfjsSharedUtil.createObjectURL;
exports.removeNullCharacters =
pdfjsLibs.pdfjsSharedUtil.removeNullCharacters;

View File

@ -332,30 +332,42 @@ function isSameOrigin(baseUrl, otherUrl) {
return base.origin === other.origin;
}
// Validates if URL is safe and allowed, e.g. to avoid XSS.
function isValidUrl(url, allowRelative) {
if (!url || typeof url !== 'string') {
// Checks if URLs use one of the whitelisted protocols, e.g. to avoid XSS.
function isValidProtocol(url) {
if (!url) {
return false;
}
// RFC 3986 (http://tools.ietf.org/html/rfc3986#section-3.1)
// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
var protocol = /^[a-z][a-z0-9+\-.]*(?=:)/i.exec(url);
if (!protocol) {
return allowRelative;
}
protocol = protocol[0].toLowerCase();
switch (protocol) {
case 'http':
case 'https':
case 'ftp':
case 'mailto':
case 'tel':
switch (url.protocol) {
case 'http:':
case 'https:':
case 'ftp:':
case 'mailto:':
case 'tel:':
return true;
default:
return false;
}
}
/**
* Attempts to create a valid absolute URL (utilizing `isValidProtocol`).
* @param {URL|string} url - An absolute, or relative, URL.
* @param {URL|string} baseUrl - An absolute URL.
* @returns Either a valid {URL}, or `null` otherwise.
*/
function createValidAbsoluteUrl(url, baseUrl) {
if (!url) {
return null;
}
try {
var absoluteUrl = baseUrl ? new URL(url, baseUrl) : new URL(url);
if (isValidProtocol(absoluteUrl)) {
return absoluteUrl;
}
} catch (ex) { /* `new URL()` will throw on incorrect data. */ }
return null;
}
function shadow(obj, prop, value) {
Object.defineProperty(obj, prop, { value: value,
enumerable: true,
@ -2431,7 +2443,7 @@ exports.isNum = isNum;
exports.isString = isString;
exports.isSpace = isSpace;
exports.isSameOrigin = isSameOrigin;
exports.isValidUrl = isValidUrl;
exports.createValidAbsoluteUrl = createValidAbsoluteUrl;
exports.isLittleEndian = isLittleEndian;
exports.isEvalSupported = isEvalSupported;
exports.loadJpegStream = loadJpegStream;

View File

@ -67,10 +67,9 @@ if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC || CHROME')) {
DownloadManager.prototype = {
downloadUrl: function DownloadManager_downloadUrl(url, filename) {
if (!pdfjsLib.isValidUrl(url, true)) {
if (!pdfjsLib.createValidAbsoluteUrl(url, 'http://example.com')) {
return; // restricted/invalid URL
}
download(url + '#pdfjs.action=download', filename);
},