Gregwar / CaptchaBundle

Symfony bundle implementing a "captcha" form type
MIT License
344 stars 127 forks source link

First captcha on page always returns bad code #171

Open verschoof opened 7 years ago

verschoof commented 7 years ago

Hi,

I have a page with 2 forms and both has a captcha code. But the first captcha is always giving a bad code, the second captcha is working normal

Symfony version:

v3.0.9

config.yml:

gregwar_captcha:
    reload: true
    as_url: true

FormTypes:

->add('captcha', CaptchaType::class, [
    'label' => false,
])

How to solve this?

rashid-mycnw commented 7 years ago

Same problem with me as well

        "name": "gregwar/captcha",
        "version": "v1.1.1",
        "source": {
            "type": "git",
            "url": "https://github.com/Gregwar/Captcha.git",
            "reference": "1240ab993ca713680573b2d4166900da5f758623"
        },

"name": "symfony/symfony", "version": "v2.8.13", "source": { "type": "git", "url": "https://github.com/symfony/symfony.git", "reference": "d04e2eb13ae63068fc8862530b403756e3702896" },

Gregwar commented 7 years ago

Does your forms have different names?

Le mer. 28 déc. 2016 20:31, rashid-mycnw notifications@github.com a écrit :

Same problem with me as well

    "name": "gregwar/captcha",
    "version": "v1.1.1",
    "source": {
        "type": "git",
        "url": "https://github.com/Gregwar/Captcha.git",
        "reference": "1240ab993ca713680573b2d4166900da5f758623"
    },

"name": "symfony/symfony", "version": "v2.8.13", "source": { "type": "git", "url": "https://github.com/symfony/symfony.git", "reference": "d04e2eb13ae63068fc8862530b403756e3702896" },

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Gregwar/CaptchaBundle/issues/171#issuecomment-269527690, or mute the thread https://github.com/notifications/unsubscribe-auth/AAWZrn-cW8XuvLF8geOmwLGpOK2ilcDBks5rMrkCgaJpZM4LPpoj .

Gregwar commented 7 years ago

@verschoof @rashid-mycnw does your forms both have the same name? The form name is used for session key, so having two forms with the same name is a problem (that could be fixed)

rashid-mycnw commented 7 years ago

I don't think I understand the question correctly. There is just one form. I have a form class and within it $builder->add('captcha', CaptchaType::class , [ 'width' => 200, 'height' => 50, 'length' => 4, 'reload' => true, 'as_url' => true, 'required' => true, 'attr' => ['class' => 'form-control captcha-img'] ])

Now when I submit a rendered form- it will always show the captcha value was wrong ("Code does not match") first time I submit it. After I fill in the captcha again, it will submit the form (accept the captcha).

verschoof commented 7 years ago

@Gregwar Nope, 2 total different form names. Should I be able to see those 2 sessions in the Symfony Profiler?

rashid-mycnw commented 7 years ago

That could be the problem. I can see only one form (my main form) in the profiler. This is true even when I submit the form successfully

After I fill in the captcha again, it will submit the form (accept the captcha).

verschoof commented 7 years ago

@Gregwar any ideas?

lalop commented 7 years ago

any news on this issue ? I get the same error

lalop commented 7 years ago

I think I get the error on my application, a second request is send to the same page so an other phrase is generated

Gregwar commented 7 years ago

You can investigate this with the profiler How the second request is generated and why?

lalop commented 7 years ago

the second one comes from an image with an empty path

Le 22 mars 2017 21:55, "Grégoire Passault" notifications@github.com a écrit :

You can investigate this with the profiler How the second request is generated and why?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Gregwar/CaptchaBundle/issues/171#issuecomment-288536527, or mute the thread https://github.com/notifications/unsubscribe-auth/AATHHUkPQzn_1zp132BjAfg6cLIek5dCks5roYqlgaJpZM4LPpoj .

Gregwar commented 7 years ago

Alright, here is your bug :-)

lalop commented 7 years ago

@Gregwar why dont use the same logic than csrf token to store the data in session ? Like that we can have has much captcha has we want on a single page

Gregwar commented 7 years ago

@lalop, it's already the case, but you have to give different name to the captcha fields since it's used to match it in the session If you think we could do better feel free to propose a PR to improve this

lalop commented 7 years ago

I will try ;)

Gregwar commented 7 years ago

Here is the key that is used in the session to validate the captcha: https://github.com/Gregwar/CaptchaBundle/blob/master/Type/CaptchaType.php#L68

Thus, if the field name differs it should be OK to have two captcha on the same page

lalop commented 7 years ago

I have seen this but this return the input name not the form name. I'm looking for the csrf logic, it seems that the key isn't regenerated as long as the form isn't submited, so if we have the same form twice the token is the same. This two things are the key of our issue

Gregwar commented 7 years ago

OK, but in your case can't you give different input names? Like "registerCaptcha" and "loginCaptcha"?

lalop commented 7 years ago

I could for some of them, but on one page I have multiple form of the same type...

Gregwar commented 7 years ago

Ok, Maybe what you want then is what is called intention http://symfony.com/doc/2.0/reference/forms/types/csrf.html#intention

Gregwar commented 7 years ago

(Which is now called csrf_token_id)

lalop commented 7 years ago

we need this https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php#L85

lalop commented 7 years ago

humm... you was right with the csrf_token_id

lalop commented 7 years ago

Giving some other tests I think your naming process is right. The key isn't the issue, the issue comes from the fact the captcha's value in session is regenerated for each captcha with the same name. In symfony the csrf value in session never change for a form even if the form is submitted. This could be a solution here as long as the user doesn't reload the captcha.

Maybe an other solution could be to store a kind of salt in session and add an hash in an hidden field in the form, like that we can compare the hash and the captcha to validate the form and reload the captcha as much as we want without invalidate other form.

Do you think that could be a solution ?

Gregwar commented 7 years ago

At the symfony level, how the forms are distincted when receiving post data? Is the form action different? That would be a difference

Gregwar commented 7 years ago

A good and simple solution would be simply to give different names for captcha fields You could add an option to your form to achieve this

lalop commented 7 years ago

This doesn't solve the problem when a same page is open in two different tabs

kadlama commented 3 years ago

Hi, I got the same error above. Finding the source of the error was difficult. When using Symfony Dynamic Generation for Submitted Forms, the error "Code does not match" is received on the first post action because the form is updated with ajax. Since ajax is not run in the second and the generated code is re-entered, there is no problem in the second.

To solve this I did not do the ajax part as in symfony documentation. I had to create a separate method and update my form. This is how I solved the problem.

But how can we do this using symfony form builder. Any ideas?