• Gabe (unregistered) in reply to FredSaw
    FredSaw:
    We know that somebody, somewhere had to write it; otherwise, it couldn't be plagiarized. For no discernable reason, we just choose to assume that someone is not you.

    The reason is because no one that smart had ever applied for a job there before. Kind of like if you put "Nuclear Physics Researcher" as your last job on your application for gas station cashier.

  • (cs) in reply to bah
    bah:
    I think the real stupid part is they are doing this by email.. Anyone could have googled an answer.
    And anyone could have googled the most interesting phrases from the email to find if that answer already exists.
  • Tyler (unregistered) in reply to Mike
    Mike:
    Oooh Oooh! I know that one:
    1. return string1 + string2 + string3;

    2. StringBuilder sb = new StringBuilder(); sb.Append( string1 ); sb.Append( string2 ); sb.Append( string3 ); return sb.ToString();

    3. return string.Concat( string1, string.Concat( string2, string3 ) );

    4. return string.Format( "{0}{1}{2}", string1, string2, string3 );

    sub UnnecessarySub { @_ }

  • Pony Gumbo (unregistered) in reply to QuestionC
    QuestionC:
    This doesn't even touch the efficiency issues with constructing SQL statements on the fly.

    DINGDINGDINGDINGDING! Winner!

  • Matt (unregistered) in reply to AuMatar
    AuMatar:
    matthewr81:
    Jesse:
    WTF:
    SQL queries are rarely generated without some sort of dynamic data to alter their structure, so this is a very common task that I've used in just about every web application I've written.

    Can I say SQL injection? That would be why I wouldn't have hired him..

    I really hope that was a joke... if you validate your dynamic date before inserting it you would be fine.

    I am curious how you do insert statements without dynamic data...

    Bind variables

    Variables = Dynamic data (Data that is not always the same)... again you both are reading into this way to much.

  • beagle (unregistered)

    mmm...I smell lawsuit!

    Peter B. could very easily sue Concatcorp's pants off.

  • barfman (unregistered) in reply to AdT
    AdT:
    The right question is: "Why would I want to intermingle SQL code and data in the first place if my development environment does not force me to?"

    Finally, someone who phrased it right! Although sometimes I think people just don't phrase what they mean correctly, yet understand the point correctly, leading to the confusion.

    I have been guilty of this. :)

  • CDub (unregistered)

    I can understand how a screener would get the impression that this was a cut-n-paste job. The reply does sound rather formal and verbose in the way an article or general reference might be. It also pulls in a reference to JS when the question was simply about PHP.

    There's also something to be said for the candidate who, while feeling the pressure to prove their worth and knowledge, is competent and confident enough to provide terse, yet accurate, replies.

  • (cs)

    The real WTF is that as we speak, somebody from Concatcorp is googling "SQL concatenation" and has found this WTF, completing the circle and proving to himself that his instincts were dead on.

  • bshock (unregistered)

    I'm mildly amazed they actually phoned to tell him he didn't get the job. I've missed quite a few positions, but no one has ever bothered calling to tell me.

  • rumpelstiltskin (unregistered) in reply to beagle
    beagle:
    mmm...I smell lawsuit!

    Peter B. could very easily sue Concatcorp's pants off.

    For what?

  • Ian (unregistered)

    This could be challenged. I'd have loved to ask them where they thought he got the description from and to present the evidence to him.

    captcha: waffles...mmm, waffles.

  • Peter B. (unregistered)

    Hey guys. Yes, it's really me. I'm the Peter B. that this story is about.

    I'd just like to quickly dismiss all this nonsense about SQL injection. The code snippet that was part of my answer is clearly not intended to showcase every best practice of web development, but merely got straight to the point of a common use of concatenation.

    These days it's all prepared statements, stored procedures, or libraries like Propel that help us not worry about basic security concerns like SQL injection.

  • mh (unregistered)

    And 6 months later, their "other candidate" gives them this:

    string Paula = "Brillant";
    Paula = "Paula " + Paula;

    (And I know it's even the wrong language...)

  • plagiarist (unregistered)

    Hey, I loved your answer so much that I used it when applying for a job! And I got it! Thanks!

  • BoredGuy (unregistered)

    Something similar happened to me. They said my answers were too good, and I'd therefore be too advanced for the job. They figured I'd get bored and my attitude would suffer being stuck in a basic job (no matter how much it paid). I was prepared to take that chance ... finish my day's work by 10am and then surf the rest of the day ...

  • Doug (unregistered)

    This reminds me of the time I had an interview with BellSouth. They were developing an internet applicatioin, apparently intending to use COM. I got asked to tell them what I knew about working with COM. I gave a pretty technical answer. After a few minutes of outlining COM practices with no feedback from the interviewer, I stopped and asked why they were building on a legacy technology. They had essentially no answer, and attempting to follow up with the guy interviewing me revealed that even though he was the development manager, he had no real clue on using COM. About 6 months later I heard on the local news that the whole division got canned for producing nothing. So I'm somewhat glad I turned out to be overqualified for the position, I can only imagine the quagmire I avoided.

  • Robert (unregistered) in reply to Jesse
    Can I say SQL injection? That would be why I wouldn't have hired him..

    Gee, selecting based on an ID, which has probably already been parsed into an integer type (if it wasn't an integer, may have been set to 0, -1, null, etc.). Less likely, it may have been gotten from a source that already guaranteed an integer, as opposed to an input string. In either case, you wouldn't need to worry about SQL injection.

    My screening test was much more difficult - but at least I got the job.

  • Duke (unregistered)

    My main problem with "Peter" is that he tends to over-think things. In the real-world this can sometimes become detrimental, sometimes being extremely counterproductive. However, you cannot tell from this basic interaction if it was not just him trying to showcase the depth of his knowledge, although it certainly shows tangential tendencies.

    Oh, and to this guy

    Jesse:
    Can I say SQL injection? That would be why I wouldn't have hired him..
    You're an idiot.

  • moskaudancer (unregistered) in reply to Bob

    Awww... Stop making us mere mortals feel so inadequate...

  • (cs) in reply to Mike
    Mike:
    Oooh Oooh! I know that one:
    1. return string1 + string2 + string3;

    2. StringBuilder sb = new StringBuilder(); sb.Append( string1 ); sb.Append( string2 ); sb.Append( string3 ); return sb.ToString();

    3. return string.Concat( string1, string.Concat( string2, string3 ) );

    4. return string.Format( "{0}{1}{2}", string1, string2, string3 );

    [DllImport("msvcrt.dll")] static extern int sprintf(StringBuilder buf,string fmt,__arglist); [DllImport("msvcrt.dll")] static extern int strlen(string s); StringBuilder sb = new StringBuilder(strlen(string1)+strlen(string2)+strlen(string3)+1); sprintf(sb,"%s%s%s",string1,string2,string3); return sb.ToString();

  • Josh L. (unregistered)

    Honestly, I wouldn't have hired the guy. After reading it, I would have thought he was either:

    1. A plagiarizer
    2. Someone who spends far too much time trying to solve a simple problem with something needlessly elegant
  • qdfqsdfqsdfqsdfqsdf (unregistered) in reply to Tyler
    Tyler:
    Mike:
    Oooh Oooh! I know that one:
    1. return string1 + string2 + string3;

    2. StringBuilder sb = new StringBuilder(); sb.Append( string1 ); sb.Append( string2 ); sb.Append( string3 ); return sb.ToString();

    3. return string.Concat( string1, string.Concat( string2, string3 ) );

    4. return string.Format( "{0}{1}{2}", string1, string2, string3 );

    sub UnnecessarySub { @_ }

    I think you mean: sub UnnecessarySub { "@_" }

  • Anonymous Coward (unregistered)

    Just goes to show what people expect of PHP programmers. And that's what you tend to get.

  • Chas (unregistered)

    Wow. I said "brown".

  • Anonymous Coward (unregistered)

    user_id = ; DROP TABLE Articles;

  • Mads Bondo Dydensborg (unregistered) in reply to Martin Ritchie

    Hmm. Thats interessting. Although I have coded almost only C# (well, the occasional perl and shellscript too) for the last year or so, I am not actually sure I could write much of it outside emacs (or another editor). Not that I use intellisense or other stuff like that, but writing real code with a pen is not something I am sure I could.

    Of course, the example is trivial, but still. I think I need a keyboard to actually write some real code in a specific language, as opposed to pseudo.

    Perhaps I should try it out.

  • tieTYT (unregistered) in reply to matthewr81
    matthewr81:
    Jesse:
    WTF: Can I say SQL injection? That would be why I wouldn't have hired him..

    I really hope that was a joke... if you validate your dynamic date before inserting it you would be fine.

    I am curious how you do insert statements without dynamic data...

    Well this person, just like me, probably comes from a Java/C# background. This is an excerpt of how you'd do it in java: PreparedStatement ps = con.prepareStatement("SELECT a FROM t where b = ?"); ps.setString(1, aString); //bind happens here ResultSet rs = ps.executeQuery(); ... //get results

    (Yes yes yes, there is no try/catch/finally here, it's an excerpt) This is how you'd escape aString in Java code. This is better than using a special, separate method called addSlashes() or whatever because that makes it easier for programmer error:

    When did addSlashes get called? Maybe it was in the function that passed aString in? Maybe it was 5 lines above the concatenation? Maybe it's done in the concatenation itself? What if you're wrong and some code gets changed and now you haven't called it at all? What if you're wrong and you called it twice (does that break things?). All these questions are avoided by the Java way of doing it. You only have one option and, fortunately, it has to be done very close to the SQL itself.

    On a side note, one thing that really pisses me off with binding is that when an error occurs, it doesn't tell you what sql it attempted to run, it spits out the sql with the ?'s in it. This makes debugging a huge pain in the ass. Maybe this is done for security reasons but there should be an option to see useful sql.

  • Franz Kafka (unregistered) in reply to Josh L.
    Josh L.:
    Honestly, I wouldn't have hired the guy. After reading it, I would have thought he was either: 1) A plagiarizer 2) Someone who spends far too much time trying to solve a simple problem with something needlessly elegant

    Yeah right. Spitting out a couple paragraphs os standard behavior for something like this - better to be too verbose than too short when you don't have the chance to answer followup questions. If I were writing the response (and I don't know php, so I wouldn't), it's probably take about 5 minutes to give a thorough answer. Not bad for an essay type question.

    The alternative is that they have a laughably low bar for hiring.

  • Sparkfizt (unregistered) in reply to Anonymous Coward
    public String concat(String a, String b, String c)
        {
        	Vector<String> stringVec = new Vector<String>();
        	stringVec.add(a);
        	stringVec.add(b);
        	stringVec.add(c);
        	int alot = 100;//100 sure is alot
        	String result = new String();
    
        	for(int i = 0; i < alot; i++)
        	{
        		
    	    	try
    	    	{
    	    		//strong error checking
    	    		if(stringVec.get(i) != null)
    	    		{
    	    			for(int j = 0; j < alot; j++)
    	    			{
    	    				try
    	    				{
    	    					//very efficient
    	    					result = result + stringVec.get(i).charAt(j);
    	    				}
    	    				catch(Exception e){break;}//something happened so prolly should break
    	    						
    	    			}
    	    		}
    	    	}
    	    	catch(Exception e){break;}//something happened so prolly should break
    
        	}
        	return result;
        }
    
  • Franz Kafka (unregistered) in reply to tieTYT
    tieTYT:
    matthewr81:
    Jesse:
    WTF: Can I say SQL injection? That would be why I wouldn't have hired him..

    I really hope that was a joke... if you validate your dynamic date before inserting it you would be fine.

    I am curious how you do insert statements without dynamic data...

    Well this person, just like me, probably comes from a Java/C# background. This is an excerpt of how you'd do it in java: PreparedStatement ps = con.prepareStatement("SELECT a FROM t where b = ?"); ps.setString(1, aString); //bind happens here ResultSet rs = ps.executeQuery(); ... //get results

    (Yes yes yes, there is no try/catch/finally here, it's an excerpt) This is how you'd escape aString in Java code. This is better than using a special, separate method called addSlashes() or whatever because that makes it easier for programmer error:

    When did addSlashes get called? Maybe it was in the function that passed aString in? Maybe it was 5 lines above the concatenation? Maybe it's done in the concatenation itself? What if you're wrong and some code gets changed and now you haven't called it at all? What if you're wrong and you called it twice (does that break things?). All these questions are avoided by the Java way of doing it. You only have one option and, fortunately, it has to be done very close to the SQL itself.

    On a side note, one thing that really pisses me off with binding is that when an error occurs, it doesn't tell you what sql it attempted to run, it spits out the sql with the ?'s in it. This makes debugging a huge pain in the ass. Maybe this is done for security reasons but there should be an option to see useful sql.

    It does lead to problems with passowrds and other priveleged data, especially if you log things. I wrote a wrapper for prepared statements that dumped the parameters along with the query at one job, and had to make sure some queries weren't wrapped.

  • nwinches (unregistered) in reply to tieTYT
    tieTYT:

    On a side note, one thing that really pisses me off with binding is that when an error occurs, it doesn't tell you what sql it attempted to run, it spits out the sql with the ?'s in it. This makes debugging a huge pain in the ass. Maybe this is done for security reasons but there should be an option to see useful sql.

    It's possible in some cases to create a thin wrapper around the connection which will give you access to the statement after the variables have been bound. Makes it significantly easier to debug some things.

  • nwinches (unregistered) in reply to nwinches

    I was too slow. :-\

  • Jeff (unregistered) in reply to Jesse
    Jesse:
    Can I say SQL injection? That would be why I wouldn't have hired him..

    How do you know he didn't do something to prevent SQL injection? Probably would have been just a little out of scope for the question. Man, if he'd have included that, they would have really thought he triple dog-dare plagiarized?

    Jeff

  • Erik (unregistered) in reply to Scott

    It's a bit nicer to use sprintf to get your string done though, makes the query a bit more readable.

    Still need to escape it though :)

  • Aaron Bassett (unregistered) in reply to Jesse
    Jesse:
    WTF:
    SQL queries are rarely generated without some sort of dynamic data to alter their structure, so this is a very common task that I've used in just about every web application I've written.

    Can I say SQL injection? That would be why I wouldn't have hired him..

    So he is using the getID method of the User object, you do not know what happens withing this method and as such can not say that it returns data likely to be used in sql injection. To me the method name "getID" (note the id) would hint towards the fact that it returns a numeric id so something as simple as:

    return (is_numeric($id)) ? $id : false;

    would be enough within that method to prevent injection.

    Had he said author_id = " . $_GET['userId'] then I would have agreed with you, but as he did not instead I am going to call you an idiot.....idiot.

  • Darien H (unregistered) in reply to Scott
    Scott:
    PHP doesn't support parameterized queries, so you actually have to concatenate the strings. He just left out the part where all user supplied data is passed through a method that escapes it.
    Michael had the right answer earlier. It's a module/library thing.

    At least with Postgres...

    $malicious_attempt = "'; insert into accounts (user,pass) values ('haxor','owned');";
    $dbconn = pg_connect("dbname=foodb");
    $query = "SELECT * FROM footable WHERE owner = $1;"
    $data = array($malicious_attempt);
    $result = pg_query_params($dbconn, $query, $data);
    
  • tieTYT (unregistered) in reply to Peter B.
    Peter B.:
    Hey guys. Yes, it's really me. I'm the Peter B. that this story is about.

    I'd just like to quickly dismiss all this nonsense about SQL injection. The code snippet that was part of my answer is clearly not intended to showcase every best practice of web development, but merely got straight to the point of a common use of concatenation.

    These days it's all prepared statements, stored procedures, or libraries like Propel that help us not worry about basic security concerns like SQL injection.

    I wouldn't take it personally. I think at this point were're discussing for the sake of education. At least that's why I replied. The question didn't ask you how to do it securely.

  • Russbo50 (unregistered)

    While I agree that the answer was a good one. I don't think anyone questioned that. They questioned the presentation of the answer. To be honest I would have questioned the response as well. The thing is that they shouldn't have just accepted the response as plagiarism. They could have called and got a response on the phone. Any idiot who asks a question like that in email is asking to get a plagiarized result.

  • (cs) in reply to Aaron Bassett
    Aaron Bassett:
    Jesse:
    WTF:
    SQL queries are rarely generated without some sort of dynamic data to alter their structure, so this is a very common task that I've used in just about every web application I've written.

    Can I say SQL injection? That would be why I wouldn't have hired him..

    So he is using the getID method of the User object, you do not know what happens withing this method and as such can not say that it returns data likely to be used in sql injection. To me the method name "getID" (note the id) would hint towards the fact that it returns a numeric id so something as simple as:

    return (is_numeric($id)) ? $id : false;

    would be enough within that method to prevent injection.

    Had he said author_id = " . $_GET['userId'] then I would have agreed with you, but as he did not instead I am going to call you an idiot.....idiot.

    It's far easier - and safer - to assume that everything you're given could potentially be unsafe, and always use bind variables. (Which you get with Perl's standard DBI library, and probably exist in some form for all major languages - it's such an obvious help that I expect there's a database library for each platform that does The Right Thing.)

  • Nathan (unregistered) in reply to Jesse

    Is there any particular reason to believe that variable contains user-supplied input?

  • That's Me! (unregistered) in reply to Anonymous Coward
    Anonymous Coward:
    user_id = ; DROP TABLE Articles;
    Let me guess, you'd connect to SQL Server as 'sa', too...

    SQL injection relies on bad practices in DB security almost as much as it relies on bad practices in code. You can't just focus on the front end cause it's easier. If all your ever going to do from an application is select rows, why would you connect to a DB with a user that has privileges to DROP?

    Grrr...

  • Language feature abuse is cool (unregistered) in reply to Random832

    Nice gratuitous use of p/invoke...

    Remember kids, fixed length parameter lists are for chumps :P

    public static string Concatenate(params string[] strings)
    {
        StringBuilder result = new StringBuilder();
    
        for(int i=0; i<strings.Length; i++)
        {
            result.Append(strings[i]);
        }
    
        return result.ToString();
    }
    </pre>
    

    Or, for some tasty abuse of extension methods...

    public static string Concatenate(this string str, params string[] strings)
    {
        StringBuilder result = new StringBuilder(str);
    
        for(int i=0; i<strings.Length; i++)
        {
            result.Append(strings[i]);
        }
    
        return result.ToString();
    }
    
    ...
    
    string foo = "Beep".Concatenate("Boop", "Bop", "Fizzle");
    </pre>
    
  • Language feature abuse is cool (unregistered) in reply to Language feature abuse is cool

    Yeaarrrg... it snipped the post i be replyin' to sez I!

  • Aaron Bassett (unregistered) in reply to skington
    skington:
    Aaron Bassett:
    Jesse:
    WTF:
    SQL queries are rarely generated without some sort of dynamic data to alter their structure, so this is a very common task that I've used in just about every web application I've written.

    Can I say SQL injection? That would be why I wouldn't have hired him..

    So he is using the getID method of the User object, you do not know what happens withing this method and as such can not say that it returns data likely to be used in sql injection. To me the method name "getID" (note the id) would hint towards the fact that it returns a numeric id so something as simple as:

    return (is_numeric($id)) ? $id : false;

    would be enough within that method to prevent injection.

    Had he said author_id = " . $_GET['userId'] then I would have agreed with you, but as he did not instead I am going to call you an idiot.....idiot.

    It's far easier - and safer - to assume that everything you're given could potentially be unsafe, and always use bind variables. (Which you get with Perl's standard DBI library, and probably exist in some form for all major languages - it's such an obvious help that I expect there's a database library for each platform that does The Right Thing.)

    right so I have written a function getId who's purpose is to fetch an id from whatever source (user input, session, db, whatever) validate/cleanse it and return it yet I am to assume that it is potentially unsafe?

    But I wrote the method, I know that it returns a valid value. Why should I assume it is unsafe?

    And if I do assume it is unsafe what should I do? Cleanse/validate it again? But what if the methods I use to cleanse/validate it return an unsafe value, should I do it twice to be sure, three times....when does the madness end!!! ;)

    I understand what you are saying but it is not feasible for web applications (which is what php is going to be used for in the majority of cases) which may accept a large amount of user input. Instead it is better to rely data cleansing and validation.

    ie: Ensuring that when you are looking for a numeric id thats what you get (pssst which would be is_numeric($id) - you know like i said earlier)

  • Snor (unregistered) in reply to Jesse

    Uhh, it's not hard to validate input.

  • gotitfirsttime (unregistered) in reply to Martin Ritchie

    return "MartinDonaldRitchie";

  • tieTYT (unregistered) in reply to Aaron Bassett
    Aaron Bassett:
    right so I have written a function getId who's purpose is to fetch an id from whatever source (user input, session, db, whatever) validate/cleanse it and return it yet I am to assume that it is potentially unsafe?
    Because there is no one-true-way to cleanse something. How do you know getID cleanses for SQL? Maybe it cleanses for XSS? Really, with a name like getID, it shouldn't be validating/cleaning anything. You may use it 6 months from now and be very confused about the results you got because they were validated/escaped even though the name of the method gave no indication that that was going to happen.
    But I wrote the method, I know that it returns a valid value. Why should I assume it is unsafe?
    What if you didn't write the method? What if someone else needs to use your method? What if you haven't used this method in 6 months? All of these force you to care about the implementation of the method instead of its interface: This is a bad thing.
    And if I do assume it is unsafe what should I do? Cleanse/validate it again? But what if the methods I use to cleanse/validate it return an unsafe value, should I do it twice to be sure, three times....when does the madness end!!! ;)
    You do it where it matters and/or where it improves responsiveness: You do it as it's being used in the sql and/or on the client's browser so you don't waste time sending it over the wire.
  • snoofle (unregistered) in reply to BoredGuy
    BoredGuy:
    Something similar happened to me. They said my answers were too good, and I'd therefore be too advanced for the job. They figured I'd get bored and my attitude would suffer being stuck in a basic job (no matter how much it paid). I was prepared to take that chance ... finish my day's work by 10am and then surf the rest of the day ...
    The same thing happened to me in a recent job interview. The headhunter told me that they were really looking for a top-flight guy, and to go in with the intention of really impressing them with my accomplishments. They asked me about my responsibilities at my previous position. I mentioned that I had managed 25 people. It turns out that my prospective bosses boss only managed about 25 people, and they were just looking for a junior programmer. Sigh.
  • (cs) in reply to AdT
    AdT:

    ...

    This is what I was thinking, too. Though, maybe they had other reasons for dismissing him and didn't want to tell the truth. E.g. they might have thought him overqualified for the job and thus (probably) too expensive. Then maybe they were simply the morons that they appear to be.

    They would have to be incredible morons to libel him as an alternative to telling him they decided to hire someone else. So, I think this little story smells. While IANAL, being turned down with a spurious accusation sounds actionable to me.

    I signed in (sometime in 2005). No captcha, sorry.

Leave a comment on “Good Answer... Perhaps TOO Good”

Log In or post as a guest

Replying to comment #:

« Return to Article