I'm afraid I have to disagree with your conclusions on serialization/deserialization risk.
This is a severely bad idea, unless you really want malicious players to have free run of your game - both client and server.
The format of the packets -- whether JSON, XML, ASN.1-BER, or your custom binary serialization format -- does not change your security model at all.
This isn't actually true. The more generalized your serialization/deserialization is, the worse its security posture is. The worst being of course, deserialization into arbitrary code (ala JSONP or YAML). The recent issues in the Rails community should highlight that.
My point is transmitting executable code as a communication mechanism does change your security profile. To make it secure you have to basically strip out all execution potential from your data stream and the interpretation mechanisms, at which point you may as well just use an existing serialization mechanism in the first place.
You're right, this is side tracking. The argument that sending executable code is unsafe isn't particularly strong IMO.
Sending code from the server to the client is done all the time, even for native code: That's what a patcher does!
Again, this is a bad example. There are so many badly written patchers out there that there are a whole class of "Evilgrade" vulnerabilities, where an attacker can impersonate the update service and run arbitrary code.
To pull things back to the original question, JSON is actually a reasonable choice, with a couple of caveats.
The first is never use JSONP. The second is to make sure that the JSON parser you are using is not calling a more dangerous parser behind the scenes (as in a recent Rails issue).
I would certainly use JSON over a languages generic object serialize/deserialize functionality; you want to make sure that you can strictly control the output of the parsing of untrusted data, and anything that looks like "object Deserialize( byte rawNetworkData)" (in whatever language you are using) is inherently unwise.