From d37e0daad3dc3bf7f5783fdd58c538bc475dd364 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 19 Oct 2026 14:50:22 +0000 Subject: [PATCH] JS: reject URL arguments which may influence the load path for sqlite3.js and sqlite3.wasm if those values look like they might be remote URLs. sqlite3.mjs (ESM) is unaffected by this. This addresses [bugs:74f052d3d2|bug report 2026-10-19T12:25:33Z] but is a preliminary measure, with follow-ups expected. FossilOrigin-Name: 5080eb6d7a7a7a5c2cdfd08a766f0e096d0d5536488fcf0b325e7b06a6bdd092 --- ext/wasm/api/extern-post-js.c-pp.js | 37 +++++++++++++++++-- ext/wasm/api/pre-js.c-pp.js | 24 ++++++------ ext/wasm/api/sqlite3-worker1-promiser.c-pp.js | 9 ++++- ext/wasm/api/sqlite3-worker1.c-pp.js | 7 +++- ext/wasm/tester1-worker.c-pp.html | 10 ++++- ext/wasm/tester1.c-pp.js | 5 ++- manifest | 24 ++++++------ manifest.uuid | 2 +- 8 files changed, 85 insertions(+), 33 deletions(-) diff --git a/ext/wasm/api/extern-post-js.c-pp.js b/ext/wasm/api/extern-post-js.c-pp.js index a3a02c8019..43a2a24907 100644 --- a/ext/wasm/api/extern-post-js.c-pp.js +++ b/ext/wasm/api/extern-post-js.c-pp.js @@ -65,9 +65,40 @@ const toExportForESM = ? (...args)=>console.warn('sqlite3.debugModule:',...args) : ()=>{}; - if(sIMS.urlParams.has('sqlite3.dir')){ - sIMS.sqlite3Dir = sIMS.urlParams.get('sqlite3.dir') +'/'; - }else if(sIMS.moduleScript){ + /** + Fetchs sIMS.urlParams.get(key). If that looks like it might + be a remote path value then null is returned and a console + warning may be emitted. If it looks like it's a local path, + it is returned. + + [bugs:74f052d3d2]: do not allow URL arguments which are used for + determining file locations to be anything other than what appears + to be a local file reference. That is the only documented use for + these args and allowing URLs as values leads to chaos. This is + believed to resolve that report but is also considered a stopgap + measure. TODO is only allow query parameters from the same origin + as this script. + */ + sIMS.getPathArgument = (key)=>{ + const s = sIMS.urlParams.get(key); + //console.warn("sIMS.getPathArgument(",key,")",s); + if( !s ) return s; + if( s.indexOf(':')>=0 || s.indexOf('//')>=0 ){ + console.warn( + "Rejecting path string",key," because it does not look", + "like a local path:",s + ); + return null; + } + return s; + }; + + if( sIMS.urlParams.has('sqlite3.dir') ){ + const s = sIMS.getPathArgument('sqlite3.dir'); + if( s ){ + sIMS.sqlite3Dir = s + (s[s.length-1]==='/' ? '' : '/'); + } + }else if( sIMS.moduleScript ){ const li = sIMS.moduleScript.src.split('/'); li.pop(); sIMS.sqlite3Dir = li.join('/') + '/'; diff --git a/ext/wasm/api/pre-js.c-pp.js b/ext/wasm/api/pre-js.c-pp.js index 1a3d46f1d9..4e9bc4e659 100644 --- a/ext/wasm/api/pre-js.c-pp.js +++ b/ext/wasm/api/pre-js.c-pp.js @@ -56,7 +56,8 @@ Worker constructor or importScripts() to be able to resolve foo/bar/X.wasm (in the latter case, with some help): - 1) If URL param named the same as `path` is set, it is returned. + 1) If URL param named the same as `path` is set and it looks like + a local path reference, it is returned. 2) If sqlite3InitModuleState.sqlite3Dir is set, then (thatName + path) is returned (it's assumed to end with '/'). @@ -84,21 +85,20 @@ return new URL(path, import.meta.url).href; //#else 'use strict'; - let theFile; - const up = this.urlParams; - if(up?.has(path)){ - theFile = up.get(path); - }else if(this.sqlite3Dir){ - theFile = this.sqlite3Dir + path; - }else if(this.scriptDir){ - theFile = this.scriptDir + path; - }else{ - theFile = prefix + path; + let theFile = this.getPathArgument(path); + if( !theFile ){ + if(this.sqlite3Dir){ + theFile = this.sqlite3Dir + path; + }else if(this.scriptDir){ + theFile = this.scriptDir + path; + }else{ + theFile = prefix + path; + } } this.debugModule( "locateFile(",arguments[0], ',', arguments[1],")", 'sqlite3InitModuleState.scriptDir =',this.scriptDir, - 'up.entries() =',Array.from(up.entries()), + 'urlParams.entries() =',Array.from(this.urlParams.entries()), "result =", theFile ); return theFile; diff --git a/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js b/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js index bcbf3fa9f8..b21f8a3a28 100644 --- a/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js +++ b/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js @@ -272,7 +272,14 @@ globalThis.sqlite3Worker1Promiser.defaultConfig = { //sqlite3.config.warn("promiser currentScript, theJs =",this.currentScript,theJs); }else if(globalThis.location){ //sqlite3.config.warn("promiser globalThis.location =",globalThis.location); - const urlParams = new URL(globalThis.location.href).searchParams; + const s = urlParams.get('sqlite3.dir'); + if( s ){ + if( s.indexOf(':')<0 && s.indexOf('//')<0 ){ + theJs = s + '/' + theJs; + }else{ + console.warn("Invalid sqlite3.dir value:",s); + } + } if(urlParams.has('sqlite3.dir')){ theJs = urlParams.get('sqlite3.dir') + '/' + theJs; } diff --git a/ext/wasm/api/sqlite3-worker1.c-pp.js b/ext/wasm/api/sqlite3-worker1.c-pp.js index 046243baa5..0e560c9789 100644 --- a/ext/wasm/api/sqlite3-worker1.c-pp.js +++ b/ext/wasm/api/sqlite3-worker1.c-pp.js @@ -44,7 +44,12 @@ import sqlite3InitModule from './sqlite3.mjs'; : new URLSearchParams(); let theJs = 'sqlite3.js'; if(urlParams.has('sqlite3.dir')){ - theJs = urlParams.get('sqlite3.dir') + '/' + theJs; + const s = urlParams.get('sqlite3.dir'); + if( s && s.indexOf(':')<0 && s.indexOf('//')<0 ){ + theJs = s + '/' + theJs; + }else{ + console.warn("Invalid sqlite3.dir value:",s); + } } //console.warn("worker1 theJs =",theJs); importScripts(theJs); diff --git a/ext/wasm/tester1-worker.c-pp.html b/ext/wasm/tester1-worker.c-pp.html index fb6421cfdf..dec3ed04da 100644 --- a/ext/wasm/tester1-worker.c-pp.html +++ b/ext/wasm/tester1-worker.c-pp.html @@ -76,8 +76,16 @@ "sqlite3 tester #1: ES6 Worker Module (@bitness@-bit WASM)"; }); }else{ - workerArgs.push(baseName+'.js?sqlite3.dir=jswasm'); + const l = globalThis.location; + workerArgs.push(baseName+'.js?sqlite3.dir='+( + 0/*set to 1 only for testing*/ + ? (l.protocol+'//'+l.host+'/jswasm') + /* ^^^ must be rejected by module loader without trying to + load that */ + : 'jswasm' + )); } + console.warn("workerArgs =",workerArgs); const w = new Worker(...workerArgs); w.onmessage = function({data}){ switch(data.type){ diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 5c6e1fe959..50b7a3c658 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -4642,8 +4642,9 @@ if(!globalThis.sqlite3InitModule && !isUIThread()){ support for locating the wasm, so remove that dir part. */; const urlParams = new URL(globalThis.location.href).searchParams; - if(urlParams.has('sqlite3.dir')){ - sqlite3Js = urlParams.get('sqlite3.dir') + '/' + sqlite3Js; + const s3d = urlParams.get('sqlite3.dir'); + if( s3d ){ + sqlite3Js = s3d + '/' + sqlite3Js; } importScripts(sqlite3Js); } diff --git a/manifest b/manifest index 4a5b480cb7..8ba803b8f0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sdefault\sfloating\spoint\sformat\sfor\sJSON\sand\sINSERT\soutput\smodes\nshould\sbe\s"%!0.17"\sto\spreserve\sfull\sbinary→text→binary\sround-trips\nwith\sno\sloss\sof\sprecision.\n[bugs:/info/2026-10-18T20:37:23Z|Bug\s2026-10-18T20:37:23Z]. -D 2026-10-19T14:34:34.551 +C JS:\sreject\sURL\sarguments\swhich\smay\sinfluence\sthe\sload\spath\sfor\ssqlite3.js\sand\ssqlite3.wasm\sif\sthose\svalues\slook\slike\sthey\smight\sbe\sremote\sURLs.\ssqlite3.mjs\s(ESM)\sis\sunaffected\sby\sthis.\sThis\saddresses\s[bugs:74f052d3d2|bug\sreport\s2026-10-19T12:25:33Z]\sbut\sis\sa\spreliminary\smeasure,\swith\sfollow-ups\sexpected. +D 2026-10-19T14:50:22.561 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -653,13 +653,13 @@ F ext/wasm/SQLTester/index.html 64f3435084c7d6139b08d1f2a713828a73f68de2ae6a3112 F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536 F ext/wasm/api/EXPORTED_FUNCTIONS.c-pp 0b0eee602791286ab18e07eadd38a531389285681bd3dbe92c5520ff81ca769a F ext/wasm/api/README.md a905d5c6bfc3e2df875bd391d6d6b7b48d41b43bdee02ad115b47244781a7e81 -F ext/wasm/api/extern-post-js.c-pp.js cba0f9735f741ce266aa0c52e6e1224f9fb027f20253292d3e71480787675a05 +F ext/wasm/api/extern-post-js.c-pp.js 22f9437272a44c385bac4ef66f632ab63ee662e31cbf7053a8961f276a28b6a4 F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41 F ext/wasm/api/opfs-common-inline.c-pp.js f84640e2b1e9c5903deb55ef3d7bf537587e31eb6f4f257b4a75827146d2b5a9 F ext/wasm/api/opfs-common-shared.c-pp.js 51d86e01ec20438552d09d233dfad97e681364b3e432fc083e2b8cd88fdcc865 F ext/wasm/api/post-js-footer.js a50c1a2c4d008aede7b2aa1f18891a7ee71437c2f415b8aeb3db237ddce2935b F ext/wasm/api/post-js-header.js f35d2dcf1ab7f22a93d565f8e0b622a2934fc4e743edf3b708e4dd8140eeff55 -F ext/wasm/api/pre-js.c-pp.js 2d12b65e1caefda202edc67ccbe248918ed1aee7fd4907527bffb3e6bca599c0 +F ext/wasm/api/pre-js.c-pp.js 145da76085bd31bbe9c9b2d52bc56106116745576699d03b8bd6eaaf78e1e537 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0e41b7b571219eaf91a66d8cdbcbcab2b16db537046c0a35af8e0e48a72f99ca F ext/wasm/api/sqlite3-api-oo1.c-pp.js d41c122250a213002adf294487156ed46f146760a4d904e13996dcc425d7c15e F ext/wasm/api/sqlite3-api-prologue.js 0084e15d66fbcd75cacbaa58e3b473d5e57082c30f3122be7fdadff5589cf6b6 @@ -673,8 +673,8 @@ F ext/wasm/api/sqlite3-vfs-opfs-wl.c-pp.js 60fa106fc11d31adb1773ac16dd60fc9335a3 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 5dd8410121acf623ce53005a4aab2c7b2b7f5d1ad072f69ebc208882bc7b7236 F ext/wasm/api/sqlite3-vtab-helper.c-pp.js 3218318194b11fa625ebda9f7900280c5c26cf257ab5b2b66709ce58e9531624 F ext/wasm/api/sqlite3-wasm.c 5ac22d03231318615112fdea462ea6abbee6cadf964f22b6dfcc813dd6b37b85 -F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 46919740f8176c10f691431a81c769c35657e3b537e2ed2bde691f9017b0ee8a -F ext/wasm/api/sqlite3-worker1.c-pp.js 21b20d3b8d43471d1647123616a7e5435b1e4b6fa447714f91ffc7f950ea01e8 +F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 3b551b4c4434d96c5daa21fe849c2f3f9ed1356d931b231975c32828efaa3c86 +F ext/wasm/api/sqlite3-worker1.c-pp.js d274d5eb7f43f4f3b35a4d1f9213a1e34aa5ae27df7af9e74df9f89a50ee7bda F ext/wasm/common/SqliteTestUtil.js dae753b95e72248c4395d8de8359e0d055cd9928488e8dd84aef89e46d23b32e F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f @@ -712,9 +712,9 @@ F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f129 F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0 F ext/wasm/sql/001-sudoku.sql 35b7cb7239ba5d5f193bc05ec379bcf66891bce6f2a5b3879f2f78d0917299b5 F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555e685bce3da8c3f -F ext/wasm/tester1-worker.c-pp.html 441b8b12769670a6bf03be205e6f20ec05827348a565ddcee94219c44ec313e3 +F ext/wasm/tester1-worker.c-pp.html 3295e3abc51599573bd363ee26948e64cc1693992e8e30ad0a3a1662786a5e3a F ext/wasm/tester1.c-pp.html 69403505b2c0b6cd76c8a210e3a09e80a8eb84a47c3eae591ab0e81c3934af61 -F ext/wasm/tester1.c-pp.js de7cdfee3b1dace334698be34a36945f2476be265f20d8c84d6b2408d5d8f8fd +F ext/wasm/tester1.c-pp.js 77c741e438d62e23c94302a5fafa56259dea2857d5a0303b6267e3eca98608ad F ext/wasm/tests/opfs/concurrency/index.html 706eab6308343c04ac2360aba6001af4ffaf46d8f33a0ccd02c64d93e3216a43 F ext/wasm/tests/opfs/concurrency/test.js 6919778fceaac1b7cc78caf41d796f545d2c4433b31188aa9689f05b5ad28828 F ext/wasm/tests/opfs/concurrency/worker.js 704d82c5e287e47f612349e027765943a58ad967dcf178fb5a1c3a8eaafb09af @@ -2287,8 +2287,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P a9d8123e27fa71bf7d29ec4cc7aa997f5e94de3c5b48907ccb7242795e44144c -R a3cb7a0de919be3d3c7a546007ca270e -U drh -Z caab71dfa7cb28c4221853205e2bf5f8 +P c31221e954bcca2e6505338446635d0efb809f453008c4927441ebd6f0e1b873 +R 1b44b97ce0051b7a496005ba6b1c390f +U stephan +Z 3cdf726eb407d58fd9231dee11be8280 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0365f452d7..c09bfad9fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c31221e954bcca2e6505338446635d0efb809f453008c4927441ebd6f0e1b873 +5080eb6d7a7a7a5c2cdfd08a766f0e096d0d5536488fcf0b325e7b06a6bdd092