solid-start icon indicating copy to clipboard operation
solid-start copied to clipboard

Security Concern: eval-based Serialization in Seroval Breaks Strict CSP

Open amirhhashemi opened this issue 10 months ago • 8 comments

I'm not sure whether this is directly related to SolidStart, but I believe here is the best place to get the conversion going.

The issue I'm experiencing is related to the use of eval in Seroval, which I believe you use for serializing data in server functions. Use of eval is restricted for websites using a strict CSP.

There is not a viable workaround for this. Two potential workarounds are:

  1. Adding 'unsafe-eval' to the script-src directive which, as its name implies, is unsafe.
  2. Using the Trusted Types API which has limited availability.

The only Issue I found about this is Eventually drop eval? which is closed and it seems there won't be any change. In that Issue, performance is mentioned as the main reason for using eval.

I get it, you want to be fast, but being fast in this instance comes with a huge cost and that is: basically no serious project can use SolidStart. A framework shouldn't limit using a core security feature like CSP.

I'm surprised this has not come up before. I only found little information about it in Discord. So I'm not entirely sure what's going on and how this can be fixed. But I hope I get an answer here.

Thank you for reading this.

amirhhashemi avatar Feb 22 '25 16:02 amirhhashemi

SolidStart (and SolidJS) uses seroval for serializing data, but only SolidStart uses the eval part of Seroval since SolidJS uses html streaming for inserting script elements. I'm not sure if there's a workaround for eval but we needed the JS serialization format since it's a lot faster and cheaper (in terms of response size) than if we go for the JSON route (Seroval also offers that mode), which is like 100x worse in terms of perf.

lxsmnsyc avatar Feb 22 '25 18:02 lxsmnsyc

I think the OP is more questioning the rationale of sacrificing security for the sake of performance? For some, that tradeoff could be a dealbreaker.

thedanchez avatar Feb 22 '25 18:02 thedanchez

I'm obviously not an expert in this area, but I wonder if this 100x difference is a significant concern in practice. I haven't noticed if other popular frameworks require eval for serialization. So it seems JSON-based serialization is at least passable.

I'm not suggesting changing the default serialization method, but I think it would be valuable for some users to have the option to choose a slightly slower serialization method if they prioritize security over speed.

amirhhashemi avatar Feb 23 '25 06:02 amirhhashemi

turbo-stream, a Seroval-like streaming ser/de package that is used with React Router, does not use eval, and therefore performs pretty poorly: https://github.com/lxsmnsyc/seroval/pull/55/commits/b5f7bf05fe52718cb7dcae849e5ff683c06df729

XiNiHa avatar Feb 25 '25 09:02 XiNiHa

In most benchmarks, devalue performs similarly without using eval. It's slightly slower, but in a realistic scenario, it seems to be fast enough since it's used in Svelte.

Now that I have seen the benchmarks, the performance argument makes less sense to me. Honestly, I'm not convinced I'm going to feel a performance hit if SolidStart used, for example, devalue.

amirhhashemi avatar Feb 25 '25 14:02 amirhhashemi

devalue never really considered eval iirc, while seroval's prior art was an eval serde.

Performance isn't really the main concern, but the response size affects the client (the JSON print of seroval is a lot larger than it's JS output), which in turn affects client performance. In which case, creating another serialization format for the sake of response size, perf and security might be the next other option. (React does this)

I'll need to discuss this with Ryan, but for now, the current state is highly desirable.

lxsmnsyc avatar Feb 25 '25 15:02 lxsmnsyc

Yeah, flexibility for configuration in this area I think is a good compromise. Can easily keep the current behavior as the default and just provide the other methods of serialization alongside it. Hope that conversation goes well.

thedanchez avatar Feb 25 '25 15:02 thedanchez

I have the same problem. Unfortunately, using eval in Chrome extensions is very difficult. Glad to know that devalue exists; I will see how to use it.


PS: I have used sveltekit. I don't know if it uses devalue, but anyway, I didn't notice it being slow.

rxliuli avatar May 24 '25 15:05 rxliuli