@@ -83,29 +83,38 @@ const isAlwaysTrustedForFetching = parsed => (
8383 parsed . origin === 'https://scratchdb.lefty.one'
8484) ;
8585
86+ const FETCHABLE_PROTOCOLS = [
87+ 'http:' ,
88+ 'https:' ,
89+ 'data:' ,
90+ 'blob:' ,
91+ 'ws:' ,
92+ 'wss:'
93+ ] ;
94+
95+ const VISITABLE_PROTOCOLS = [
96+ // The important one we want to exclude is javascript:
97+ 'http:' ,
98+ 'https:' ,
99+ 'data:' ,
100+ 'blob:' ,
101+ 'mailto:' ,
102+ 'steam:' ,
103+ 'calculator:'
104+ ] ;
105+
86106/**
87107 * @param {string } url Original URL string
108+ * @param {string[] } protocols List of allowed protocols
88109 * @returns {URL|null } A URL object if it is valid and of a known protocol, otherwise null.
89110 */
90- const parseURL = url => {
111+ const parseURL = ( url , protocols ) => {
91112 let parsed ;
92113 try {
93114 parsed = new URL ( url ) ;
94115 } catch ( e ) {
95116 return null ;
96117 }
97- const protocols = [
98- // The important one we want to exclude is javascript:
99- 'http:' ,
100- 'https:' ,
101- 'ws:' ,
102- 'wss:' ,
103- 'data:' ,
104- 'blob:' ,
105- 'mailto:' ,
106- 'steam:' ,
107- 'calculator:'
108- ] ;
109118 if ( ! protocols . includes ( parsed . protocol ) ) {
110119 return null ;
111120 }
@@ -274,22 +283,23 @@ class TWSecurityManagerComponent extends React.Component {
274283 * @returns {Promise<boolean> } True if the resource is allowed to be fetched
275284 */
276285 async canFetch ( url ) {
277- const parsed = parseURL ( url ) ;
286+ const parsed = parseURL ( url , FETCHABLE_PROTOCOLS ) ;
278287 if ( ! parsed ) {
279288 return false ;
280289 }
281290 if ( isAlwaysTrustedForFetching ( parsed ) ) {
282291 return true ;
283292 }
284293 const { showModal, releaseLock} = await this . acquireModalLock ( ) ;
285- if ( fetchOriginsTrustedByUser . has ( origin ) ) {
294+ const origin = ( parsed . protocol === 'http:' || parsed . protocol === 'https:' ) ? parsed . origin : null ;
295+ if ( origin && fetchOriginsTrustedByUser . has ( origin ) ) {
286296 releaseLock ( ) ;
287297 return true ;
288298 }
289299 const allowed = await showModal ( SecurityModals . Fetch , {
290300 url
291301 } ) ;
292- if ( allowed ) {
302+ if ( origin && allowed ) {
293303 fetchOriginsTrustedByUser . add ( origin ) ;
294304 }
295305 return allowed ;
@@ -300,7 +310,7 @@ class TWSecurityManagerComponent extends React.Component {
300310 * @returns {Promise<boolean> } True if the website can be opened
301311 */
302312 async canOpenWindow ( url ) {
303- const parsed = parseURL ( url ) ;
313+ const parsed = parseURL ( url , VISITABLE_PROTOCOLS ) ;
304314 if ( ! parsed ) {
305315 return false ;
306316 }
@@ -315,7 +325,7 @@ class TWSecurityManagerComponent extends React.Component {
315325 * @returns {Promise<boolean> } True if the website can be redirected to
316326 */
317327 async canRedirect ( url ) {
318- const parsed = parseURL ( url ) ;
328+ const parsed = parseURL ( url , VISITABLE_PROTOCOLS ) ;
319329 if ( ! parsed ) {
320330 return false ;
321331 }
@@ -385,7 +395,7 @@ class TWSecurityManagerComponent extends React.Component {
385395 * @returns {Promise<boolean> } True if embed is allowed.
386396 */
387397 async canEmbed ( url ) {
388- const parsed = parseURL ( url ) ;
398+ const parsed = parseURL ( url , FETCHABLE_PROTOCOLS ) ;
389399 if ( ! parsed ) {
390400 return false ;
391401 }
0 commit comments