Hi Ross,
I was not able to stop OTP spraying. I don't think it can be stopped as the server action is called multiple times with different OTPs by some tools like BurpSuite.
I have done some work around to prevent the tool from getting the valid OTP. And, when the pen testing team retested this issue it got passed.
Please find below what I have done.
1. Encrypting input and output parameters of the server action.
I have serialized and encrypted the the serialized string and sent it as the input parameter so that it cannot be read by the attacker. Then decrypted the input parameter inside the server action and de-serialized it. The same way I encrypted the response output parameter from the server action so that the attacker won't be able to identify if the response is valid or not. Then decrypted it in client side.
2. Restrict multiple attempts by restricting the user for a specific number of attempts.
I set a site property with the limit of attempts(3 in my case) for OTP. Then in the server action to validate the OTP, if that limit is reached I returned an error response. I had this logic in client side already, but it was not getting validated in server action. Hence the attacker was able to attempt multiple times and get the valid response after some attempts. Now I added this logic in server action also. Hence, when the attacker try to spray OTP from burp suite, after 3 attempts he will always get the error response from server action.
Hope this helps to resolve your issue as well.
Sundeep.