Part of this is blatantly wrong. “PlayerControllers are only on server side” is incorrect. Granted I do not know how this played off in May 2015, but the PlayerController is replicated ONLY for the player that owns it. Meaning the client has only a single PlayerController instance on their machine - namely their own controller - while the server replicates the various controllers to the respective clients. This is extremely important for client-server communication as it allows processing of input through RPC events easily without even having to worry who the events are replicated to.
“PlayerState is extension of PlayerController” is also wrong. PlayerState is its own class hierarchy and the first parent class the two share is AActor. PlayerState is, as Duncan Dam pointed out, designed to store data across sessions. It is a form of container, not a form of controller.
When it comes to security, the server should always sanitize player input. In your MOBA example, the server simply shouldn’t accept the request to trigger a spell twice within 0.5 seconds when the cooldown is supposed to be 3 seconds. Of course the fact PlayerControllers aren’t replicated across all clients helps greatly and might be one reason for this implementation. But it certainly is not enough to protect your game.