How is it possible that a transaction with an invalid signature was able to be validated?
Because the Script required any invalid signature.
There are many things, which can be done by scripts: you can require a single key, multiple keys, or even no keys at all. Or: you can also require some valid signature, some invalid signature, some identical signature for the same public key, some different signature for the same key, or even some valid signature, which will take less than N bytes. There are a lot of options, probably much more, than people already tried.
Classically, you can have something like that: "<pubkey> OP_CHECKSIG". However, nothing stops you from doing "<pubkey> OP_CHECKSIG OP_NOT" instead, which would require any invalid signature, and will be strictly rejected, if you make a valid one. Or you can even use "OP_CHECKSIG" alone, and it would then require any valid key, with any valid signature. Or even "OP_CHECKSIG OP_NOT", to accept anything, what wouldn't pass through OP_CHECKSIG for various reasons.
transactions like this were more costly to verify and therefore it was advisable not to allow them
Yes, because using OP_CODESEPARATOR will enforce re-hashing transaction data. And even if producing some invalid signature is trivial, then validating it requires similar effort, as checking some valid one, because you have to be 100% sure, that nobody produced a matching signature.
And also, slow things can be combined. So, you can mix OP_CODESEPARATOR with OP_CHECKMULTISIG. And in case of Taproot, you can make even more tricky cases, like "OP_SHA256 OP_CHECKSIG OP_NOT", which would hash your message, use it as x-value of your public key, and make sure, that it won't pass Schnorr signature verification.