oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
73.72k stars 2.72k forks source link

cookie-session session.sig isn’t created by Bun. #14113

Open bilabror opened 2 weeks ago

bilabror commented 2 weeks ago

What version of Bun is running?

1.1.29+6d43b3662

What platform is your computer?

Darwin 24.0.0 arm64 arm

What steps can reproduce the bug?

here is my express settings

const app = express();
app.use(express.json());
app.use(cors());
app.use(helmet({ contentSecurityPolicy: false, crossOriginEmbedderPolicy: false }));
app.use(
  cookieSession({
    name: 'session',
    keys: [config.sessionKey1, config.sessionKey2],
    maxAge: 4 * 60 * 60 * 1000,
    httpOnly: true,
    secure: config.isProd || config.isStag,
    sameSite: 'strict',
  })
);

here is how i set the session

const encryptedArgs = Crypto.encrypt(args);
req.session![SS_SESSION_NAME] = encryptedArgs;

here is my encrypt code

const key = Buffer.from(config.encryptionKey, 'base64');
const algorithm = 'aes-256-gcm';
const encoding = 'base64';

const encrypt(data: unknown) {
  const iv = crypto.randomBytes(12);
  const cipher = crypto.createCipheriv(algorithm, key, iv);
  let encrypted = cipher.update(JSON.stringify(data), 'utf8', encoding);
  encrypted += cipher.final(encoding);
  const authTag = cipher.getAuthTag().toString(encoding);
  return `${encrypted}.${iv.toString(encoding)}.${authTag}`;
}

my nodemon settings

{
  "watch": ["src/**/*", "nodemon.json"],
  "exec": "bun src/index.ts",
  "ignore": ["node_modules/"],
  "ext": "graphql,ts,js,json"
}

how i run project

bun run dev

What is the expected behavior?

The session.sig cookie should be created automatically

What do you see instead?

Use ts-node : session.sig was created.

Screenshot 2024-09-23 at 22 19 32

Use bun : session.sig was not created.

Screenshot 2024-09-23 at 22 34 58

Additional information

No response

RiskyMH commented 1 day ago

I have made this more minimal:

const express = require('express');
var http = require('http')

const app = express();

app.get('/', (req, res) => {
    const date = Date.now()

    http.OutgoingMessage.prototype.setHeader.call(res, 'Set-Cookie', [
        `a=a${date}; path=/;`,
        `ab=b${date}; path=/;`
    ]);
    res.json({ message: 'Session set successfully' });
});

const port = 3001;
app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});

I have no idea why http.OutgoingMessage.prototype.setHeader.call is being weird and only cares about first element in bun

RiskyMH commented 1 day ago

made more minimal again:

const http = require('http');

const res = new http.OutgoingMessage();
res.setHeader("myheader", ["first", "second"]);

console.log(res.getHeaders())

Node returns:

[Object: null prototype] { myheader: [ 'first', 'second' ] }

Bun returns:

{  myheader: "first,second" }

Notice how Bun returns the header value as a single string ("first,second") instead of an array unlike Node.js.


This behavior occurs because Bun uses Headers, while Node.js has its own implementation.

The difference happens because Bun uses the new Headers constructor in res.setHeader, which automatically joins list values into a single string. However Node.js, uses a different internal implementation for res.setHeader, which preserves an array for headers with multiple values.

bilabror commented 18 hours ago

@RiskyMH Thank you for confirming that it is a bug from Bun.