I am using a Postgres 9.3 database as a back-end for a web application. I use PHP 5.5.7 to connect to the database and return JSON for the front-end AJAX calls.
I'm trying to decide on where to put the user authentication logic.
I am not a security expert; however, I am familiar with PHP's new password_*()
functions and I have a strong grasp of what is going on under the hood. I am also familiar with the Postgres Extension pgcrypto
and the associated crypt()
function.
My question is, does it make sense to use PHP or Postgres to hash passwords?
I was curious as to how these functions differ, so I made a password hash in PHP and then gave it to Postgres to see if Postgres uses the same algorithm. Given the same parameters, Postgres returned a different result when compared to PHP (not unexpected, but with noting).
PHP
password_hash('password', PASSWORD_BCRYPT, ["cost" => 15]);
output: $2y$15$o8JufrnVXoob2NKiEGx6.uI4O2D4VcaAmY7WtNq5zPFiJow4KohGu
Postgres
SELECT '$2y$15$o8JufrnVXoob2NKiEGx6.uI4O2D4VcaAmY7WtNq5zPFiJow4KohGu' = crypt('password', '$2y$15$o8JufrnVXoob2NKiEGx6.uI4O2D4VcaAmY7WtNq5zPFiJow4KohGu')
output: false
PHP vs. Postgres
Given that these processes are different, I wonder if one is better then the other? Is one more, or less, secure?
Some other thoughts:
I currently have all logic stored in the database (in views, functions, constraints, etc.) so if I ever need to use a different front-end I don't have to worry about missing logic. Calculating password hashes in PHP would effectively require all requests to pass through PHP to access the database.
On the other hand, putting the logic in the database would allow me the flexibility to use other connection options; however, all of the Postgres queries are logged. I can't disable the logs because of the WAL used in replication. This seems like a big security hole.
Am I on the right track here? What am I missing?
EDIT
I just looked at another message thread and found some more information.
- Putting the logic in Postgres would require the database to processes and perform the hash operation. This would be a bad thing for other users and batch jobs that need those resources.
- Not only would the hash slow down normal operations, it would make the whole system more vulnerable to DOS attacks.
Our simple web servers with load balancing would address both issues...
Again, am I on the right track here? What else am I missing?