tus / tus-js-client

A pure JavaScript client for the tus resumable upload protocol
https://tus.io/
MIT License
2.11k stars 316 forks source link

Issue with tus.upload Redirecting from HTTPS to HTTP, Causing an Error #711

Closed likecrazy closed 2 months ago

likecrazy commented 2 months ago

Question The issue is as described in the title. When attempting to upload files from the same or a different domain, the file transfer works fine in local and HTTP environments. However, when using HTTPS, the upload request is redirected to HTTP, causing an error. httpStack.js:64 Mixed Content: The page at 'https://mydomain.io/pop' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://mydomain.io/f/files/c4b535d051e35cfeb87e000286adbf39'. This request has been blocked; the content must be served over HTTPS.

Below is the relevant portion of my Nginx configuration, where only domain-related information has been modified. server { listen 80; server_name mydomain.io; client_max_body_size 10240m; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name mydomain.io; client_max_body_size 10240m; ssl_certificate /etc/ssl/certs/star__io.crt; ssl_certificate_key /etc/ssl/private/star__io.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; location / { proxy_pass http://$backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }

Here is the code related to @tus/server and @tus/file-store in my Node.js application:

`const { Server: TusServer, EVENTS } = require('@tus/server'); const { FileStore } = require('@tus/file-store');

const tusServer = new TusServer({ path: '/f/files', datastore: new FileStore({ directory: uploadPath, maxSize: 10 1024 1024 * 1024 // 10GB }), maxUploadSize: parseInt(process.env.TUS_MAX_UPLOAD_SIZE, 10) || Infinity, chunkedTransferDecoding: process.env.TUS_CHUNKED_TRANSFER_DECODING === 'true' || false, threadLocalCache: process.env.TUS_THREAD_LOCAL_CACHE === 'true' || false, });

router.all('/files', (req, res) => { tusServer.handle(req, res); });

router.all('/files/*', (req, res) => { console.log(Received request: ${req.method} ${req.originalUrl}); tusServer.handle(req, res); });

tusServer.on(EVENTS.POST_FINISH, async (req, res, upload) => { console.log("-----------------------------------Upload complete event triggered"); try {


 } catch (error) {
        console.error("Error during POST_FINISH event processing: ", error);
    }
});`

And here is the tus.upload code:

`<script src="https://cdn.jsdelivr.net/npm/tus-js-client@4.1.0/dist/tus.min.js"></script>

Array.from(files).forEach(file => {
    const fileSize = file.size;
    let upload = new tus.Upload(file, {
        endpoint: 'https://mydomain.io/f/files',
        metadata: {
            filename: file.name,
            filetype: file.type,
            filesize: fileSize.toString()
        },
        retryDelays: [0, 1000, 3000, 5000],
        onError: function (error) {
            console.log('Failed because: ' + error);
        },
        onProgress: function (bytesUploaded, bytesTotal) {
            const percentage = (bytesUploaded / bytesTotal * 100).toFixed(2);
            progressBar.style.width = `${percentage}%`;
            progressBar.setAttribute('aria-valuenow', percentage);
            progressBar.innerHTML = `${percentage}%`;
        },
        onSuccess: async function () {
            // Success logic
        }
    });

    upload.start();
});`

Additionally, the upload works correctly when sending to https://master.tus.io/files/.
**Setup details**

Runtime Environment: ubuntu 22.04, Chrome, Node.js 20.17.0, Express.js, EJS
Used tus-js-client Version: 4.1.0
Used tus Server Software: @tus/file-store 1.4.0, @tus/server 1.7.0

I apologize for any formatting issues; I'm still getting the hang of using GitHub.
likecrazy commented 2 months ago

I found the reason for the error. During the merge process, a coworker made changes to the file settings where the meta tags are stored. <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />

Acconut commented 2 months ago

I think this is caused by not setting the respectForwardedHeaders in tus-node-server: https://github.com/tus/tus-node-server/tree/main/packages/server#example-use-with-nginx

Using the meta tag just covers the symptoms (insecure requests) instead of addressing the root cause (why is tus-node-server returning insecure URLs)?

likecrazy commented 2 months ago

However, I had already configured it before discovering that the meta code had been modified, but that solution didn't work. Does it need to be used together with the meta code?

Acconut commented 2 months ago

Using Content-Security-Policy: upgrade-insecure-requests is not necessary (neither via the meta tag or as a HTTP header) to get tus uploads working if the tus server and proxy are configured properly.