'Ensuring sensitive code is run only server-side with NextJS, where can such code be ran from?

I'm learning NextJS and I'm trying to determine how to layout my project with a clean architecture that's also secure. However, I'm not sure about where to store code that contains potentially sensitive data (ie. connections to databases, accessing the file system, etc.). I've read the docs, but I'm still unsure about this one issue.

In my project layout, I have 2 directories that that relate to this problem: a top level /lib I added and the /pages/api directory that comes baked into every NextJS project.

To my understanding /pages/api NEVER sees the client-side and is hence safe for sensitive code. It should only be used as somewhere to do post, patch, delete, etc. operations. An example of where /pages/api is used would be when you make a post request to the server from a form. You can call an api from this route from ANYWHERE, for example: a form component, the /lib folder, a page in /pages, an external 3rd party api - wherever.

On the other hand, the top level /lib directory, is a place for boilerplate code, carrying out tedious operations such as sorting blog posts into alphabetical order, doing math computations, etc. that's not necessarily "secret" or sensitive - just long and annoying code. The /lib directory will ALWAYS be seen by the client-side - even if it's code that's only called by a server-side method such as getStaticProps().

In short, anything remotely sensitive should always be made as a post, patch, put etc. request to the /pages/api directory, and any long/tedious code that's not sensitive should be refactored to the /lib directory.

Do I have this all right?



Solution 1:[1]

You can do you sensitive stuff in api routes, getServerSideProps, getStaticProps. None of your code in /lib will be seen by the client unless your page actually imports code from there.

Since you were talking about db connections, it's very unlikely you'd be able to connect to your db from the browser by accident. Almost none of the libraries used to connect to db won't work from the browser and you also can only access env variables that start with NEXT_PUBLIC_ on the client.

You also need to keep in mind that every file under /api will be an api route, so you should put your helper files inside /lib instead of /api. If you put them under the /api that could lead to security vulnerabilities since anyone can trigger the default exported function of the files under /api.

If you for some reason need to be absolutely certain that some code isn't bundled to the files that clients will load even if you by accidentally to import it, it can be done with custom webpack config. Note that I'd only look into this option if the code in itself is very sensitive. As in that someone being able to read the code would lead to consequences. Not talking about code doing db queries or anything like that, even if you imported them by accident to client bundles, it wouldn't pose any threat as the client cannot connect to your database.

Solution 2:[2]

The /pages/api and lib should be safe enough. These files are not exposed by Next.js. Next.js exposes the files in your public folder. What you have said about the lib is correct. It is just a folder that can be used to house helper functions that you can reuse within your code.

getStaticProps only runs on the server-side. It will never run on the client-side. It won’t even be included in the JS bundle for the browser. That means you can write code such as direct database queries without them being sent to browser. You can safely make your calls with this function.

There is a tool you can use to validate that code in getStaticProps only runs serverside and never gets exposed client side. Link to tool: https://next-code-elimination.vercel.app/

Solution 3:[3]

I've used /lib in much the same way you intend on a number of Next projects and haven't had any problems. As others have mentioned, if you are server-side generating everything with getStaticProps, you should be fine.

One thing I've run into is client and server side getting out of sync between the actual client and server (especially with iFrame or data that gets manipulated after a fetch). That doesn't cause security issues but it is something to think through architecturally. Next exposes its router if you need to sync effects to URL changes.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Gideon Bamuleseyo
Solution 3