The problem isn't so much that you're sending the assertion directly from the browser to the verification service, but rather about what happens right after that.
If the server is the one performing the verification (by sending it to verifier.login.persona.org
) then it knows that the assertion is valid because it checked itself. A hostile user cannot intercept and tamper with the communication between the server and the verification service. So the server can create a session for the user and set a cookie. That's all good.
On the other hand, if the client is doing the verification, then how is the session created? Perhaps the client code checks that the assertion is valid and then calls /create_session
on the server? The problem here is that the server needs to trust that when the client asks for a session to be created, it has actually done the check.
Client code running in a user's browser cannot be trusted because it can easily be changed (e.g. using the developer tools) by users. So while you're sending me JavaScript code that properly checks assertions, I could modify that check to skip the assertion check and just lie to your server when asking for a new session to be created.