Four Rules for Accepting Secure User Uploads to a PostgresSQL Database (MVC) | Dear Coder
Published: 2021-05-10 13:01:14

Dear Coder,

In my last letter, I wrote about how I used enums to populate a dropdown list of genres from which a user can select to categorize their webtoons in the ToonSpace database.

But what about the webtoons?

I haven't allowed the user to upload their own files to the database yet, and that's for good reason: I'm scared.

You should be too.

Okay, maybe I'm being a little dramatic. But only a little.

Whenever you're allowing users to upload to your database, security should be your highest concern. For our purposes, that means two things: safeguard your database from insecure uploads and prompt the user to register an account before they are able to upload anything to the database.

We'll discuss registration at a later date, but that's the subject of a different letter.

For now, let's dig into the four requirements for accepting secure image uploads from the user.

# The Rules

### Rule Number One: Do Not Accept the filename the User Gives You

You must change the name during the upload process. This prevents the user from wittingly or unwittingly using common problematic symbols in directories and filenames like spaces and slashes from causing problems.

I must change the name during the upload process.

### Rule Number Two: Do Not Accept the Pathing that the User Gives You

A user might try to upload and wittingly or unwittingly upload a file to a folder that I don't want them to access. This could cause all kinds of problems if I need to retrieve the file path.


### Rule Number Three: Investigate the Content of the User's Upload

Just because a user uploads a file with a "png" extension doesn't necessarily mean the file is actually a png image. I need to safeguard my database from accepting unwanted file types.

### Rule Number Four: Turn Off Execution Rights in the Upload Folder

This one is the most critical because I don't want my user to be able to execute any impermissible operations that could damage or otherwise maliciously attack my database or application. The user should not be able to execute anything when they upload.


# The Solution

I've considered three ways I can allow the user to upload their images to the database, each with their own security concerns. I'll outline them to you and tell you which I eventually settled on.

### Method One: Allow the User to Upload Directly to the Server

I could create an image folder in the wwwroot directory and programatically direct the user to upload to it, but this method doesn't scale well, and requires a lot of extra code to satisfy my four rules for secure uploads.

### Method Two: Use a Third-Party Cloud Service to Handle the Upload

This is the most recent method for handling a secure upload, and it comes with plenty of advantages (namely ease, speed, and peace of mind),  but third-party hosting with Azure or Amazon can also cost more money than a developer is willing to pay for a small project.

### Method Three: Upload the Image and Store them as Byte Arrays

This method is the simplest and most ideal because I don't need to use the name or path a user gives me, and the file cannot execute. I'm just breaking down the image into a stream of bytes and decoding it again to display it.

However, I still have to investigate the content of the file to verify that it's actually an image file.

I can accomplish all of these goals by creating an interface and basic image service to handle user uploads.

But again, dearest Coder, coding and implementing my image service will be the subject of my next letter.

Until next time, godspeed in your keystrokes.

Clickity Clacks,

Kasey