gornostay25 / svelte-adapter-bun

A SvelteKit adapter for Bun
MIT License
534 stars 33 forks source link

"Cross-site POST form submissions are forbidden" #54

Open LeqitDev opened 7 months ago

LeqitDev commented 7 months ago

Just encountered this error while testing my website in production.

Setup: I'm using docker with nginx proxy manager as a reverse proxy.

So i was building my multi-container through this docker-compose.yml

version: '3.9'
services:
  db:
    restart: 'always'
    build: './pocketbase'
    expose:
      - 80
    ports:
      - ${PORTDB:-8081}:80
    environment:
      FRONTEND_URL: http://web:3001
    volumes:
      - dbdata:/pb/pb_data
      - ./pocketbase/pb_migrations:/pb/pb_migrations
      - ./pocketbase/pb_hooks:/pb/pb_hooks
    networks:
      - nginx-network
  web:
    restart: 'always'
    build: 
      context: './web'
      dockerfile: 'Dockerfile'
      args:
        PUBLIC_DATABASE: ${PUBLIC_DATABASE:-https://api.domain.tld/sub}
    ports:
      - ${PORTWEB:-8080}:3001
    expose:
      - 3001
    environment:
      PORT: 3001
      PUBLIC_DATABASE: ${PUBLIC_DATABASE:-https://api.domain.tld/sub}
      ORIGIN: https://sub.domain.tld
    networks:
      - nginx-network

volumes:
  dbdata:

networks:
  nginx-network:
    name: nginx-proxy-manager_default
    external: true

With my web Dockerfile looking like this:

FROM oven/bun as builder

ARG PUBLIC_DATABASE
ENV PUBLIC_DATABASE=${PUBLIC_DATABASE}

WORKDIR /app

COPY . .
ENV ORIGIN=https://sub.domain.tld

RUN bun i
RUN bun run build

FROM oven/bun
COPY --from=builder /app/build .

ENV ORIGIN=https://sub.domain.tld

EXPOSE 3001

CMD [ "bun", "index.js" ]

I know that the ORIGIN env is set multiple times just wanted to check that it wasn't on the wrong spot.

I was also printing the url.origin in the load function in +layout.server.ts which resulted in the following output: http://sub.domain.tld

Running bun --print process.env also tried with (Bun.env) resulted in:

{
  ...,
  ORIGIN: "https://sub.domain.tld",
  ...,
}

What i discovered was that when i didnt enforce https with my reverse proxy and use the website with "http://" it just works fine but that isnt the way i think

Hope somebody can help fixing this monster that cost me more then 2 hours of trying and failing If you need some more infos just ask for it

YummYume commented 6 months ago

Hello,

I'm having the exact same issue. My configuration is very similar to yours and is also using Docker. I tried a lot of things, but only switching to the Node adapter worked. This is what I pretty much always end up doing because of a few incompatibilities that this adapter seems to have.

Here my Dockerfile if needed, I kept my original configuration but added Node with COPY (for Alpine) and changed the adapter in my svelte.config.js file.

maietta commented 4 months ago

This is how I'm getting around the issue at the moment. I don't like doing this, but it's about the only wait that doesn't involve throwing yet another server in front of the app that fixes this.

My svlete.config.js

import adapter from 'svelte-adapter-bun';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

/** @type {import('@sveltejs/kit').Config} */
const config = {
    preprocess: vitePreprocess(),

    kit: {
        adapter: adapter(),
        csrf: { // Did https://github.com/gornostay25/svelte-adapter-bun/pull/61 work? (I can't wait to find out)
            checkOrigin: false
        }
    }
};

export default config;

The server option would be to use something like this in front of your app with something like this:

// @bun
import { build_options, env, handler_default } from './build/handler.js';
import './build/mime.conf.js';

var { serve } = globalThis.Bun;
/*! MIT © Volodymyr Palamar https://github.com/gornostay25/svelte-adapter-bun */
var hostname = env('HOST', '0.0.0.0');
var port = parseInt(env('PORT', 3000));
var { httpserver, websocket } = handler_default(build_options.assets ?? true);
var serverOptions = {
    baseURI: env('ORIGIN', undefined),
    fetch: httpserver,
    hostname,
    port,
    development: env('SERVERDEV', build_options.development ?? false),
    websocket
};
websocket && (serverOptions.websocket = websocket);

console.info(`Listening on ${hostname + ':' + port}` + (websocket ? ' (Websocket)' : ''));

serve(serverOptions);

Instead of running your app directly, you'd bun server.ts instead. This in turn will run your app fixing the CORS issue.

vyconm commented 2 months ago

bump this issue still persists, might be related or fixable py this pr: #61

jack-y commented 1 month ago

Please fix this issue, it's still blocking our production release.

notramo commented 1 month ago

Just reminding everyone here that origin checking is an insufficient CSRF protection measure. It's harmful by creating a false sense of security. Origin can be spoofed, so checking it only provides partial protection, but doesn't protect against sophisticated attacks.

Feel free to set checkOrigin: false and add a CSRF token field to every form instead for proper prevention.

Edit: since #61 is merged, disabling origin checking may be not necessary anymore, but it's still an insufficient security measure, and CSRF token is still required.

jack-y commented 1 month ago

@notramo Thank you so much for this comment. For all, if needed, here is a good article by Admir Dizdar on the CSRF token and its management: What is a CSRF Token and How Does It Work?

andersmmg commented 1 month ago

I'm still getting this error with the latest version of the adapter in my SvelteKit action. It works with the node adapter

YpsilonTM commented 4 days ago

I have the same issue, currently not smart enough to fix this with a pr 😓 Has #61 fixed this issue? I see its merged, But if so can a new release be build?