1
0
Эх сурвалжийг харах

Merge pull request #1464 from PrivateBin/wasm-streaming

WASM streaming / eliminate unsafe-eval
El RIDO 1 жил өмнө
parent
commit
1c7d639546

+ 1 - 0
CHANGELOG.md

@@ -1,6 +1,7 @@
 # PrivateBin version history
 
 ## 1.7.6 (not yet released)
+* CHANGED: Switched to WASM streaming and replace unsafe-eval with wasm-unsafe-eval CSP declaration (#1464), requires webserver to have `application/wasm` MIME type configured.
 
 ## 1.7.5 (2024-11-16)
 * ADDED: Allow non persistent SQL connections, if configured (#1394)

+ 3 - 5
cfg/conf.sample.php

@@ -101,11 +101,9 @@ languageselection = false
 ;   they are embedded in pastes. If you wish to allow that, you can adjust the
 ;   policy here. See https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-it-load-embedded-images
 ;   for details.
-; - The 'unsafe-eval' is used in two cases; to check if the browser supports
-;   async functions and display an error if not and for Chrome to enable
-;   webassembly support (used for zlib compression). You can remove it if Chrome
-;   doesn't need to be supported and old browsers don't need to be warned.
-; cspheader = "default-src 'none'; base-uri 'self'; form-action 'none'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'unsafe-eval'; style-src 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads"
+; - The 'wasm-unsafe-eval' is used to enable webassembly support (used for zlib
+;   compression). You can remove it if compression doesn't need to be supported.
+; cspheader = "default-src 'none'; base-uri 'self'; form-action 'none'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'wasm-unsafe-eval'; style-src 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads"
 
 ; stay compatible with PrivateBin Alpha 0.19, less secure
 ; if enabled will use base64.js version 1.7 instead of 2.1.9 and sha1 instead of

+ 3 - 16
js/legacy.js

@@ -6,7 +6,6 @@
  * @see       {@link https://github.com/PrivateBin/PrivateBin}
  * @copyright 2012 Sébastien SAUVAGE ({@link http://sebsauvage.net})
  * @license   {@link https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License}
- * @version   1.3.1
  * @name      Legacy
  * @namespace
  */
@@ -175,18 +174,6 @@
             )) {
                 return true;
             }
-
-            // async & ES6 support
-            try {
-                eval('async () => {}');
-            } catch (e) {
-                if (e instanceof SyntaxError) {
-                    return true;
-                } else {
-                    throw e; // throws CSP error
-                }
-            }
-
             return false;
         }
 
@@ -238,7 +225,7 @@
         {
             return init;
         };
-        
+
         /**
          * returns the current status of the check
          *
@@ -250,7 +237,7 @@
         {
             return status;
         };
-        
+
         /**
          * init on application start, returns an all-clear signal
          *
@@ -308,4 +295,4 @@
     this.Legacy = {
         Check: Check
     };
-}).call(this);
+}).call(this);

+ 24 - 33
js/zlib-1.3.1.js

@@ -1,6 +1,6 @@
 'use strict';
 
-(function() {
+(function () {
     let ret;
 
     async function initialize() {
@@ -23,16 +23,7 @@
             _abort: errno => { console.error(`Error: ${errno}`) },
             _grow: () => { },
         };
-
-        let buff;
-        if (typeof fs === 'object') {
-            buff = fs.readFileSync('zlib-1.3.1.wasm');
-        } else {
-            const resp = await fetch('js/zlib-1.3.1.wasm');
-            buff = await resp.arrayBuffer();
-        }
-        const module = await WebAssembly.compile(buff);
-        const ins = await WebAssembly.instantiate(module, { env });
+        const ins = (await WebAssembly.instantiateStreaming(fetch('js/zlib-1.3.1.wasm'), { env })).instance;
 
         const srcPtr = ins.exports._malloc(CHUNK_SIZE);
         const dstPtr = ins.exports._malloc(CHUNK_SIZE);
@@ -116,28 +107,28 @@
         }
 
         ret = {
-                inflate(rawDeflateBuffer) {
-                    const rawInf = new RawInf();
-                    for (let offset = 0; offset < rawDeflateBuffer.length; offset += CHUNK_SIZE) {
-                        const end = Math.min(offset + CHUNK_SIZE, rawDeflateBuffer.length);
-                        const chunk = rawDeflateBuffer.subarray(offset, end);
-                        rawInf.inflate(chunk);
-                    }
-                    const ret = rawInf.getBuffer();
-                    rawInf.destroy();
-                    return ret;
-                },
-                deflate(rawInflateBuffer) {
-                    const rawDef = new RawDef();
-                    for (let offset = 0; offset < rawInflateBuffer.length; offset += CHUNK_SIZE) {
-                        const end = Math.min(offset + CHUNK_SIZE, rawInflateBuffer.length);
-                        const chunk = rawInflateBuffer.subarray(offset, end);
-                        rawDef.deflate(chunk, rawInflateBuffer.length <= offset + CHUNK_SIZE);
-                    }
-                    const ret = rawDef.getBuffer();
-                    rawDef.destroy();
-                    return ret;
-                },
+            inflate(rawDeflateBuffer) {
+                const rawInf = new RawInf();
+                for (let offset = 0; offset < rawDeflateBuffer.length; offset += CHUNK_SIZE) {
+                    const end = Math.min(offset + CHUNK_SIZE, rawDeflateBuffer.length);
+                    const chunk = rawDeflateBuffer.subarray(offset, end);
+                    rawInf.inflate(chunk);
+                }
+                const ret = rawInf.getBuffer();
+                rawInf.destroy();
+                return ret;
+            },
+            deflate(rawInflateBuffer) {
+                const rawDef = new RawDef();
+                for (let offset = 0; offset < rawInflateBuffer.length; offset += CHUNK_SIZE) {
+                    const end = Math.min(offset + CHUNK_SIZE, rawInflateBuffer.length);
+                    const chunk = rawInflateBuffer.subarray(offset, end);
+                    rawDef.deflate(chunk, rawInflateBuffer.length <= offset + CHUNK_SIZE);
+                }
+                const ret = rawDef.getBuffer();
+                rawDef.destroy();
+                return ret;
+            },
         }
 
         return ret;

+ 3 - 3
lib/Configuration.php

@@ -54,7 +54,7 @@ class Configuration
             'qrcode'                   => true,
             'email'                    => true,
             'icon'                     => 'identicon',
-            'cspheader'                => 'default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'unsafe-eval\'; style-src \'self\'; font-src \'self\'; frame-ancestors \'none\'; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads',
+            'cspheader'                => 'default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'wasm-unsafe-eval\'; style-src \'self\'; font-src \'self\'; frame-ancestors \'none\'; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads',
             'zerobincompatibility'     => false,
             'httpwarning'              => true,
             'compression'              => 'zlib',
@@ -106,13 +106,13 @@ class Configuration
             'js/dark-mode-switch.js' => 'sha512-CCbdHdeWDbDO7aqFFmhgnvFESzaILHbUYmbhNjTpcjyO/XYdouQ9Pw8W9rpV8oJT1TsK5FbwSHU1oazmnb7BWA==',
             'js/jquery-3.7.1.js'     => 'sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==',
             'js/kjua-0.9.0.js'       => 'sha512-CVn7af+vTMBd9RjoS4QM5fpLFEOtBCoB0zPtaqIDC7sF4F8qgUSRFQQpIyEDGsr6yrjbuOLzdf20tkHHmpaqwQ==',
-            'js/legacy.js'           => 'sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==',
+            'js/legacy.js'           => 'sha512-UxW/TOZKon83n6dk/09GsYKIyeO5LeBHokxyIq+r7KFS5KMBeIB/EM7NrkVYIezwZBaovnyNtY2d9tKFicRlXg==',
             'js/prettify.js'         => 'sha512-puO0Ogy++IoA2Pb9IjSxV1n4+kQkKXYAEUtVzfZpQepyDPyXk8hokiYDS7ybMogYlyyEIwMLpZqVhCkARQWLMg==',
             'js/privatebin.js'       => 'sha512-JUj/Sbl/bMHlIoIUT1U9e89JU33fDBxCxLSGxwwaeydBFXOBHyfdF7hwSIjgbPxb4d9CO7CSe4meouTIRMy8Vg==',
             'js/purify-3.1.7.js'     => 'sha512-LegvqULiMtOfboJZw9MpETN/b+xnLRXZI90gG7oIFHW+yAeHmKvRtEUbiMFx2WvUqQoL9XB3gwU+hWXUT0X+8A==',
             'js/rawinflate-0.3.js'   => 'sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==',
             'js/showdown-2.1.0.js'   => 'sha512-WYXZgkTR0u/Y9SVIA4nTTOih0kXMEd8RRV6MLFdL6YU8ymhR528NLlYQt1nlJQbYz4EW+ZsS0fx1awhiQJme1Q==',
-            'js/zlib-1.3.1.js'       => 'sha512-Z90oppVx/mn0DG2k9airjFVQuliELlXLeT3SRiO6MLiUSbhGlAq+UFwmYbG4i9mwW87dkG8fgJPapGwnUq7Osg==',
+            'js/zlib-1.3.1.js'       => 'sha512-5bU9IIP4PgBrOKLZvGWJD4kgfQrkTz8Z3Iqeu058mbQzW3mCumOU6M3UVbVZU9rrVoVwaW4cZK8U8h5xjF88eQ==',
         ),
     );