To elaborate on this part of Ugam Kamat's excellent answer: "When you sign the transaction with your private key, you include the hash of the entire transaction data as a message."
The function that turns the transaction into a hash to be signed is not just any hash function; in the code it's called a "sighash" or "signature hash". Each signature contains encoded flags called "sighashflags" which answer the question: "
Which parts of the transaction shall be hashed, and which parts shall be ok to modify without invalidating the signature?"
The way signature hashing works pre-segwit is a bit messy, and I don't remember it well enough to lay it out in detail, but you can find it in the source code for the class CTransactionSignatureSerializer.
Post-segwit, there is a specification for the signature hash function in BIP 143: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki . (It also describes some of the issues the old version a bit, under "motivation")
The SIGHASH_NOINPUT proposal (see e.g. https://github.com/bitcoin/bips/blob/master/bip-0118.mediawiki , although I'm not sure how current that is) would allow a new type of signature hashing, which does not include the transaction inputs into the signature. This would, in fact, allow the same signature to be reused multiple times to cash out coins from the same address! HOWEVER, there are still restrictions that would make it not as bad as you fear: (1) The outputs are still signed, so the person replaying the signature can't change the destination of the coins. (2) The signer has to CHOOSE to use this mode; an attacker can't change the sighashflags of a signature.
Even despite those restrictions, there were concerns that people could be harmed by using this mode without understanding all the possible consequences. I'm not sure what the current state of the proposal is.