• Do prepared queries mean that we let the attacker think they've gotten in, when in reality we just execute our own code with their input?

    No. It just means that their injected code doesn't have any effect. If someone puts "rm *" into a python string, that doesn't delete all your files, though it would if you were to (foolishly) execute that string.

  • Can you re-explain SQL injection on the board please?

    Sure, I'd be glad to.

  • I'm still a little unclear on how prepared queries avoid the issue of an injection attack, couldn't extra information that alters a database still be added in the 'list_of_values' parameter when running curs.execute(sql_with_placeholders, list_of_values)?

    Yes, but it won't be executed. It's just passive data at that point.

  • Why does %s prevent string inputs from being treated as extra code to run? Something about the separation of preparation and execution? Does the executer throw an error if it gets extra material where a single input was expected? Can you use %s to search a database of sql commands?

    Yes, it separates the code (that will be parsed and executed) from the inputs to that code.

    If you provide too many or too few values, you'll get an error, just like you would with giving a function too many or too few arguments.

    I don't know what you mean by using %s to search a database of SQL commands. If we had a database table filled with a varchar column of strings containing SQL commands, we could search it like any other table that contains text. But we shouldn't execute those commands.

  • So can %s be a value of any length?

    Yes.

  • If PyMySQL doesn't use prepared queries, then why isn't it vulnerable to SQL injections? What does it do instead?

    PyMySQL does an excellent approximation of prepared queries, gaining the same effect, so we will treat it as if it's the real thing.