If I'm reading the question right, you're concerned with the clear password getting grabbed before it's mined, then used by an attacker with more gas. If so, this is a rephrasing of the frontrunning problem (here's a link to how it's described on Ethereum's wiki). Zero-Knowledge proofs are an option, but may be overkill. Let's explore some other options.
Modifiers if you know all addresses that will need to access this function, you can use a modifier to whitelist them.
addresses_with_access = [0x...,0x...,0x...];
modifier onlyPrivileged {
privileged = false;
for (uint i=0; i < addresses_with_access.length; i++) {
if(msg.sender === addresses_with_access[i]){
privileged = true;
break;
}
}
require privileged;
}
function checkPassword(string cleanPassword, string newPasswordHash) onlyPrivileged {
(That is, in Solidity. Vyper doesn't have modifiers. Your code above is in Solidity, though, and if you'd like Vyper, you can have a list of addresses and assert that msg.sender is a member of the list at the beginning of the function with.)
def checkPassword(string cleanPassword, string newPasswordHash):
assert msg.sender is in addresses_with_access
Precommit if you can implement a pre-commit, that should be enough. Here is another EthStackExchange Q&A about that. I'm not sure this will help all they way. It may be able to stop frontrunning, but not griefing. Griefing is where the attacker can't steal your information and perform the tx themselves, but can still stop you from doing what you want to do.
Submarines there is a library dedicated to submarine transactions to defeat frontrunning. Their website is here, repo, HackerNoon article.
Update: Just found an OpenZeppelin article here that talks at length about solutions to mitigate frontrunning, and contains solutions not discussed here (in addition to submarines and commit/reveal).