Next's Server Actions Might Not Be That Safe...
📘 T3 Stack Tutorial: 1017897100294.gumroad.com/l/j...
🤖 SaaS I'm Building: www.icongeneratorai.com/
💬 Discord: / discord
🔔 Newsletter: newsletter.webdevcody.com/
📁 GitHub: github.com/webdevcody
📺 Twitch: / webdevcody
🤖 Website: webdevcody.com
🐦 Twitter: / webdevcody
Пікірлер: 90
This is another reason why a strong split between front and backend code is useful
I’ve always placed this in mind. When a new solution is introduced to solve problem(s), somehow, it introduces a new problem or vulnerability while stopping one. That’s nature for me 😅
Keep ‘em coming Cody! You’re doing so well! I’m very proud of you 😘
@WebDevCody
Жыл бұрын
Thank you beautiful! 😘
I'm really not a fan of this direction in the first place. Next is trying so hard to blur the lines of the client and server paradigms that they are obfuscating the actual inner workings of the framework. This is going to make security vulnerabilities easier to create by accident and harder to spot :(
@IvanKleshnin
6 ай бұрын
They are trying to pull everything under their umbrella: CSS, fonts, API, animation... everything, so you couldn't even think of getting rid of NextJS. And at some point, I imagine, NextJS will become Vercel-only. So every web developer would pay them. Sounds like a nice plan.
I'm glad someone finally took the time to actually run the tweeted code to understand it, besides only stating "I don't fully understand what's going on here..."! Thank you. I believe the risk is not really on using alpha features. I believe that the bigger risk is using sample code from someone else without putting the effort to actually understand it. Good job!
@WebDevCody
Жыл бұрын
The risk is not understanding how any of this works and you accidentally leak your db secrets and your company’s reputation is ruined because everyone’s data is leaked
@lpanebr
Жыл бұрын
@@WebDevCody exactly. And this can happen with the most stable features if the developer does not put the effort in understanding them.
All the seniors will have fun reviewing code from juniors with this features.
@ehvenga
Жыл бұрын
some are still stuck with classbased react and approving bs code without understanding.
@codedusting
Жыл бұрын
That's why I have blocked this for another 6 months for the patterns to emerge and then for juniors and myself to learn (otherwise what will I even review 😂) and then we start to this architecture.
@parlor3115
Жыл бұрын
You mean block juniors from using it all together. I get anxiety just thinking about this feature tbh
The actions are currently in Alpha so their security will be improved in the future. Currently, using it in production is not only shooting yourself in the foot, but blowing the entire leg off. And I do think that separating the actions in a different file is better anyway. Helps with security + separation of concerns.
@cerstvemlieko
7 ай бұрын
Well before react, styles, markup and js logic was 3 different files (separation of concerns). JSX components meant you do all of the 3 together, and separate concerns on the component level.
Appreciate you making a vid explaining this cuz I also didn't know what people were talking about in twitter
Nice video, will include it in tomorrow's newsletter 👌
Tom Sherman! What a legend
@tom-sherman
Жыл бұрын
Thicken Nugget approved
@Holyflare
Жыл бұрын
@@tom-sherman The man, the myth, the legend!
With more power, comes more responsibility
This is basically the equivalent of doing const secret = fetch(/my/secret) in your react and that result gets bundled with the frontend. Closures are important in js for this and many other reasons.
Scary stuff 🫣
1:30 curios how you toggle between screens here without showing the app switcher. Are you doing that with a specific program or utility or is that being done some how with OBS?
@WebDevCody
Жыл бұрын
I three finger swipe on max using virtual desktops
Thanks for this!
it's really simple: every server action call is a separate http request that doesn't have access to any state of the server (assuming you are running serverless/edge, and it probably treats it independently even if you have a dedicated machine). Anything involved in a closure is treated like an argument. imo, it's better to explicitly pass them as arguments instead of hiding it behind a closure.
interesting, aside from any issues that come from using server actions in alpha, what will t3 stack look like? will trpc even be needed once server actions become the norm? atleast not for mutations of any kind 🤔
@WebDevCody
Жыл бұрын
Idk if tRPc will be as useful. It was basically a way to get fully typesafe code, but with server actions we get that already
Excellent video
I don't get it. Why would anyone place it within the component/closure not in the server function? Is there a use case for doing this?
@reiito8727
Жыл бұрын
From what i get, is that you are right. No one should place it within the component and the right thing to do is to put it directly in the server function as he showed in the end of the video. The purpose of this video is just to warn people that if you put it inside the compoent function things can be leaked. This is just a video to prevent a flaw that have been fund on this alpha.
@MrBrandenS
Жыл бұрын
People make mistakes and this is a mistake that shouldn't expose serious credentials. Let's hope it gets fixed or a warning come beta time.
@avi7278
Жыл бұрын
@@MrBrandenS why should this be fixed. There are lots of ways to leak your keys. Why should this be treated any differently? Anyone making this mistake is probably not working on a serious app anyway.
@WebDevCody
Жыл бұрын
@@avi7278 elitism much? This is a simple mistake that could cause leaking a variable you think should only live on the server but is sent to the client. It’s much harder to make this mistake with a rest api because the api only returns what your explicitly specify as a return value. Next is exposing variables you never explicitly expose
color theme?
when you define your screts inside the function they don't appear inside the payload if that means they are not sent to the client why wouldn't you define the secrets inside server actions ?
@WebDevCody
Жыл бұрын
They should probably only be defined in the server actions. This is just an example of what can go wrong if you’re not careful
Ty
I am a bit confused... how is the secret being passed to the backend in the first 'safe' example?
@arpadgabor
Жыл бұрын
it's state that is serialized. basically the Home component is async, so it loads up on the server and renders some html. The secret is loaded too, but that secret is basically some state of your component that, because it's declared and assigned there, next will assume it will be needed in the rendering process and possibly in the client as well, so it's probably stored as a json string somewhere in the serialized response (i'd suggest always checking the actual rendered html in the browser to make sure you're not leaking anything)
@bigmistqke
Жыл бұрын
@@arpadgabor oo I see, didn't notice the async... Mm yes this does seem a bit error prone. But as the secret is in the serialized state in the first exampe, wouldn't that mean the secret is also visible there? It's not encrypted or anything right?
lets goooooooooo
Is server action still unsafe to use in production?
@WebDevCody
11 ай бұрын
It’s still alpha, so 🤷♂️
Just a note. Those aren’t the stable server components. They are server actions running inside client components and it’s in alpha still. If that becomes stable it would be cool.
I just can't see why someone would connect to a DB or do complex stuff with this server actions thing. We are already seeing some bad things about serverless, why should we go deeper?
@WebDevCody
Жыл бұрын
Not sure what you mean. How else will you store data when someone submits a form?
ive been saying this for a while injecting sql into components without a safe middleware is just asking for problems
Am I the only one who thinks that we don't need 'server actions'? Like seriously, what's wrong good ole JSON? I get that you can't really upload files with JSON, but with Next those files aren't persisted anyways... Plus, we figured this out with the whole pre-signed URLs thing.
Imo all of these alpha and beta features seriously need to be removed from the main release package and instead be added to packages named ”13.4.0-beta-{major}.{minor}" or something so that people aren't using these features in production unless the package version explicitly states that it's the beta/alpha version. Having these in the main package seems really weird to me.
@WebDevCody
Жыл бұрын
I do agree, if it’s alpha do not put in the main release. In their defense you can not uses these features unless you set a flag to true in the next config, so it’s fine imo
If you are building a long-term project, PLEASE go with an Express RESTful API + React SPA (Vite swc) + Zustand + React-Query. This stack is tried and true and will not screw you over. Don't chase the fancy new thing. Go for stability and reliability!
@LEDsellers
Жыл бұрын
or T3 stack + supabase
Not that scary imo. If you’re accessing a secret in code that’s being returned to the client (eg JSX) you’re just asking for it
@WebDevCody
Жыл бұрын
What code is being returned to the client? The server action is ran on the server, not the client.
@Reohh
Жыл бұрын
You are fetching the secret inside your Home component, which means that code is being run on both the server AND the client. This being called a security vulnerability is just a failure to understand how Next executes your component code. Which don’t get me wrong, is perfectly valid criticism of Next but has nothing to do with Server Actions.
@WebDevCody
Жыл бұрын
@@Reohh the component is a server rendered component, the secret does not get sent to the frontend at all. The server component is built to run the jsx on the backend so it only sends the html. The hydration part only happens with client components
@b_two
Жыл бұрын
@@WebDevCody put it this way: if your `getSecret` was implemented as `return Math.random()` and you called `getSecret` at the time the server component was served, even if the server action is only being executed on the server, the only way for your server action to be guaranteed to have the same "secret" you randomly generated at serve-time is by having your server component communicate the secret to the browser and the browser to the server action. you can't expect the closure's state (ie the `const secret`) to be preserved across both the synchronously served server component and the asynchronously executed server action *_unless_* you allow the browser, being the intermediary between the serving of the server component and executing of the server action, to preserve that state for you (eg what if you have a distributed architecture where the server component is served in the US but when the user calls the server action, they're in Europe?) the fix for this is to not allow secrets to cross "runtime" boundaries. we have several different runtime contexts: server (at server component serve-time), browser, and server action (at server-action execution time). when you try to create a secret (or any value for that matter) in one context but access it in another, that secret necessarily must be exposed, at least to the network communications. when I think about it this way, the answer to this is clearly to keep the "const secret = await getSecret" _inside_ the server action
This is a foot gun, but its not at all surprising or counterintuitive. If you remove the server action it's so obvious you are pulling a secret into a component! Why would you expect that secret to ever be excluded from client code if you did this? I guess the point is that you wouldn't do it on purpose, but it would be a careless mistake.
@WebDevCody
Жыл бұрын
Idk if you fetch the secret in the server component, it won’t be sent to the frontend from what I can tell. The fact that you define the server action as an inner function causes it to be exposed. That’s not intuitive
@barefootfunk
Жыл бұрын
@@WebDevCody oooooooooooooooooooooh Im dead wrong. I thought this was a client component. Yup you're 100% right this is super unintuitive and dangerous.
This is what u should not do using server actions. Its not much of a vulnerability!! U can always see the payload ig
an eslint rule is going to be necessary if they don't change this
@WebDevCody
Жыл бұрын
Absolutely, or force server actions to be separate files or something
It's far from production ready
@WebDevCody
Жыл бұрын
Yeah, it’s in alpha
onest
I think they jumped the gun on releasing all of this... NextJS releasing with a canary version of React? IDK...
@WebDevCody
Жыл бұрын
It’s alpha, so it’s fine, just don’t use it in prod yet
@frenchButt44
Жыл бұрын
@@WebDevCody Tagged alpha for a reason.
@WebDevCody
Жыл бұрын
@@frenchButt44 yup mentioned in video
twoest
Guys any other good KZreadrs like Cody and theo to watch 🎉🎉🎉
This is alpha, come on. Let's not just talk bad things about Next just because of an alpha feature
@WebDevCody
Жыл бұрын
Why is an alpha feature in a production version release?
@lucas.p.f
Жыл бұрын
@@WebDevCody that's their model. It is an opt-in feature that you can enable at any time, in any project to experiment it. No need to switch branches or all that fancy stuff, just change the next config and you can experiment every testing feature
@WebDevCody
Жыл бұрын
@@lucas.p.f it’s at least ok to point it out so it can be improved, is it not?
@lucas.p.f
Жыл бұрын
@@WebDevCody of course! My comment was not directed at you in any way, as you were only helping. It was directed to some people that is hating on Vercel for quite some time and using this as an argument to trash talk about them
Angular is the matured professional framework, it has simple syntax than react. React is hard to understand, the DX of react is horrible. React is a child play. When it comes to serious enterprise app development, Angular comes in glory. React has brought shame to JavaScript community by making web development unnecessarily complicated.
@eduardoromaguera9707
Жыл бұрын
What are you talking about 😂?
@Euquila
Жыл бұрын
This is completely untrue and the data does not support your statement
@Dev-Siri
Жыл бұрын
Everyone, just ignore this person. I have seen this exact account under many React videos. Don't listen to him, he is not here to make the web better, he is only here to trash on libraries/frameworks like React & Svelte and blame them for the web being bad.
@eduardoromaguera9707
Жыл бұрын
@@Dev-Siri just look at his account name, lol
@Dev-Siri
Жыл бұрын
@@eduardoromaguera9707 what is so special about the name?
The first example you show also leaks btw! action={doSomething(secret)} is still closing on secret.
@WebDevCody
Жыл бұрын
I’ll retest but I didn’t find the secret in any of the frontend html or JavaScript when I did that approach, because react will run through your component once and evaluate everything and not send it to the server. It’s the same reason why we can do prisma or sql queries inside the server render component and not have it leak secrets.
@hhueston
Жыл бұрын
@@WebDevCody it is leaking. You’re not using the variable in the function - hence it is not included in the rendered form. If you ‘console.log(secret)’ inside ‘doSomething’ (1:24) you will see that it leaks. This has nothing to do with sql or prisma, it’s to do with closures.
@WebDevCody
Жыл бұрын
@@hhueston leaked where?
@hhueston
Жыл бұрын
Your secret will be injected into the html form as a hidden input