Contracts can be upgraded if they're designed that way. You can have a wrapper contract that just calls out to other contracts, where the addresses of the other contracts are updateable. You can even make the callee run in the context of the caller, so all the data is held at the caller, which calls an external function that manipulates it.
Doing this is a tradeoff. On the one hand it lets you fix bugs and vulnerabilities, on the other your users have to trust you not to abuse your power.