1. Authentication
a. What did you struggle with when adding authorization to your back end?
I msot struggled with refactoring tests to now requrie authorization. I
had to refactor tests to setup a sample login for a certain account as
part of the before each loop. Other than that I reused ost of the flow
from the login activity and updated by db and backend and frontend schemas
to have the created by field. So addding the actual code for this was not
the hardest part of the assignment imo.
b. What did you struggle with when adding authorization to your front end?
The only challenge really was figuring out how I wanted to handle the user
login and create account flow from a design perspective as the actualy
login for detecting user login and cookies was already done in an activity
before this. Thus I realized that I just want separate forms for login and
creating a user and that I will not allow any of my edit or add or delete
book forms to be submitted when im not logged in. however the user can
still see all of those options and I was fine with that. The other tough
part about the frontend was compiling it and making sure it worked in the
new deployment process.
2. Deployment
a. What did you struggle with when deploying your app to the internet?
I mainly struggled with figuring out how to setup the pm2 and the
caddyfile. Getting the dist folder working locally worked for me almost
first try. I then realized I can simplify the build and start process with
a simple npm script abstraction. However setting up the reverse proxy on
the server to listen what I am hosting on localhost port 3000 and getting
that to persist even when I was not logged onto the machine was tricky. I
followed the instructions the professor provided by I also have to add a
new A record on Porkbun which was not in the instructions. Without this I
noticed that my site wasn't going live and it took me a while to realize
what was the root cause of that.
3. Security audit
a. If your app was vulnerable to XSS attacks, explain what you did to
mitigate them. If it wasn't, explain why.
I mitigated XSS by using React's default data binding, which sanitizes and
escapes all strings before rendering them to the DOM, preventing malicious
script injection. I also mitigated XSS at the server level using Caddy and
the express Helmet.js config.
b.If your app was vulnerable to CSRF attacks, explain what you did to
mitigate them. If it wasn't, explain why.
My application is resilient to CSRF because it utilizes JSON Web Tokens
(JWT) stored in localStorage (or SameSite cookies). Because the browser
does not automatically attach localStorage data to cross-origin requests,
a malicious site cannot forge an authenticated request on behalf of the
user.
c. If you added rate limiting with a firewall, include what commands you
ran/packages you used. If you added rate limiting to your application
code, indicate this.
I implemented application-level rate limiting using the express-rate-limit
package. To ensure accuracy while running behind a reverse proxy, I
enabled app.set('trust proxy', 1). This allows the middleware to correctly
identify and limit the origin IP address rather than the local proxy
address. Additionally, I utilized the UFW (Uncomplicated Firewall) at the
OS level to restrict incoming traffic strictly to ports 80, 443, and 22,
further reducing the server's attack surface.
d. Explain what HTTP headers you set, what they do, and why they're
useful.
To prevent MIME-type sniffing and Clickjacking, I configured these
X-Content-Type-Options: nosniff and X-Frame-Options: DENY. These headers
work in tandem to provide a multi-layered defense strategy that protects
the user's browser environment from external manipulation.
e. If you did anything else to secure your app, explain what you did and
why.
No not really, I didn't feel the need to do anything else since what we
did in terms of security felt quite exhaustive for a class assignment.