Consulta parametrizada
O comando vai com um espaço reservado, e o valor vai por fora, como dado, nunca como comando.
A defesa definitiva contra injeção de SQL é a consulta parametrizada (também chamada prepared statement). Em vez de colar o valor dentro do texto do comando, você escreve o comando com um espaço reservado e entrega o valor separado. O banco recebe os dois por canais diferentes e nunca interpreta o valor como parte do comando.
O inseguro, colando o texto:
cur.execute("SELECT * FROM users WHERE name = '" + name + "'")
O seguro, com parâmetro:
cur.execute("SELECT * FROM users WHERE name = ?", (name,))
O espaço reservado muda com a biblioteca: ? (SQLite, muitos drivers), %s (psycopg, MySQL), :nome (nomeado). Em todos, uma aspa, um OR '1'='1' ou um UNION dentro do valor viram só texto procurado, nunca comando. Como bônus, o banco reaproveita o comando já analisado, o que costuma ser mais rápido. A regra é simples: nunca monte SQL com + ou interpolação de texto; sempre passe os valores como parâmetros.