Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.x]: URL passthrough rewrite failing when using actionInput #15041

Closed
WHITE-developer opened this issue May 21, 2024 · 17 comments
Closed

[4.x]: URL passthrough rewrite failing when using actionInput #15041

WHITE-developer opened this issue May 21, 2024 · 17 comments

Comments

@WHITE-developer
Copy link

What happened?

Description

Got this from: https://craftcms.stackexchange.com/questions/41657/url-passthrough-rewrite-failing-when-using-actioninput

We are experiencing some issues with form submissions on websites that are using action inputs.

If a visitor denies analytics_storage via a cookie consent plug-in. Google Tagmanager will start using the URL passthrough function to pass the GCLID and other data otherwise stored in cookies by rewriting all URL's on a page.

This rewriting also happens on form submissions and will try to change the "action" attribute on the submitted form. To do this, the Google JavaScript tries to read the action parameter of the form and that's where things go wrong. Reading the action attribute of a form that's using the actionInput tag returns the complete HTMLInputElement instead of the action string. And Google appends that complete object to the rewritten action attribute. Resulting in a form that's submitted to: "/[Object HTMLInputElement]?GOOGLE_STRING". Which obviously doesn't work.

Contacting Google about this issue seems like a pretty lost cause. But is there any way to solve this in our website or Google Tagmanager settings without disabling the URL passthrough?

Steps to reproduce

  1. Click from a google ad to the site
  2. Errors when adding to cart, accept cookies and other form submission

Craft CMS version

4

PHP version

8.2

Operating system and version

No response

Database type and version

No response

Image driver and version

No response

Installed plugins and versions

No response

@brandonkelly
Copy link
Member

Rather than using a nested action param within your form, can you try setting the form’s action argument to {{ actionUrl('controller/path') }}?

@WHITE-developer
Copy link
Author

Hi Brad,

I've tried this, but it doesn't fix the problem. Any other ideas?

@brandonkelly
Copy link
Member

Hm, that’s surprising. What happens?

@WHITE-developer
Copy link
Author

WHITE-developer commented Jun 6, 2024

I'm still getting /[Object HTMLInputElement]?GOOGLE_STRING

I tested it with a "user/login" form. It doesn't work then.

<form method="post" class="checkout-form needs-validation" accept-charset="UTF-8">
{{ csrfInput() }}
<input type="hidden" name="action" value="{{ actionUrl('users/login') }}">
{{ redirectInput(CHECKOUT_ADDRESS_URL) }}

@brandonkelly
Copy link
Member

Sorry, that’s not what I meant. I’m saying remove the action input, and use an action param on the <form> element instead:

<form method="post" class="checkout-form needs-validation" accept-charset="UTF-8"
  action="{{ actionUrl('users/login') }}"
>
    {{ csrfInput() }}
    {{ redirectInput(CHECKOUT_ADDRESS_URL) }}

@WHITE-developer
Copy link
Author

Hi Brandon,

sorry for the late reply, but this works. Thanks!

@brandonkelly
Copy link
Member

Sweet, glad to hear!

@masiorama
Copy link

masiorama commented Jun 20, 2024

This is an issue for me on Craft 5 too... @brandonkelly what you suggested is not working for me, I switched password reset form from

<form method="post" accept-charset="UTF-8">
    {{ csrfInput() }}
    {{ actionInput('users/send-password-reset-email') }}
    {{ redirectInput('shop/customer/sign-in') }}
   ...

to

<form method="post" accept-charset="UTF-8" action="{{ actionUrl('users/send-password-reset-email') }}">
    {{ csrfInput() }}
    {{ redirectInput('shop/customer/sign-in') }}
   ...

The errors simply switches from 403 to page not found, since the server tries to load this address:

https://sale.colombomilano1911.com/index.php?p=actions/users/send-password-reset-email&GOOGLE_STRING

You can test it here: https://sale.colombomilano1911.com/shop/customer/forgot-password
No need to fill the input text.

@masiorama
Copy link

Any suggestion on this? I'm kinda lost on how to handle this thing, if it's related to some bug on craft or if the matter is totally guilt of GA.

@brandonkelly
Copy link
Member

@masiorama

I just tested that locally and it worked, so I’m guessing it’s more of a server configuration issue.

The errors simply switches from 403 to page not found, since the server tries to load this address:

https://sale.colombomilano1911.com/index.php?p=actions/users/send-password-reset-email&GOOGLE_STRING

@masiorama Just tested on your site, and I get a 404 response from https://sale.colombomilano1911.com/index.php?p=actions/users/send-password-reset-email, not a 403. (And no Google-added query string params in the URL.)

I just tested your code snippet locally, and the users/send-password-reset-email action is called successfully. So I’m guessing this is a server misconfiguration issue somehow. Not totally sure what to look at, though.

@brandonkelly
Copy link
Member

Does the form work locally for you?

@masiorama
Copy link

The errors simply switches from 403 to page not found, since the server tries to load this address:
https://sale.colombomilano1911.com/index.php?p=actions/users/send-password-reset-email&GOOGLE_STRING

@masiorama Just tested on your site, and I get a 404 response from https://sale.colombomilano1911.com/index.php?p=actions/users/send-password-reset-email, not a 403. (And no Google-added query string params in the URL.)

Sorry, I didn't mention: you have to accept cookies to switch GA tracking on (due to GDPR here in Italy).

I just tested your code snippet locally, and the users/send-password-reset-email action is called successfully. So I’m guessing this is a server misconfiguration issue somehow. Not totally sure what to look at, though.

Does the form work locally for you?

Well, your simple question pointed me to this: since locally (dev env) I do not include tracking scripts I am not sure, so I will turn it on and debug. I thought, as you do, that the problem is server misconfiguration so it didn't come to my mind, but I will check on dev env just to confirm that theory.

Thanks, I will keep you posted.

@masiorama
Copy link

Hi @brandonkelly sorry for the delay, hectic days recently.

I will work in the next couple of days and keep you posted.

@masiorama
Copy link

@brandonkelly I get the same behavior on local dev.
I'm totally lost on this and indeed I keep getting 404.
To reproduce the scenario on prod env:

  1. access this url: https://sale.colombomilano1911.com/shop/customer/sign-in
  2. on the cookie banner, click Rifiuta tutto (reject all)
  3. click on link "Password dimenticata?" (Forgot password?) you should be getting the url with google tracking appended (otherwise the test is not worth it)
  4. then click on "Invia" to send the form empty

In this scenario you should get the 404, as this are not working (without google tracking we get .
The problem is that the url in the address bar is https://sale.colombomilano1911.com/index.php?p=actions/users/send-password-reset-email&_gl...

  1. If you remove the &gl... stuff you get a "Ops post request required" error in place of the 404, which is compliant with what you should expect targeting that url on the address bar as a get request.

So the point is that with that google stuff appended on the url Craft is not able to correctly read the route, am I right?

I have no clue if my hypotesis could be right or even if I was able to explain my idea in proper english.
Hope this whole rant makes sense somehow, since I'm stuck with a project I should have published 1 month ago :(

Thanks for any hint/help/idea.

@masiorama
Copy link

Hello, sorry to bother @brandonkelly any thoughts on this? Just to point me to the right direction (more exclude an option).

@brandonkelly
Copy link
Member

@masiorama Just got around to looking into that again.

I’m not sure exactly what the problem is, but it’s not with the _gl query string param.

You can verify by opening your Network tab, then submitting the form, then inspecting the 404 request, and creating a new POST request to the same URL sans-_gl param, and the same form data, from your console:

fetch('https://sale.colombomilano1911.com/index.php?p=actions/users/send-password-reset-email', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    CRAFT_CSRF_TOKEN: '...',
    redirect: '...',
    loginName: 'you@domain.com'
  })
})

When you submit it, you’ll get the same 404 response back.

So something on your server isn’t handling POST requests to action URLs properly, it seems.

Screenshot of the browser Network tab and console, demonstrating the failed request

@masiorama
Copy link

Thenks @brandonkelly I will dig into it and keep you posted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants