How to ACTUALLY Secure Your API (5 Steps)

Поделиться
HTML-код
  • Опубликовано: 19 июн 2024
  • There are so many opinions when it comes to API route security. Which do you listen to? How can you avoid data leaks or unauthorized API access? Here are my 5 steps for writing high-quality, secure API endpoints.
    -- links
    Discord: / discord
    My GitHub: github.com/joschan21
    Thanks for the video inspiration: / csaba_kissi
  • НаукаНаука

Комментарии • 95

  • @hayveno
    @hayveno 11 месяцев назад +1

    Working on a backend project, and all checked ✅
    Great video 👏🏾

  • @Casal0x
    @Casal0x 11 месяцев назад

    I great that you mention it, Errors is something no one makes tutorials or mention as something important.

  • @smotch7533
    @smotch7533 11 месяцев назад +1

    I like the bg change for every section, nice touch.

  • @CallousCoder
    @CallousCoder 10 месяцев назад +5

    Very good, you covered all the required bases. What you however should arguable always do, is put your APIs behind an API gateway (or reverse proxy) and let that throttle the responses. That way you don’t need to load your services with throttling code, which is not their primary function. You can declaratively manage the rates on a centralized point based on policies ranging from roles to ip networks. As you will not want to limit API speeds from your back office for example.
    Also an API gateway (reverse proxy) can be a termination point for TLS, although you should have imo always TLS also on your API as long as you automatically manage the certificates so that they are automatically refreshed when it’s time.
    And also your API should authenticate itself with service principle or manage identity. And in our industries we even do not allow interpreted languages because we want to be able to sign the runtime that is statically linked so nobody can sneakily change out the service or a library and exfiltrate data. Our custom API gateway actually checks the signature of the binary everything the API refreshes its access token or requests an access token. If it doesn’t match with what we told the api gateway it should be it won’t start. And those signatures we put in a keyvault that the API gateway may read.

    • @rembautimes8808
      @rembautimes8808 4 месяца назад

      @CallousCoder very good suggestion and value add to this excellent content . Hope there are more videos on this

  • @ylaguardia
    @ylaguardia 11 месяцев назад +3

    Great video, Josh! I do all of that, but for rate limiting I’ve never used Upstash. Do you have a video using that in one of your projects so I can check it out?

  • @leandroloriato
    @leandroloriato 10 месяцев назад

    Hi Josh, nice video! Love your channel, always bring relevant content! Could you please expand a little more on some of the steps, specially auth/authorization and rate limiting? It would be very nice if you brought some example code in github, good patterns, useful libraries, caveats, etc. Thank you so much for your work!

  • @kiddasneve1677
    @kiddasneve1677 11 месяцев назад +18

    i also like to use an application token to my back-end systems, which i use to allow only my front-end client to access by registering the same application token on environment variables, then i pass this app token in request headers, this way only my applications can make requests on the server

    • @joshtriedcoding
      @joshtriedcoding  11 месяцев назад +9

      Smart approach, respect if you came up w/ that yourself

    • @hago7568
      @hago7568 11 месяцев назад +2

      I have seen an api where they use a cookie they send down and a frequently changing not displayed html element to prevent spamming the api - at the end of the day - just use puppeteer and dom-parser and you can circumvent it all

    • @arden6725
      @arden6725 11 месяцев назад +7

      What's stopping a malicious user from harvesting the token from your frontend?

    • @kiddasneve1677
      @kiddasneve1677 11 месяцев назад

      ​@@arden6725 onboardbase can avoid this situation, which i personally use to store secret keys instead .env in production

  • @gr8tbigtreehugger
    @gr8tbigtreehugger 11 месяцев назад

    Many thanks for these tips! Wondering how this works in nextjs? Also an idea for a vid: arm wrestling dates and timezones due to passing dates between client and server components. My data is in UTC in my db but stuff like 'Today" for the client means something different for db calls than on the server. Love your channel!

  • @soundsandstills
    @soundsandstills 11 месяцев назад +5

    Great video. Could you do a video on really thorough error handling in typescript. It would be great to include a simple try catch, and something more complex where there are multiple async steps taking place. Perhaps even including utility functions and where you would put the try catch and why. I think this is a hard thing to do really well.

    • @ness-ee
      @ness-ee 9 месяцев назад

      What I do as a FED: If you have a function that makes the request you put the try catch in the function (might be a store action) that uses it. If you’ve made a factory to make your requests and store the results, then you put the try catch in that factory and use the catch block to call your error reducer/mutator in your store. Here you rely on store state to let your UI know there’s an error. Typically the store factory will put loading, response and error into the state for the UI to pick up.
      Where it can get complicated is when you need to bubble errors up to another try catch… and it’s only complicated because then you might lose track of errors. Let’s imagine that our factory also bubbles errors as well as calling the error reducer/mutator. In this case you need a try catch in your action. I’m trying to think of a use case for doing this but actually there isn’t one. You want your actions to be single responsibility. So, for example, if you wanted to add monitoring to your application and ping an endpoint on every api error from the FE, put a callback in your factory’s catch block and not in the action. It’s important to make it a callback to separate the concerns of the store factory and how the application uses it.

  • @codinginflow
    @codinginflow 11 месяцев назад

    Good summary. I'm doing all of the same things 👍

  • @webber5629
    @webber5629 11 месяцев назад +1

    I would love to see a full video of protecting API as you said.

  • @user-gm3lg8gp3m
    @user-gm3lg8gp3m 11 месяцев назад

    This is very useful. Thanks.

  • @frankdavidaddae8397
    @frankdavidaddae8397 11 месяцев назад

    Hi @joshtriedcoding, thanks for the insight. I really appreciate.
    I have a little request, are you able to make a video where you build a demo API that show case the things you’ve talked about here. I would really love to get a bit more clarity on that.
    Thanks in advance.

  • @owenwexler7214
    @owenwexler7214 11 месяцев назад +23

    Big part of input validation that was left out of this is protecting against SQL injection if using a SQL db, which is likely. Always at the very least use something like Pg with parameterized queries if not using an ORM.
    Very good overview otherwise.

    • @skateboarderlucc
      @skateboarderlucc 11 месяцев назад +4

      And for god sakes, if an npm package is being called as part of the middleware before the request is responded to, please verify if the package does not have any CVEs associated with it. The amount of compromised npm packages that receive thousands of downloads per week are numerous. just my 2 cents.

  • @DezZolation
    @DezZolation 11 месяцев назад +21

    Great stuff as always! Little take from me: I'm of the opinion that one should never deliberatly throw a 500. A 500 to me indicates an unhandled exception that a developer always needs to look at :) when it appears so it doesn't make sense to throw it if it can be helped. There are always 4xx alternatives.

    • @joshtriedcoding
      @joshtriedcoding  11 месяцев назад +2

      Interesting take, thanks for sharing!

    • @mateja176
      @mateja176 11 месяцев назад

      In a theoretical situation where you don’t know whether the error is request related or an internal server error, it might make sense to throw a 500 error. In practice you should always be able to verify whether the request is malformed.

    • @JohnDoe-ji1zv
      @JohnDoe-ji1zv 10 месяцев назад

      500 is thrown when UNEXPECTED error is happened. You are rethrowing the error yourself because there would be a log message and also you need to make sure that nothing is leaked when unexpected error happened. So it’s normal to do that

    • @klicer3068
      @klicer3068 9 месяцев назад

      4xx for bad request, 5xx for server error where something went wrong

  • @joaomaia9140
    @joaomaia9140 11 месяцев назад +1

    Congratulations on the video ! Can you do a tutorial on this topic?

  • @vinaymama
    @vinaymama 11 месяцев назад

    Super useful...
    Thanku Josh

  • @kobiowuquadri9458
    @kobiowuquadri9458 2 месяца назад

    Thank you, josh

  • @a.perkemantus
    @a.perkemantus 11 месяцев назад

    Great video!

  • @danielgruner
    @danielgruner 8 месяцев назад

    I really like this video and also the discussion in the comments as it goes far beyond the typical videos on APIs. They’re mostly about how to develop but not how to secure APIs.
    One question about input validation. I validate user input with zod but strings mostly only with z.string(). I don’t use any further regex validation or so. I use prisma as an ORM and I currently “trust” Prisma to handle input strings in a secure manner. I haven’t found any information if Prisma does so or not and I am a little bit lost. 😅 Should I validate my input strings even more (e.g using regex?) or should I trust Prisma ORM? 🎉

  • @jjrise
    @jjrise 11 месяцев назад

    Awesome video

  • @AdamGweleg
    @AdamGweleg 11 месяцев назад

    Love ur videos ❤

  • @pratikbankar4757
    @pratikbankar4757 11 месяцев назад +9

    I hope you make a complete tutorial on this steps.

  • @buddy.abc123
    @buddy.abc123 11 месяцев назад

    Another awesome video man, thanks! I was hoping you would touch on CSRF too

    • @joshtriedcoding
      @joshtriedcoding  11 месяцев назад +2

      I decided to not touch on specific vulnerabilities because they are so dependent on your use case. If I touched on CSRF, why not SSFR, various injections, and so on, y'know. A separate video on those would be cool tho!

    • @buddy.abc123
      @buddy.abc123 11 месяцев назад

      @@joshtriedcoding gotcha!

  • @filip_wojda
    @filip_wojda 3 месяца назад

    great video

  • @Ultrajuiced
    @Ultrajuiced 10 месяцев назад

    Input validation is not only important for the sake of security but also for not breaking your app in development.
    It might always happen that accidentally malformed or erroneous data ends up in your database in the worst case taking down the whole app,
    so you waste time finding that data.
    If you do it properly right from the start you are protected against that _plus_ against malicious requests.

  • @buddhaFC
    @buddhaFC 11 месяцев назад

    Awesome 👍

  • @Wakkyguy
    @Wakkyguy 11 месяцев назад +1

    Please make a video on "How to securely handle environment variables in frontend?"

  • @kalpadhwaryu7929
    @kalpadhwaryu7929 11 месяцев назад +2

    Do you mind making a video explaining these steps by creating an API?

  • @xdarrenx
    @xdarrenx 11 месяцев назад +3

    I love token based rate limiting, because u can separate time from attempts. Example, loging route 3 tokens for 60 minutes to stop brute force, but for another end point, 50 tokens per minute, so that way legit users can do a big paginated request in high speed once, but not repeatedly to not overload

    • @skateboarderlucc
      @skateboarderlucc 11 месяцев назад

      great approach imo. Attacks can take place in slow motion.

  • @rogueturnip
    @rogueturnip 11 месяцев назад

    What sort of performance impact does the API get by adding a call out to do the rate limiting checks? If you are checking tokens, a session cookie and rate limit could that impact the API performance enough that it's noticeable?

    • @7thAttempt
      @7thAttempt 10 месяцев назад

      That entirely depends on the logic that's implementing the rate limiting checks ... It's the cost of doing business. If you removed all 5 suggestions your API would be as fast as possible, but at what cost. Implement best practices, draw a line under it, make them non-negotiable. Move on.

  • @ekchills6948
    @ekchills6948 11 месяцев назад

    Hi Josh! Please I'm confused about the session token and jwt can you please shed more light. The whole Auth stuff confuses me

  • @lifesexpression5168
    @lifesexpression5168 7 месяцев назад

    I love your videos nice work, however, your error handling does not look so great.
    How do you handle uncaught exceptions and unhandled rejections in one go?
    Those can be handled using middleware which you can only call once throughout the server.

  • @user-mq6zb7xy6d
    @user-mq6zb7xy6d 11 месяцев назад

    Can you make a series of building full stack websites whenever you have a time

  • @n2-yt
    @n2-yt 10 месяцев назад

    To secure your API just follow the best practices and standard approach. Most of the modern API frameworks follow those, sometimes you just need to configure them.

  • @CaleMcCollough
    @CaleMcCollough 11 месяцев назад +1

    HTTPS won't stop a man-in-the-middle attack. If someone is snooping when you pass off encryption keys, it's not longer encrypted.

  • @x_Saad
    @x_Saad 4 месяца назад

    What if my Frontend website doesn't require the user to login

  • @emrebabur8236
    @emrebabur8236 11 месяцев назад

    👏

  • @CodeZakk
    @CodeZakk 11 месяцев назад +1

    also you should also secure for xss attacks!!

    • @AlecMaly
      @AlecMaly 11 месяцев назад +2

      In addition to other injection attacks (sqli, command injection, host header injection, etc.), mass assignments, 4xx bypasses, directory traversal, SSRF, web cache poisoning, logic errors, race conditions, IDORs, unicode normalization, information disclosure, etc. etc. etc.
      I'm glad to see someone talking about security. I don't see this often enough from non-security focused developer channels imo.
      Nice video!

    • @joshtriedcoding
      @joshtriedcoding  11 месяцев назад

      @@AlecMaly There was a reaaaally good website I once found explaining each of these in great detail, listing how to mitigate them and providing interactive examples. Can't remember the name right now. Most of these are heavily use case dependent, some you don't need to worry about at all depending on your deployment/tech stack. Nevertheless, these are very interesting to get into. Maybe one of y'all remembers that site it's definitely worth checking out

    • @crizuka
      @crizuka 11 месяцев назад

      @@joshtriedcoding maybe the website was hacksplaining? there is a lessons tab where they give a good explanation on those topics

  • @MDKhan-ww5tp
    @MDKhan-ww5tp 11 месяцев назад +1

    Can you make a video on you vscode setup

    • @joshtriedcoding
      @joshtriedcoding  11 месяцев назад +1

      What would be interesting for you to be in that video? Like custom snippets, theme, ...?

    • @MDKhan-ww5tp
      @MDKhan-ww5tp 11 месяцев назад +1

      @@joshtriedcoding You are goat everything in your setup will be interesting

  • @BeyondLegendary
    @BeyondLegendary 11 месяцев назад +2

    Impressive, very nice. Let's see Paul Allen's api security.

    • @joshtriedcoding
      @joshtriedcoding  11 месяцев назад

      It even has a tasteful THICCness to it. Oh my god.

  • @saidurrahmansiam
    @saidurrahmansiam 11 месяцев назад

    An extra additional step that I follow is generating the current time in milis and then making it a signed token which will be in the "key" parameter in the API link. Then when the API is hit it first verifies the key value token and then compares it with the current time of the API server and if the time passes more than 10 seconds API responds with a 401 not authorised response. because both times come from the same server it never gets the wrong time in milis. Even though if the request server and API server are different milis would be the same for any timezone of the world.

    • @joshtriedcoding
      @joshtriedcoding  11 месяцев назад +2

      Honestly sounds kinda cool but I must admit I actually have no idea what you mean

    • @saidurrahmansiam
      @saidurrahmansiam 11 месяцев назад

      @@joshtriedcoding XD... I guess I meesed up on explaining...so here it is in the API calling function I get the current second using (Date.now()/1000) then add 10 to that variable which makes the variable 10 seconds ahead of its time like we do in generating cookies. then wrap that variable using signed jwt and store that signed jwt to a variable named key. then in the fetcher I add the variable as key param like this `/api/get-user-data?&key=${key}`. finally in the API route I check the condition if the URL has key param.if so then I take the key param value(signed jwt) and validate that and store the validate data in a variable otherwise return 401. lastly I check the decoded jwt data or you can say the second is near the time by simply subtracting like this const difference= decodedKey - (Date.now/1000); then wrap with condition (difference > 0 && difference < 12). this makes the API link only available for 10 seconds otherwise link will always return 401. even if someone understand how it works they can't bypass the jwt validation. so this adds another layer of security to the API

  • @luisfelipemurguiaramos659
    @luisfelipemurguiaramos659 10 месяцев назад

    Make a video to log data. If a error happens send to a server the error or logs

  • @reversetcp
    @reversetcp 11 месяцев назад

    except, error handling is a nightmare in nextjs... try/catch spam and copy paste catch block on every route u create

    • @joshtriedcoding
      @joshtriedcoding  11 месяцев назад

      How do other languages / frameworks handle that better?

    • @elab4d140
      @elab4d140 11 месяцев назад

      @@joshtriedcoding in express, there is a package named express-async-errors which let you remove that try/catch spam and let you handle all the errors in the error handler middleware.

    • @reversetcp
      @reversetcp 11 месяцев назад

      @@joshtriedcoding You can write a custom function in express that can wrap your route in.

    • @reversetcp
      @reversetcp 11 месяцев назад

      Had to come back to this. Almost forgot: Bad middlewares. You can not use Prisma in middleware; for me that means I can not auth in middleware and the every API route has to be spammed with a auth check before I can actually start writing logic. ExpressJS' approach to middleware is so much more flexible and flawless imo.

  • @omarkraidie
    @omarkraidie 11 месяцев назад

    if i have two functions in pages/api/posts/index.ts which function gets invoked when making an api request? also how can I define the method for said functions in next js api routes?

    • @omarkraidie
      @omarkraidie 11 месяцев назад

      I think its something like this
      "if (req.method === 'POST')" // handle post
      "if (req.method === 'DELETE')" // handle delete?
      Thanks alot man nextjs 13 is exciting but its hard at first!

    • @joshtriedcoding
      @joshtriedcoding  11 месяцев назад +2

      @@omarkraidie Oh yeah it is. For the pages router I used to write a custom middleware that you could just wrap your entire API endpoint in to automatically send back a 405 status code for unspecified methods. It's far more intuitive in the new app router though

    • @Adrian_Galilea
      @Adrian_Galilea 11 месяцев назад +1

      Please do a practical example in the new app router :)

    • @omarkraidie
      @omarkraidie 11 месяцев назад

      @@Adrian_Galilea also maybe prisma and MongoDb? 🤍

  • @AngelEduardoLopezZambrano
    @AngelEduardoLopezZambrano 11 месяцев назад

    Csfr?

  • @user-ye4ek7oo9t
    @user-ye4ek7oo9t 9 месяцев назад

    Another one is "Versioning" extremely necessary for update and patches

  • @soumyasagar2305
    @soumyasagar2305 11 месяцев назад +3

    Summary
    1- Use https
    2- Authorize user in API
    3- Rate limiting the API
    4- Validation of data passed in API
    5- Error handling

    • @RootEntry
      @RootEntry 11 месяцев назад

      yk the summary is in the descriptionright

    • @soumyasagar2305
      @soumyasagar2305 11 месяцев назад

      @@RootEntry oops didn't have a look 💀

  • @thefuntech2810
    @thefuntech2810 11 месяцев назад

    Bro you missed the one of the most secure section and that was
    ACID. Transaction
    How to revert those transactions which executed but they failed at the end
    At that time our data will get corrupted
    Hope you explain me or make video on this
    Thanking you in advance

  • @samislam2746
    @samislam2746 5 месяцев назад

    I think error handling is off-topic

  • @user-pj4cg8oz9d
    @user-pj4cg8oz9d 11 месяцев назад

    Timing errors!!

  • @beancoffee
    @beancoffee 11 месяцев назад

    Just leaving it here,for when I come back to the video in the future...
    1. HTTPS
    2. Auth
    3. Rate Limiting
    4. Input Validation
    5. Error Handling

  • @jennibgmailcom
    @jennibgmailcom 11 месяцев назад

    Thanks. I think it would help if you did a video on passing tokens by http header vs passing tokens as cookies.

  • @mehmatrix
    @mehmatrix 11 месяцев назад

    Great video. I would say there is a very important 6th step. Maybe more important than the 5th one. Monitoring. We would like to know if our Server is being attacked, down or returning errors etc. So we can take action towards it. Thanks for the curation tho 🙏🏻👍🏻🫶🏻

  • @ohith3291
    @ohith3291 2 месяца назад

    JordIndian fans. here --->