• (cs) in reply to GFK
    GFK:
    feugiat:
    GFK:
    enim:
    Hidden Man:
    Uninformed blah blah blahThere is no reason to not use a prepared statement.Repeated blah blah blah
    orly? Why don't you look up when SQL Server started supporting prepared statements. GIYF. How does your foot taste?

    I don't get it. sp_executesql, which is used by SqlCommand parameters, existed in SQL Server 2000. The SqlParameter class exists since .net 1.1.

    I don't understand what you're trying to say (and you probably don't either)--are you saying there is no possibility that this code was for a system prior to SQL Server 2000? If so, you're pretty dumb.

    No wait. Your not dumb! But I do have a bridge to sell you...

    There's a possibility that it did, but there's a fair probability that it didn't. Keep your bridge for yourself, you might need it.

    Um, yeah, my thought exactly... Espcially considering SQL server 2000 came out in, wait for it, 2000 and .Net 1.0 came out in 2002. So the likelyhood of any .Net app, new or old, using anything SQL 7 or before is very low. I've seen it, but again unlikely. Also, stored procedures existed in SQL 7 (not sure about versions before that though).

  • genitus (unregistered) in reply to C-Octothorpe
    C-Octothorpe:
    GFK:
    feugiat:
    GFK:
    enim:
    Hidden Man:
    Uninformed blah blah blahThere is no reason to not use a prepared statement.Repeated blah blah blah
    orly? Why don't you look up when SQL Server started supporting prepared statements. GIYF. How does your foot taste?

    I don't get it. sp_executesql, which is used by SqlCommand parameters, existed in SQL Server 2000. The SqlParameter class exists since .net 1.1.

    I don't understand what you're trying to say (and you probably don't either)--are you saying there is no possibility that this code was for a system prior to SQL Server 2000? If so, you're pretty dumb.

    No wait. Your not dumb! But I do have a bridge to sell you...

    There's a possibility that it did, but there's a fair probability that it didn't. Keep your bridge for yourself, you might need it.

    Um, yeah, my thought exactly... Espcially considering SQL server 2000 came out in, wait for it, 2000 and .Net 1.0 came out in 2002. So the likelyhood of any .Net app, new or old, using anything SQL 7 or before is very low. I've seen it, but again unlikely. Also, stored procedures existed in SQL 7 (not sure about versions before that though).

    Correct, because no software was written before .NET.

    How old were you when 2000 rolled around? Do the letters Y2K mean anything to you? It was short for "The Year 2000". This was significant because programmers from the 1970's did not anticipate their software would be around until the turn of the century, leading to a problem because of assumptions that only two digits were needed to represent the year.

    Moral of the story: yes, software can be and often is old.

  • (cs) in reply to genitus
    genitus:
    C-Octothorpe:
    GFK:
    feugiat:
    GFK:
    enim:
    Hidden Man:
    Uninformed blah blah blahThere is no reason to not use a prepared statement.Repeated blah blah blah
    orly? Why don't you look up when SQL Server started supporting prepared statements. GIYF. How does your foot taste?

    I don't get it. sp_executesql, which is used by SqlCommand parameters, existed in SQL Server 2000. The SqlParameter class exists since .net 1.1.

    I don't understand what you're trying to say (and you probably don't either)--are you saying there is no possibility that this code was for a system prior to SQL Server 2000? If so, you're pretty dumb.

    No wait. Your not dumb! But I do have a bridge to sell you...

    There's a possibility that it did, but there's a fair probability that it didn't. Keep your bridge for yourself, you might need it.

    Um, yeah, my thought exactly... Espcially considering SQL server 2000 came out in, wait for it, 2000 and .Net 1.0 came out in 2002. So the likelyhood of any .Net app, new or old, using anything SQL 7 or before is very low. I've seen it, but again unlikely. Also, stored procedures existed in SQL 7 (not sure about versions before that though).

    Correct, because no software was written before .NET.

    How old were you when 2000 rolled around? Do the letters Y2K mean anything to you? It was short for "The Year 2000". This was significant because programmers from the 1970's did not anticipate their software would be around until the turn of the century, leading to a problem because of assumptions that only two digits were needed to represent the year.

    Moral of the story: yes, software can be and often is old.

    My, aren't we a pretentious prick today?

    Any idiot can change the scope of the conversation at any point to match their argument, but I thought we were staying focused. My mistake...

    In any case, IF you were referring to this particular WTF, it's written in .Net... Also, yes, .Net can target pre SQL 7 (or most any DB for that matter including oracle, MySQL, terradata, etc.), but if you took a second to look, you would notice the provider is SQL server.

    Moral of the story: you don't know everything, and acting like a wanker makes it that much more obvious.

  • boog (unregistered) in reply to boog
    boog:
    boog (inane imitator):
    boog:
    boog (clueless copycat):
    boog (witless wannabe):
    boog (meta meddler):
    My, your an unoriginal troll, aren't you?
    Says boog of wall people
    Says wall of boog people
    It seems I missed out on a lot of fun yesterday. How many fake boog comments was that in just one day? I'm impressed!

    I never realized I had so many fans.

    Who cares?
    Who doesn't?

    > SELECT * FROM fucks WHERE date_given = TODAY() ;
    Empty set (0.02s)

    Who knew?

  • will (unregistered) in reply to C-Octothorpe
    C-Octothorpe:
    notregistered:
    With regards to SQL, it is completely acceptable assuming that the input is correctly escaped to make SQL injection impossible. These "*NEVER*" comments tend to identify coders that have only been exposed to very limited problems and environments.

    With regards to non-SQL string concatenation NEVER being acceptable, you are an idiot.

    Fair enough. If you can give me an example of when it's OK to intentionally write SQL injectable code via string concatenation, then I will withdraw my NEVER statement. Otherwise, you're the idiot...

    I have one. Use to develop for a document search product that used SQL, tied with its own additions, in order to perform read only. No binding or parameters allowed so string concatenation was the only way. So yes SQL injection was available but anything but a select was ignored.

  • (cs) in reply to iusto
    iusto:
    GFK:
    feugiat:
    GFK:
    enim:
    Hidden Man:
    Uninformed blah blah blahThere is no reason to not use a prepared statement.Repeated blah blah blah
    orly? Why don't you look up when SQL Server started supporting prepared statements. GIYF. How does your foot taste?

    I don't get it. sp_executesql, which is used by SqlCommand parameters, existed in SQL Server 2000. The SqlParameter class exists since .net 1.1.

    I don't understand what you're trying to say (and you probably don't either)--are you saying there is no possibility that this code was for a system prior to SQL Server 2000? If so, you're pretty dumb.

    No wait. Your not dumb! But I do have a bridge to sell you...

    There's a possibility that it did, but there's a fair probability that it didn't. Keep your bridge for yourself, you might need it.

    Like someone said on here earlier: you cannot make any assumptions that you are not given. You THINK that it exists in a stored-procedure world, but I have enough evidence here to show the likelihood that it did not exist at authorship.

    In case you don't realize the reference: the "bridge" is similar to the idea of "ocean-front property in Arizona". The fact that I offered it to you shows that I don't think you're smart enough to realize that neither exists.

    Maybe you THINK you know what you're talking about, but I have enough evidence here to show the likelihood that I should explain to you why you don't.

    This code is .net (out 2002), and has been written (at authorship) via Ole to SQL Server, which is capable of command parametrization since version 7 (out 1998).

    My only assumption here is that this code has not been written for a version of SQL Server prior to version 7, and this assumption has a way bigger probability to be correct than the assumption that the author of this code knew or cared about parametrized command but couldn't implement it.

  • (cs) in reply to boog
    boog (laughable lookalike):
    boog:
    boog (inane imitator):
    boog:
    boog (clueless copycat):
    boog (witless wannabe):
    boog (meta meddler):
    My, your an unoriginal troll, aren't you?
    Says boog of wall people
    Says wall of boog people
    It seems I missed out on a lot of fun yesterday. How many fake boog comments was that in just one day? I'm impressed!

    I never realized I had so many fans.

    Who cares?
    Who doesn't?

    > SELECT * FROM fucks WHERE date_given = TODAY() ;
    Empty set (0.02s)

    Who knew?

    Who didn't?

  • (cs) in reply to boog
    boog:
    > SELECT * FROM fucks WHERE date_given = TODAY() ;
    Empty set (0.02s)
    Who knew?
    Now that's funny! However, you took way too long to think about it.
  • mara (unregistered) in reply to C-Octothorpe
    C-Octothorpe:
    genitus:
    C-Octothorpe:
    GFK:
    feugiat:
    GFK:
    enim:
    Hidden Man:
    Uninformed blah blah blahThere is no reason to not use a prepared statement.Repeated blah blah blah
    orly? Why don't you look up when SQL Server started supporting prepared statements. GIYF. How does your foot taste?

    I don't get it. sp_executesql, which is used by SqlCommand parameters, existed in SQL Server 2000. The SqlParameter class exists since .net 1.1.

    I don't understand what you're trying to say (and you probably don't either)--are you saying there is no possibility that this code was for a system prior to SQL Server 2000? If so, you're pretty dumb.

    No wait. Your not dumb! But I do have a bridge to sell you...

    There's a possibility that it did, but there's a fair probability that it didn't. Keep your bridge for yourself, you might need it.

    Um, yeah, my thought exactly... Espcially considering SQL server 2000 came out in, wait for it, 2000 and .Net 1.0 came out in 2002. So the likelyhood of any .Net app, new or old, using anything SQL 7 or before is very low. I've seen it, but again unlikely. Also, stored procedures existed in SQL 7 (not sure about versions before that though).

    Correct, because no software was written before .NET.

    How old were you when 2000 rolled around? Do the letters Y2K mean anything to you? It was short for "The Year 2000". This was significant because programmers from the 1970's did not anticipate their software would be around until the turn of the century, leading to a problem because of assumptions that only two digits were needed to represent the year.

    Moral of the story: yes, software can be and often is old.

    My, aren't we a pretentious prick today?

    Any idiot can change the scope of the conversation at any point to match their argument, but I thought we were staying focused. My mistake...

    In any case, IF you were referring to this particular WTF, it's written in .Net... Also, yes, .Net can target pre SQL 7 (or most any DB for that matter including oracle, MySQL, terradata, etc.), but if you took a second to look, you would notice the provider is SQL server.

    Moral of the story: you don't know everything, and acting like a wanker makes it that much more obvious.

    Aha. Your brain failed to make the connection between what we were talking about and the Y2K scenario. My mistake: I simply overrepresented your intelligence in my mind.

    Let me put it another way--have you ever worked on code with a long lifetime? This sort of duty is called "maintenance," something that occurs after the initial development effort has concluded. In this context, the fact that it is .Net code (although THAT is not really indicated here--it could very easily be C++) is immaterial. As technology evolves and your software migrates to many platforms, it is very often the case that you have to modify the code to perform the same operation using a slightly different context. This migration falls under the larger umbrella called "refactoring", which has the same basic goal: make the product work like it did before you changed what exists "under the covers."

    It is idiotic when you migrate code to start chasing rabbit trails and make the software do what it did not do originally--this should be part of a subsequent operation generally called "enhancement" or, if it is a serious enough defect, "bug fixing." If you try to do this as part of the "refactoring" effort, you have no baseline and an enormous potential to lose important data. I've met plenty of junior developers that fail to understand this fundamental concept.

  • (cs) in reply to boog
    boog:
    > SELECT * FROM fucks WHERE date_given IS NOT NULL ;
    Empty set (0.02s)
    Who knew?

    FTFY, and I'm so sorry to hear that...

  • no u (unregistered) in reply to method1
    method1:
    I'm amazed that you've never got a correct answer(unless you've only asked it once or twice). Fair enough if its an entry-level job, not if its for a DB guy, because it is trivial

    I'd estimate to have asked around 10-15 people that question. This is not for a DB admin role, but it is for a role which requires someone to be reasonably comfortable with sql queries, and where only people indicating as such on their resumes are brought in for an interview. (here's the twist.. turns out they are usually lying).

  • (cs) in reply to C-Octothorpe
    C-Octothorpe:
    GFK:
    feugiat:
    GFK:
    enim:
    Hidden Man:
    Uninformed blah blah blahThere is no reason to not use a prepared statement.Repeated blah blah blah
    orly? Why don't you look up when SQL Server started supporting prepared statements. GIYF. How does your foot taste?

    I don't get it. sp_executesql, which is used by SqlCommand parameters, existed in SQL Server 2000. The SqlParameter class exists since .net 1.1.

    I don't understand what you're trying to say (and you probably don't either)--are you saying there is no possibility that this code was for a system prior to SQL Server 2000? If so, you're pretty dumb.

    No wait. Your not dumb! But I do have a bridge to sell you...

    There's a possibility that it did, but there's a fair probability that it didn't. Keep your bridge for yourself, you might need it.

    Um, yeah, my thought exactly... Espcially considering SQL server 2000 came out in, wait for it, 2000 and .Net 1.0 came out in 2002. So the likelyhood of any .Net app, new or old, using anything SQL 7 or before is very low. I've seen it, but again unlikely. Also, stored procedures existed in SQL 7 (not sure about versions before that though).

    Injection protection is a feature of the library, not the DBMS. Sure, the library uses sp_executesql when available, but that's not the only way to skin this cat. SQLBindParameter has been around in ODBC since 2.0 in the early 1990s. It's the library and the driver's responsibility to find a supported method to get parameter values to the server without string concatenation. With old versions of SQL, ODBC or the .Net SQL Client will use RPC over TDS, with new versions they will use sp_executesql. Other DBMSs may have their own method and the driver may or may not implement it. Parameter binding worked just fine in SQL 6.5 and SQL 7 as long as you used the right library and used it properly, regardless of whether or not you use stored procedures (also, stored procedures are not a guarantee of proper parameterization, that's a separate issue).

  • (cs) in reply to no u
    no u:
    (here's business as usual.. turns out they are usually lying).

    FTFY

  • ludus (unregistered) in reply to Jaime

    And your implication is that no software was written before the 90's?

    Can you explain what you see in this picture? [image]

  • boog (unregistered) in reply to mara
    mara:
    C-Octothorpe:
    genitus:
    C-Octothorpe:
    GFK:
    feugiat:
    GFK:
    enim:
    Hidden Man:
    Uninformed blah blah blahThere is no reason to not use a prepared statement.Repeated blah blah blah
    orly? Why don't you look up when SQL Server started supporting prepared statements. GIYF. How does your foot taste?

    I don't get it. sp_executesql, which is used by SqlCommand parameters, existed in SQL Server 2000. The SqlParameter class exists since .net 1.1.

    I don't understand what you're trying to say (and you probably don't either)--are you saying there is no possibility that this code was for a system prior to SQL Server 2000? If so, you're pretty dumb.

    No wait. Your not dumb! But I do have a bridge to sell you...

    There's a possibility that it did, but there's a fair probability that it didn't. Keep your bridge for yourself, you might need it.

    Um, yeah, my thought exactly... Espcially considering SQL server 2000 came out in, wait for it, 2000 and .Net 1.0 came out in 2002. So the likelyhood of any .Net app, new or old, using anything SQL 7 or before is very low. I've seen it, but again unlikely. Also, stored procedures existed in SQL 7 (not sure about versions before that though).

    Correct, because no software was written before .NET.

    How old were you when 2000 rolled around? Do the letters Y2K mean anything to you? It was short for "The Year 2000". This was significant because programmers from the 1970's did not anticipate their software would be around until the turn of the century, leading to a problem because of assumptions that only two digits were needed to represent the year.

    Moral of the story: yes, software can be and often is old.

    My, aren't we a pretentious prick today?

    Any idiot can change the scope of the conversation at any point to match their argument, but I thought we were staying focused. My mistake...

    In any case, IF you were referring to this particular WTF, it's written in .Net... Also, yes, .Net can target pre SQL 7 (or most any DB for that matter including oracle, MySQL, terradata, etc.), but if you took a second to look, you would notice the provider is SQL server.

    Moral of the story: you don't know everything, and acting like a wanker makes it that much more obvious.

    Aha. Your brain failed to make the connection between what we were talking about and the Y2K scenario. My mistake: I simply overrepresented your intelligence in my mind.

    Let me put it another way--have you ever worked on code with a long lifetime? This sort of duty is called "maintenance," something that occurs after the initial development effort has concluded. In this context, the fact that it is .Net code (although THAT is not really indicated here--it could very easily be C++) is immaterial. As technology evolves and your software migrates to many platforms, it is very often the case that you have to modify the code to perform the same operation using a slightly different context. This migration falls under the larger umbrella called "refactoring", which has the same basic goal: make the product work like it did before you changed what exists "under the covers."

    It is idiotic when you migrate code to start chasing rabbit trails and make the software do what it did not do originally--this should be part of a subsequent operation generally called "enhancement" or, if it is a serious enough defect, "bug fixing." If you try to do this as part of the "refactoring" effort, you have no baseline and an enormous potential to lose important data. I've met plenty of junior developers that fail to understand this fundamental concept.

    tl;dr

  • (cs) in reply to C-Octothorpe
    C-Octothorpe:
    boog (imbecilic impersonator):
    > SELECT * FROM fucks WHERE date_given IS NOT NULL ;
    Empty set (0.02s)
    Who knew?
    FTFY, and I'm so sorry to hear that...
    Is it any surprise? I made sure to "fix" all of my clones, in order to prevent reproduction in the wild. Naturally he wouldn't get any action.
  • boog (unregistered) in reply to boog
    boog:
    C-Octothorpe:
    boog (imbecilic impersonator):
    > SELECT * FROM fucks WHERE date_given IS NOT NULL ;
    Empty set (0.02s)
    Who knew?
    FTFY, and I'm so sorry to hear that...
    Is it any surprise? I made sure to "fix" all of my clones, in order to prevent reproduction in the wild. Naturally he wouldn't get any action.
    Who said anything about reproduction? You're mom's on the pill, right?
  • (cs) in reply to PerlPlexed
    PerlPlexed:
    Not only is it looping over the return of a select statement to get a count (when that's what the count function is for) its also not using place-holder variables. Vulnerable to SQL injection attacks.

    SQL injection would be redundant. What I don't get is how he missed the fact that his code returned a value vastly larger than the dataset?

  • (cs) in reply to Jaime
    Jaime:
    Injection protection is a feature of the library, not the DBMS. Sure, the library uses sp_executesql when available, but that's not the only way to skin this cat. SQLBindParameter has been around in ODBC since 2.0 in the early 1990s. It's the library and the driver's responsibility to find a supported method to get parameter values to the server without string concatenation. With old versions of SQL, ODBC or the .Net SQL Client will use RPC over TDS, with new versions they will use sp_executesql. Other DBMSs may have their own method and the driver may or may not implement it. Parameter binding worked just fine in SQL 6.5 and SQL 7 as long as you used the right library and used it properly, regardless of whether or not you use stored procedures (also, stored procedures are not a guarantee of proper parameterization, that's a separate issue).
    If I recall, one of the benefits to using prepared statements is that the SQL statement and execution path are cached (giving several benefits, most importantly performance). In order for this to work, parameters cannot be concatenated in, as it would change the query text, causing the database to re-parse the SQL statement and calculate a new execution path. Instead, the statement is parsed with placeholders, which are replaced with the parameters at execution time. As such, there shouldn't be any need for the library to "sanitize" any parameters to prevent SQL injection, as the statement shouldn't be re-parsed.

    Or at least I believe that is how it works in Oracle. I can't speak for SQL Server and others.

  • Annoyed at Arrogance (unregistered) in reply to boog
    boog:
    useless garbage Or at least I believe that is how it works in Oracle. I can't speak for SQL Server and others.
    Then don't.
  • (cs) in reply to mara
    mara:
    Aha <snip> concept.

    Ah, so you did change the topic. Oooh, can I play too?

    You moron, obviously XSS is a security concern too! And JavaScript has been around since the mid '90s.'

    Clearly you didn't hear the voices in my head the same way I did...

  • (cs) in reply to Annoyed at Arrogance
    Annoyed at Arrogance:
    boog:
    useless garbage Or at least I believe that is how it works in Oracle. I can't speak for SQL Server and others.
    Then don't.
    I didn't.
  • (cs) in reply to boog
    boog:
    > SELECT * FROM fucks WHERE date_given = TODAY() ;
    'TODAY' is not a recognized built-in function name.
    Who knew?

    FTFY. Did you mean CURRENT_TIMESTAMP?

    Also: the SQL Server Provider has been around for ages. No excuse for using such a stupid connection string.

  • Nagesh (unregistered) in reply to Nagesh
    Nagesh:
    Can friendly plz post Java version for this?

    You're just kidding, right? You're not a retard?

  • (cs) in reply to Nagesh
    Nagesh:
    Nagesh:
    Can friendly plz post Java version for this?

    You're just kidding, right? You're not a retard?

    Oh, he's a retard alright, but this time he's kidding.

  • (cs) in reply to boog
    boog:
    Jaime:
    Injection protection is a feature of the library, not the DBMS. Sure, the library uses sp_executesql when available, but that's not the only way to skin this cat. SQLBindParameter has been around in ODBC since 2.0 in the early 1990s. It's the library and the driver's responsibility to find a supported method to get parameter values to the server without string concatenation. With old versions of SQL, ODBC or the .Net SQL Client will use RPC over TDS, with new versions they will use sp_executesql. Other DBMSs may have their own method and the driver may or may not implement it. Parameter binding worked just fine in SQL 6.5 and SQL 7 as long as you used the right library and used it properly, regardless of whether or not you use stored procedures (also, stored procedures are not a guarantee of proper parameterization, that's a separate issue).
    If I recall, one of the benefits to using prepared statements is that the SQL statement and execution path are cached (giving several benefits, most importantly performance). In order for this to work, parameters cannot be concatenated in, as it would change the query text, causing the database to re-parse the SQL statement and calculate a new execution path. Instead, the statement is parsed with placeholders, which are replaced with the parameters at execution time. As such, there shouldn't be any need for the library to "sanitize" any parameters to prevent SQL injection, as the statement shouldn't be re-parsed.

    Or at least I believe that is how it works in Oracle. I can't speak for SQL Server and others.

    Parameterization may end up with a prepared statement, but it may not. Prepared statements may be called properly parameterized, but they don't have to be. The two are separate issues.

    In SQL Server, if you issue the following statements from an application and use string concatenation instead of parameterization:

    EXEC GetEmployee 1234 EXEC GetEmployee 2345

    ... you will get plenty of cache benefits, but no injection prevention.

    If you issue SELECTs, but properly parameterize them, you will get injection protection, and you might get statement caching through a mechanism called "ad-hoc batch caching". Ad-hoc batch caching does auto-parameterization, so two calls can have different text, but still use the same execution plan.

  • (cs) in reply to ludus
    ludus:
    And your implication is that no software was written before the 90's?

    Can you explain what you see in this picture? [image]

    I was just mentioning that SQL 6.5 and SQL 7 were covered. I made no statement that all applications back to the beginning of time had SQL injection protection, or that they should.

  • Roman (unregistered)

    Finally, we are getting somewhere... near interesting.

  • (cs) in reply to Jaime
    Jaime:
    Parameterization may end up with a prepared statement, but it may not. Prepared statements may be called properly parameterized, but they don't have to be. The two are separate issues.
    Fair enough; when I say "prepared statement", I generally assume it's parameterized and not concatenated, but you're right, that's not always the case.

    It's easy to forget that these are separate issues when you always see it done either one way (prepared statements, properly parameterized) or the other (SQL string with params concatenated in; ready for injection attacks!).

  • (cs) in reply to boog
    boog:
    Jaime:
    Parameterization may end up with a prepared statement, but it may not. Prepared statements may be called properly parameterized, but they don't have to be. The two are separate issues.
    Fair enough; when I say "prepared statement", I generally assume it's parameterized and not concatenated, but you're right, that's not always the case.

    It's easy to forget that these are separate issues when you always see it done either one way (prepared statements, properly parameterized) or the other (SQL string with params concatenated in; ready for injection attacks!).

    Now you understand my stance on stored procedures. When you tell a newbie to use stored procedures to protect against SQL injection, he builds the call using string concatenation and buys nothing. When you tell a newbie to use parameterization to protect against SQL injection, it always works. Convincing him to use stored procedures is another argument for another day.

  • (cs) in reply to Jaime
    Jaime:
    Now you understand my stance on stored procedures. When you tell a newbie to use stored procedures to protect against SQL injection, he builds the call using string concatenation and buys nothing. When you tell a newbie to use parameterization to protect against SQL injection, it always works. Convincing him to use stored procedures is another argument for another day.
    Well, stored procedures are yet another issue, and as far as I'm concerned have nothing to do with prepared statements. This discussion started with a comment about prepared statements, but for some reason somebody brought up stored procs. I've tried to keep my comments from straying into that territory, but oh well, here we are.

    To be fair I've never argued that stored procedures should be used to protect against SQL injection. My opinion of stored procedures is really no different than for any other form of subroutine, and that's the only reason I've ever advocated using them.

    But I do see where you're coming from; the solution (stored procs, and even prepared statements) is unrelated to the problem (SQL injection), and most people fail to realize this. Thanks for clarifying.

  • iMalc (unregistered)

    It could be worse; At least isn't counting the rows recursively!

  • only me (unregistered) in reply to airdrik
    airdrik:
    mike:
    airdrik:
    To all of the people crying over possible SQL injection attacks, while it should be using prepared/parameterized statements, I would venture to say that unless there is evidence otherwise it is probably safe to assume that there is no possibility of such attacks. First, this looks like inner library code. The values passed in were probably pulled directly from the database (myHomeID) or from some hard-coded enumeration (myStatus). Assuming that this is the case, it would be a big WTF if those values did contain some "extra sql" (though that could explain why they were concatenating strings rather than using prepared statements - oh, how the thought makes my brain hurt). Second, if this were somehow exposed to user input, it is probably safe to assume that it is under a layer or two of (most likely WTF-worthy) sanitization/validation code which makes sure that the values conform to some format. That they are using the values as filter conditions in the where clause leads me to believe that neither is linked to a free-form, user-exposed field.

    There is no cost to using prepared statements for field substitution. Indeed, its use can improve performance when multiple queries are made. Used consistently, it makes your code provably invulnerable to SQL injection attacks. It avoids other potential bugs that come from data changes (spaces, commas, etc in your fields). For very good reasons, it is the current best practice for forming SQL string queries.

    Using string concatenation for SQL field substitution is always the wrong way to do it. It promotes sloppiness in your code base, provides dangerous sample code for people coming on later to the project, and it is a hole in your code where you can't unequivocally claim there is no chance for SQL injection attacks. Arguing that it doesn't matter shows a deliberate disregard for good programming practices.

    Yes, I realized that already. In summary: don't be stupid, use prepared statements (and use the functions that are provided which do what you are trying to accomplish).

    Okay, so junior developer here. I just learned SQL ( from a book ) and now I have to learn web programming to maintain the code to the DB. I understand most of the bad things here, ( though not all ) but what is correct way to prevent sql injection, so my code doesn't end up here ?

  • Denis (unregistered) in reply to andrew

    There also is: opening a new connection on each call!

  • (cs) in reply to only me
    only me:
    airdrik:
    mike:
    airdrik:
    To all of the people crying over possible SQL injection attacks, while it should be using prepared/parameterized statements, I would venture to say that unless there is evidence otherwise it is probably safe to assume that there is no possibility of such attacks. First, this looks like inner library code. The values passed in were probably pulled directly from the database (myHomeID) or from some hard-coded enumeration (myStatus). Assuming that this is the case, it would be a big WTF if those values did contain some "extra sql" (though that could explain why they were concatenating strings rather than using prepared statements - oh, how the thought makes my brain hurt). Second, if this were somehow exposed to user input, it is probably safe to assume that it is under a layer or two of (most likely WTF-worthy) sanitization/validation code which makes sure that the values conform to some format. That they are using the values as filter conditions in the where clause leads me to believe that neither is linked to a free-form, user-exposed field.

    There is no cost to using prepared statements for field substitution. Indeed, its use can improve performance when multiple queries are made. Used consistently, it makes your code provably invulnerable to SQL injection attacks. It avoids other potential bugs that come from data changes (spaces, commas, etc in your fields). For very good reasons, it is the current best practice for forming SQL string queries.

    Using string concatenation for SQL field substitution is always the wrong way to do it. It promotes sloppiness in your code base, provides dangerous sample code for people coming on later to the project, and it is a hole in your code where you can't unequivocally claim there is no chance for SQL injection attacks. Arguing that it doesn't matter shows a deliberate disregard for good programming practices.

    Yes, I realized that already. In summary: don't be stupid, use prepared statements (and use the functions that are provided which do what you are trying to accomplish).

    Okay, so junior developer here. I just learned SQL ( from a book ) and now I have to learn web programming to maintain the code to the DB. I understand most of the bad things here, ( though not all ) but what is correct way to prevent sql injection, so my code doesn't end up here ?

    Avoid string concatenation for database commands, use the parameterization feature of your chosen database access library. If you come across a use case that is beyond the capabilities of that parameterization feature, then either re-design or get the help of someone who understands SQL injection. It's really that simple.

  • (cs) in reply to Denis
    Denis:
    There also is: opening a new connection on each call!
    I responded to this one 150 posts ago, but it got lost in the noise...

    It's not a WTF, and is actually recommended practice if database connection pooling is available.

  • Jay (unregistered)

    Just to join in on the "sanitizing inputs" free-for-all:

    My general philosophy is: Sanitize inputs at point of input. Then you can rely on their being valid throughout the system. If the field is entered on a screen by the user, we validate when processing the input and before saving to the database or using in any calculations. If the field is received from another system, we validate at the time we get the message or whatever. Etc.

    Yes, you COULD write all your code checking the validity of every parameter for every function. But then you have six bazillion validity checks. It seems to me that this violates one of the most basic principles of good programming: Don't Repeat Yourself. This: (a) Wastes CPU cycles validating the same field over and over. (b) Makes the program more difficult to maintain. If the validity test changes -- maybe a field that used to be limited to 8 characters is now allowed to be 9 -- we have a bazillion places to change instead of one. (c) Makes the code harder to read. Every function has so-many lines of extra code to do this validity testing, which clutters up the logic. (d) Makes the user interface less friendly, as instead of alerting the user to bad data at the time he tries to enter it, we presumably accept it, and then fail later when we try to use it. The user who gets the error message may not be the user who entered the bad data, or even if it's the same person he may have entered the bad data months ago and has no easy way to determine what the correct data is. (I suppose we could be validating at input time and also validating when we try to use it, in which case this objection would not be applicable.)

    Yes, this philosophy means that if a foolish programmer fails to validate an input and writes it to the database, functions could fail all over the place. But if we have bugs in our code, surely the solution is to fix the bug, not to write other code to circumvent the bad effects of the bug.

  • (cs) in reply to Jay
    Jay:
    Just to join in on the "sanitizing inputs" free-for-all:

    My general philosophy is: Sanitize inputs at point of input. Then you can rely on their being valid throughout the system. If the field is entered on a screen by the user, we validate when processing the input and before saving to the database or using in any calculations. If the field is received from another system, we validate at the time we get the message or whatever. Etc.

    Yes, you COULD write all your code checking the validity of every parameter for every function. But then you have six bazillion validity checks. It seems to me that this violates one of the most basic principles of good programming: Don't Repeat Yourself. This: (a) Wastes CPU cycles validating the same field over and over. (b) Makes the program more difficult to maintain. If the validity test changes -- maybe a field that used to be limited to 8 characters is now allowed to be 9 -- we have a bazillion places to change instead of one. (c) Makes the code harder to read. Every function has so-many lines of extra code to do this validity testing, which clutters up the logic. (d) Makes the user interface less friendly, as instead of alerting the user to bad data at the time he tries to enter it, we presumably accept it, and then fail later when we try to use it. The user who gets the error message may not be the user who entered the bad data, or even if it's the same person he may have entered the bad data months ago and has no easy way to determine what the correct data is. (I suppose we could be validating at input time and also validating when we try to use it, in which case this objection would not be applicable.)

    Yes, this philosophy means that if a foolish programmer fails to validate an input and writes it to the database, functions could fail all over the place. But if we have bugs in our code, surely the solution is to fix the bug, not to write other code to circumvent the bad effects of the bug.

    This will only work for trivial cases. How will your validation in the search box know that the users isn't actually looking for "' or 1=1 --"? Or even more realistically, preventing SQL injection at the point of input would mean that O'Brien would be invalid in a last name field, while handling it properly in the data access layer would properly search for O'Brien by escaping the single quote at the point it is submitted to the server.

    As for DRY, nobody writes SQL sanitation code; it's built into every sane library on the planet. All you have to do is parameterize your calls (which you should be doing anyways because it often provides other benefits).

  • (cs) in reply to Jay
    Jay:
    Just to join in on the "sanitizing inputs" free-for-all:

    My general philosophy is: Sanitize inputs at point of input. Then you can rely on their being valid throughout the system. If the field is entered on a screen by the user, we validate when processing the input and before saving to the database or using in any calculations. If the field is received from another system, we validate at the time we get the message or whatever. Etc.

    Sanitizing and validating inputs are also separate issues. For example, an apostrophe in a name is perfectly valid, but is not sanitized; if you concatenate it into an SQL statement, you'll get trouble.

    Validating certainly should be done at the point of input, but I'd suggest that sanitizing wait until it's actually necessary. You may need the value unchanged for prior operations, but more importantly, there is more than one way to sanitize depending on how you use the value (HTML encoded, URL encoded, or whatever).

  • (cs) in reply to Jay
    Jay:
    Just to join in on the "sanitizing inputs" free-for-all:

    My general philosophy is: Sanitize inputs at point of input. Then you can rely on their being valid throughout the system. If the field is entered on a screen by the user, we validate when processing the input and before saving to the database or using in any calculations. If the field is received from another system, we validate at the time we get the message or whatever. Etc.

    Yes, you COULD write all your code checking the validity of every parameter for every function. But then you have six bazillion validity checks. It seems to me that this violates one of the most basic principles of good programming: Don't Repeat Yourself. This: (a) Wastes CPU cycles validating the same field over and over. (b) Makes the program more difficult to maintain. If the validity test changes -- maybe a field that used to be limited to 8 characters is now allowed to be 9 -- we have a bazillion places to change instead of one. (c) Makes the code harder to read. Every function has so-many lines of extra code to do this validity testing, which clutters up the logic. (d) Makes the user interface less friendly, as instead of alerting the user to bad data at the time he tries to enter it, we presumably accept it, and then fail later when we try to use it. The user who gets the error message may not be the user who entered the bad data, or even if it's the same person he may have entered the bad data months ago and has no easy way to determine what the correct data is. (I suppose we could be validating at input time and also validating when we try to use it, in which case this objection would not be applicable.)

    Yes, this philosophy means that if a foolish programmer fails to validate an input and writes it to the database, functions could fail all over the place. But if we have bugs in our code, surely the solution is to fix the bug, not to write other code to circumvent the bad effects of the bug.

    One word: canonicalization. The same data can be in differenent encodings, different targets, etc. The problem with only validating at point of entry is that there is a possibility of the data being used elsewhere.

    For example: you have a field that searches a SQL database table by a users first name. Now in the UI you sanitize the data looking for 'DROP', or 'CREATE', or '--', etc. Now lets say you start using the same data to query LDAP, or you're going to look into an XML file, etc. Now your 'sanitization' targeted to a DB is useless as a malicious user can now perform LDAP or XML/xpath injection attacks...

    Here is a link, as they word it much better than I can...

  • Crispinito (unregistered) in reply to Lone Marauder

    He is iterating through the entire table (very slow) instead of using the sql 'count()' function (very fast).

  • Grey (unregistered)

    They make such pearls to convince users to buy more expensive hardware to run their shit. Welcome to the industry!

  • Dominicus (unregistered)

    Over and over again "the daily wtf" suprises me. One should think there must be something on an programmers mind. If I read such code I just can think, "It surely has nothing to do with programming"....

  • Chrisw (unregistered)

    how about this:

    int GetLeadCount(SqlDb voDb, int vnHomeID, ReviewStatusEnum veReviewStatus) { string lsSql = "SELECT COUNT(*)" + " FROM LeadsTab" + " WHERE HomeID = " + vnHomeID + " AND ReviewStatus = " + (int) veReviewStatus;

    return voDb.ExecuteScalarInt(lsSql);
    

    }

    when using only int's, you needn't escape the sql-string parts - no danger but faster to type.

  • unabomber (unregistered) in reply to Lone Marauder

    He nievely returned all the data from the database using the select * and then preoceeded to loop though the datareader to count the rows.

    When all he really needed to do was 'select count(*)' which would have returned the count for him.

  • Neil (unregistered) in reply to GFK
    GFK:
    sp_executesql, which is used by SqlCommand parameters, existed in SQL Server 2000.
    Wait, so the most efficient way of executing a string of SQL is to invoke a stored procedure?

    CAPTCHA: distineo

    sp_executesql('SELECT DISTINEO ' & columns & from & join & where & group & having & order)

  • John (unregistered)

    SQL Injection tops the Homeland Security list of website problems:

    http://www.nytimes.com/2011/06/28/technology/28secure.html?_r=1

  • anon (unregistered)

    He could have inserted his records into a DataGridView then retrieved the RowCount property... :)

  • notregistered (unregistered) in reply to C-Octothorpe

    Fair enough. If you can give me an example of when it's OK to intentionally write SQL injectable code via string concatenation, then I will withdraw my NEVER statement. Otherwise, you're the idiot...

    I think the point was that it is perfectly possible to write NON-SQL-injectable code via string concatenation, assuming you use an appropriate escaping function. No one stated that it is OK to write injectable code, but have fun with your strawman.

    For instance if you are using conacenation to build a SQL statement in PL/PGSQL, you would use quote_literal or quite_ident as appropriate. This code is not vulnerable to injection.

    If you were doing the same thing in PHP (for postgres), you would use pg_escape_string. There are genuine occasions where you might want to do this. An example might be where the database is remote from the client and the latency between the two is very high (dwarfing query execution time), preparing the query can actually slow things down because of the initial round trip to the DB doing the prepare added to the round trip time of the query when executed. When you write apps in the third-world with third-world infrastructure, reality sometimes gets in the way of your convenient "*NEVER".

  • junior (unregistered) in reply to Jaime
    Jaime:
    Denis:
    There also is: opening a new connection on each call!
    I responded to this one 150 posts ago, but it got lost in the noise...

    It's not a WTF, and is actually recommended practice if database connection pooling is available.

    BUT if you are using database connection pooling, you should not be constructing your connection string on the fly. Connection pooling depends on recognising that a new connection matches an existing one, ie has a functionally identical connection string.

Leave a comment on “A More Better Way to Count”

Log In or post as a guest

Replying to comment #:

« Return to Article