How Is This Code Safe?

Поделиться
HTML-код
  • Опубликовано: 7 июн 2024
  • Tagged template literals are a really common JS feature that nearly everyone uses, but most people have no idea that you can use them as a function. In this video I will show you exactly how to use tagged template literals as a function and why the Next.js release code is actually safe.
    📚 Materials/References:
    Tagged Template Literals Article: blog.webdevsimplified.com/202...
    🌎 Find Me Here:
    My Blog: blog.webdevsimplified.com
    My Courses: courses.webdevsimplified.com
    Patreon: / webdevsimplified
    Twitter: / devsimplified
    Discord: / discord
    GitHub: github.com/WebDevSimplified
    CodePen: codepen.io/WebDevSimplified
    ⏱️ Timestamps:
    00:00 - Introduction
    00:33 - The Problem
    01:12 - Basic Function Tagged Template Literals
    03:26 - Advanced Function Tagged Template Literals
    #TaggedTemplateLiterals #WDS #JavaScript

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

  • @MrABCLynch
    @MrABCLynch 6 месяцев назад +64

    As a lesson on template strings, this is a good one. Don't sanitise SQL yourself, rely on whichever database lib you're using. It will likely use parameterisation which is driver/database level functionality.

    • @zappz8858
      @zappz8858 6 месяцев назад

      Personally if you don't sanitize the sql yourself I don't think you're taking intentional approaches to implement data integrity handling.

  • @arnothar8035
    @arnothar8035 6 месяцев назад +30

    SQL sanitizing is a good idea, but it has a weakness compared to prepared statements: The execution plan that is created by your database server for the sanitized SQL is only valid once and is discarded after your SQL was executed. Whereas a prepared statement can be reused with different parameters without having to generate a new execution plan.

    •  6 месяцев назад +1

      Dropping a plan is not always a weakness. Sometimes, DB can optimize the query more when it knows the exact parameters because it can compare it with table stats. With a prepared query plan, it has to be generic, ignoring the distribution of the values in the table, for example.

    • @ckennedy0323
      @ckennedy0323 6 месяцев назад

      Yeah it's a balance based on your data. On one hand, parameter sniffing is a killer when you have a massive disparity in relationships. On the other, if you have a pretty homogeneous group a plan can save you from "death by a thousand cuts" rebuilding a plan frequently.

  • @rael_gc
    @rael_gc 6 месяцев назад +1

    I'm loving the short and direct to the subject videos.

  • @Russ_Paul
    @Russ_Paul 6 месяцев назад +3

    Very interesting breakdown of the template string. Had completely forgotten about the backtick invocation.

  • @henrique-work
    @henrique-work 6 месяцев назад

    I did see this syntax in some of libs, but never checked how it worked, very interesting video XD

  • @Trekiros
    @Trekiros 6 месяцев назад +2

    This is good syntactic sugar, I didn't know about it until last week

  • @lolxnn
    @lolxnn 6 месяцев назад +15

    Don't sanitize the tags yourself just replace the tags with the placeholder used by your db like '?' and return that plus the array of bind params. Then query your db by using the rendered query and the params extracted. Let the DB do the actual sanitization!

    • @JJJMMM1
      @JJJMMM1 6 месяцев назад +3

      The DBMS doesn't have to do any sanitization on prepared statements since the SQL is compiled without the data. The data can't cause SQL injection because it never goes through the compiler.

    • @lolxnn
      @lolxnn 6 месяцев назад

      @@JJJMMM1 Yes that's more correct. Let's say that I just wanted to warn people about self query sanitization

  • @MichaelCampbell01
    @MichaelCampbell01 6 месяцев назад +4

    All the SQL comments below, while valid and good advice, are missing the point here, which is "this isn't string concatenation, so this isn't necessarily an instance of SQL injection".

  • @whonayem01
    @whonayem01 6 месяцев назад

    Thanks! It’s clear now!

  • @BobFrTube
    @BobFrTube 6 месяцев назад

    Yes, this is just what I implemented for myself. Very powerful.

  • @shap_po
    @shap_po 6 месяцев назад +2

    wow, this is such an interesting feature

  • @zappz8858
    @zappz8858 6 месяцев назад

    Turn your sql strings into sql methods with often shared names (split off namespaces to prevent collisions or simply name the sql whateversql with the method being the whatever).
    Within the method perform needed sanitizing, validation with try catches as required for necessary error handling and your database, api calls are fine. From there it's more of a question of where you want to have that validation take place (client, server side).
    Use the parameterization method the database type calls for and have it interpolate as required (or interpolate as needed for the specific language you're using). Like with C# there is a type to value pairing on the value that is being interpolated/provided where you can define it as the database specific type that may not directly correspond with C# or the ansi model that is generally provided.

    • @zappz8858
      @zappz8858 6 месяцев назад

      const GetNameSql = "SELECT NAME FROM TABLE WHERE ID = :ID";
      public string GetName (int id){
      const parameters = new OracleParameters[]{
      new OracleParameter(":ID", id, OracleDbType.Number)
      }
      return OracleConnection.ExecuteScalar(GetNameSql, parameters);
      }
      For JavaScript you have to implement your own type checking which I would just make a static Type class and then implement that here. JavaScript needs a dedicated type validation class.

    • @zappz8858
      @zappz8858 6 месяцев назад

      Okay this is funny. After all the comments and watching the video none of them really dealt with what you were talking about. Apologies for mine haha.

  • @devwithbrian1534
    @devwithbrian1534 6 месяцев назад

    Thanks Kyle

  • @kgaming7599
    @kgaming7599 6 месяцев назад +2

    i'm not convinced that
    function sanatize(strings, ...values) {
    return values.reduce((prev, cur, idx) => (prev + '"' + cur.replace(/"/g, '""') + '"' + strings[idx + 1]);
    }
    would actually successfully sanitize sql but I also can't see why it wouldn't 😭

  • @krtirtho
    @krtirtho 6 месяцев назад

    So much fun to troll the people who are trolling without knowing a single thing about what they're trolling and also they're wrong and makes them look like a fool

  • @jjdjdkdjfj174
    @jjdjdkdjfj174 6 месяцев назад

    Hi, is your React course ALONE enough to go from zero to somewhat Pro in React or I still need other courses or resources too ? please let me know.

    • @stevenstraker5105
      @stevenstraker5105 6 месяцев назад +1

      This sort of answers your question, but there's no real end state in development (like Pro). You gain more and more experience over time and usage to try and attain mastery until the next update/version, and then you try to learn and improve again. Web/App development is a vicious cycle, but it's rewarding! I'm 15+ years a developer and I'm still learning new things :). Hope this helps!

    • @WebDevSimplified
      @WebDevSimplified  6 месяцев назад +1

      It will teach you more than enough to land your first job as a React developer but being a developer is about constant learning. You shouldn't need another course after mine but you will need to keep up with documentation for new libraries and other things like that as a developer

  • @khraks
    @khraks 6 месяцев назад

    What if I forgot to write sql`...`?

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

    What if my id=`1"; DROP TABLE USERS;select "1` ?

  • @engine_man
    @engine_man 6 месяцев назад

    Didn’t Josh someone already cover this?

  • @mebamme
    @mebamme 6 месяцев назад +4

    That's really cool!
    Until someone forgets to add the sql prefix!

  • @veerakumar1279
    @veerakumar1279 6 месяцев назад +1

    im just wondering where is the paranthesis what happened to js?

  • @soniablanche5672
    @soniablanche5672 6 месяцев назад +3

    for the 1st example, slugs should be generated by the server so they should be safe in theory even without sanitizing it.

  • @gabormiklay9209
    @gabormiklay9209 6 месяцев назад

    If the string doesn't come from the user then it's OK.
    Every input that comes from the user should be sanitized (prepared statements or whatever your method is).

  • @tomshieff
    @tomshieff 6 месяцев назад

    People are so eager to criticize anything without even understanding what's going on!

  • @alerighi
    @alerighi 6 месяцев назад +1

    Tough it seems to easy to forget the sql tag and have an SQL injection. Sure, linters will catch this (if properly configured), but I would avoid it, since it induces bad practices.
    Also if you want to execute more time the same query (e.g. multiple insert) this is inefficient, since it constructs each time a new query as a string, while when using prepared statements the query is parsed and optimized by the DBMS only a single time and then executed as many times you want with different parameters.

    •  6 месяцев назад +1

      SQL tag can return a specialized type which can be chceked by TS, linter, ... but also during runtime to make sure no SQL injection is possible. Simply checking if the query is of type SqlQuery and throwing an exception to remind using the tag does the trick 🙂

    • @IxMeTutorials
      @IxMeTutorials 6 месяцев назад +1

      I'm pretty sure Next will runtime error if you forget the tag.

  • @adambickford8720
    @adambickford8720 6 месяцев назад +5

    I'm not convinced making it almost indiscernible from an injection attack is the best api choice, even if it works.

    • @airixxxx
      @airixxxx 6 месяцев назад +1

      If you like it or not is up to you, but calling it liability like half the internet did is showing ignorance.

    • @adambickford8720
      @adambickford8720 6 месяцев назад +1

      @@airixxxx if you like it or not is up to you, but ignoring the foot gun factor is showing ignorance.

    • @airixxxx
      @airixxxx 6 месяцев назад

      @@adambickford8720 nope

  • @protocol6
    @protocol6 6 месяцев назад +1

    Hopefully the tag function in question doesn't just wrap it in quotes like you did since you could just pass in a value with quotes in it to defeat it.

    • @kgaming7599
      @kgaming7599 6 месяцев назад

      so you gotta replace all "s with ""s

  • @nomadshiba
    @nomadshiba 6 месяцев назад

    I am suprised that people are not aware of this espacilly after lit

  • @Myrusaf
    @Myrusaf 6 месяцев назад

    Kyle Kyle kyle

  • @joeynovak07
    @joeynovak07 6 месяцев назад

    This is so bad... Please... Please... Don't anyone ever do this. Quoting a string isn't sanitizing. All the comments about "It's ok if it isn't user input"... Can you send me your resume so that I can make sure to never hire you? The SAFE way to do this would be to use the sql function to create a prepared statement replacing the arguments with the placeholder for your database (probably a ?) and then return the prepared statement. Or execute it and return the results, your choice.
    Note: I LOVE your videos and have learned a ton, just please don't roll your own SQL sanitizer again, even as an example. Too many people will think you are serious.

    • @lolxnn
      @lolxnn 6 месяцев назад +1

      You can make a prepared statement in the templating function. But I agree that this could give developers a bad habit.

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

    This is a VERY dangerous way to sanitize SQL, even if you write the perfect sanitization function. A developer has to remember NEVER to use parenthesis with that sql function you defined.
    If you use parenthesis such as this:
    id = "1 OR (1=1); DROP TABLE users;--"
    sql(`SELECT * FROM users WHERE id=${id}`)
    Then the function sql will receive a SINGLE argument that looks like this:
    "SELECT * FROM users WHERE id=1 OR (1=1); DROP TABLE users;--"

  • @ZamirMubashir
    @ZamirMubashir 6 месяцев назад +3

    Like others have mentioned this is a good lesson on template strings but I still don't believe this is the right use case.
    I get that this approach gives access to your arguments to make them easier to sanitize but it still is the function's responsibility to sanitize it properly. Without a proper implementation for the sanitization function this approach will be vulnerable to SQL injections.
    Instead of re-inventing the universe every time, why not rely on the database library one is using or prepared statements which have already solved such problems?

    • @sambegstha3516
      @sambegstha3516 6 месяцев назад +1

      It was just a showcase of how next js 14's new architecture worked. It's not like they're saying to use it that way.
      How can you showcase a feature, without using the way the feature was intended to use.

    • @1vader
      @1vader 6 месяцев назад +2

      The idea is obviously that the `sql` function comes from a library.

  • @carlitosesquer1688
    @carlitosesquer1688 6 месяцев назад

    using on today code direct SQL statements is so unprofessional. why do you think are ORM invented? why do you think Microsoft Entity, Ruby on Rails Active Record or python Django ORM are for?

  • @vladpopa33
    @vladpopa33 6 месяцев назад +1

    Very good explanation on template string, but still, this is prone to error, it's just a big enough possibility for someone to forget about sanitizing. Prepared statements remains the way to go.

    • @joachimfrank4134
      @joachimfrank4134 6 месяцев назад +4

      The sql Function probably converts the string in a prepared statement. It could just put ?, or what else is the marker for the database in use , between the string parts. Then the values can be passed through to the database.

    • @Russ_Paul
      @Russ_Paul 6 месяцев назад

      @@joachimfrank4134 So in essence something like this { values, sql: strings.join("?") }?

    • @1vader
      @1vader 6 месяцев назад

      ​@@joachimfrank4134That doesn't change the fact that you can accidentally use a regular string. Unless the SQL library rejects strings.

  • @The-Great-Brindian
    @The-Great-Brindian 6 месяцев назад

    Man I swear... This whole 'good code' v 'bad code' is gonna cause a huge divide in the dev game...
    Like the whole east coast v west coast shit during 90s hip hop lol
    😂
    Me personally I'm hood code.. Like, if it works it works. If I EXECUTE and code works, job done lol

  • @1vader
    @1vader 6 месяцев назад

    Good explanation of the JS featuere but your quote "sanitation" is terrible and doesnt prevent injections at all. Maybe it was just an example but imo it's a really bad one since it's not clear to beginners that that's not actually sanitizing anything.

  • @user-fed-yum
    @user-fed-yum 6 месяцев назад +3

    Whilst it may work, this encourages bad practices that may cause one to repeat the same pattern in a different toolkit, that doesn't share the same "protection". Long term maintainability becomes questionable. For what gain? Just because you can do something, doesn't mean you should. I see a number prepared statement advocates here - again, worthy in some situations, but in many others it will make things slower. And it all depends on the database and the nature of each transaction. So stay away from assumed and dangerous practices, and don't optimize too early unless you have evidence to support your position.

  • @sarahwbs
    @sarahwbs 6 месяцев назад +1

    Just because it's safe doesn't mean you should.

    • @airixxxx
      @airixxxx 6 месяцев назад +1

      But don't call it unsafe when it isn't.

  • @Woeden
    @Woeden 6 месяцев назад +3

    I will never ever trust a frontend or "fullstack" dev with SQL queries lol

    • @airixxxx
      @airixxxx 6 месяцев назад

      Learn English before trying to sound cool diminishing others.

  • @daedalus5070
    @daedalus5070 6 месяцев назад +1

    Too slim a difference for me 😅
    I'm all in favour of getting people to just write SQL but this aint it.

  • @khaled-0
    @khaled-0 6 месяцев назад +3

    Why is this a valid js syntax. I hate JavaScript

    • @exercitus8535
      @exercitus8535 6 месяцев назад +3

      What's wrong with this syntax?