How to handel the cHash on a get form? - typo3

I'm using TYPO3 9.5 and building a search Extension with extbase and have some problems with the cHash.
I build my search form in fluid with f:form and use GET as method. There are no problems if I use POST.
My search action is configured as non-cachable action. I also tried to set the TypoScript config requireCHashArgumentForActionArguments = 0 for my extension.
But every time I try to search, I get a 404. Even when I let the form viewhelper generate a cHash. The only workaround that is working, is to disable pageNotFoundOnCHashError in the LocalConfiguration. But that feels wrong to me.
The action works also if I create a Link with fixed search words.
So there are some questions that came up to me.
Why is a cHash for a non-cachable action needed?
How can the cHash work on a form at all? It's the concept of a form that the user can modify the values, and as far as I understand it is the concept of the chash to prevent this.
Here is also some example code
<f:form
id="search-form"
class="press-search-widget"
additionalAttributes="{'role': 'search'}"
method="get"
action="search"
extensionName="MySearch"
pluginName="Mysearch"
controller="Search"
section="search-form" >
<f:form.textfield
id="pressfilter-search"
class="form-control"
type="text"
name="searchTerms[searchTerm]"
value="{parameters.searchTerm}"
placeholder=""
/>
</f:form>

Why is a cHash for a non-cachable action needed?
cHash is evaluated before it is known which TypoScript should be fetched, so it is also not known which (un-)cached plugins should be loaded or if they require cHash evaluation (or have it disabled).
How can the cHash work on a form at all? It's the concept of a form that the user can modify the values, and as far as I understand it is the concept of the chash to prevent this.
I don't know the reason of you using a form submission with HTTP GET. However all GET parameters are taken into account except for the ones excluded (see response above already).
I strongly recommend switching to HTTP POST - mainly because the HTTP standard requires POST parameters to not be cached (also not in the browser!), otherwise Visitor A could submit something with the form and Visitor B sees the result from Visitor A. POST is for data submission, GET is actually defined as a "read-only" mode in HTTP.
Two options for TYPO3 are:
switch to POST if there is no 100% necessity for GET in your use case
use the cHashExcludedParameters option in TYPO3 to disable all user-input values from the form.

cHash is a security feature. It protects against maniuplation of parameters. And servers as an additional layer of security it also prevents a cache bloat attacks.
Where a bot can generate links with new parameters and TYPO3 then caches the result of every such page and quickly grow the cache tables in the database.
It is however possible to exclude certain parameter from this caluculation using the install tool: [FE][cHashExcludedParameters] setting.
The excluded parameters then also do not affect the caching. (pages are cached as if the parameters are not present) but as you have a non-cacheable-action your result has to be generated on the fly anyway.

Why is a cHash for a non-cachable action needed?
I dont really know. Maybe they just forgot it or no one really uses GET forms.
How can the cHash work on a form at all? It's the concept of a form that the user can modify the values, and as far as I understand it is the concept of the chash to prevent this.
The URL parameters are included in the chash. So sending via POST shouldnt take use of the chash except for the action/controller parameters.
You have to build the form by yourself and validate it manually or use Javascript. Indexed_search uses POST, changes the page/pointer ind the hidden form fields and submits the form again for the pagination.

Related

Store TYPO3 fluid request variables (i.e. searchform) for bookmarks

What's the best practice to be able to store fluid form variables as a bookmark (for simple search filter storing)?
We have a simple extbase&fluid plugin that shows searchfilters and searchresults. The filters are a collection of input and select fields, all created with . Fluid puts in a lot of extra parameters with _referred information and chash's into the request.
Now we want a visitor to be able to bookmark a search result easily. If we use a HTTP GET request, the URL sadly exceeds the URL variable limit because of all the extra parameters; and without them, the fluid plugin won't take on the arguments (unless we disable caching of the whole page?).
The best way (imo) is to generate a clean url that can be stored. In Fluid you can add a link with only the parameters you need and add an onclick event with JS to add this link as a bookmark.
<f:link.action action="yourAction" controller="yourController" arguments="{filterArguments}">Add Bookmark</f:link.action>
How to add the bookmark function with js(jQuery):
How do I add an "Add to Favorites" button or link on my website?
It is also a good practice to configure realurl to produce nice urls for your extension

What portions of the marketo code snippet can change?

My company is using marketo forms, and we are generating the page from a content management system.
We'd like to keep the contribution experience as simple as possible and prevent the user from contributing actual <script> tags.
The API documentation says they will give you a block of code that looks like this:
<script src="//app-sjqe.marketo.com/js/forms2/js/forms2.js"></script>
<form id="mktoForm_621"></form>
<script>MktoForms2.loadForm("//app-sjqe.marketo.com", "718-GIV-198", 621);</script>
My question is, what portions of this code are subject to change?
I am sure the 3 part hypen separated string and the integer being passed in can change.
What about the app-sjqe.marketo.com address?
The 3-part string is your Marketo instance ID, and shouldn't really change. The other integer is the form ID, which definitely will change depending on what form you want to embed.
The other thing that you may want to consider, is the other configurable options that you can send along with the form embed. For example, in the module that I have made for my CMS, I let the user put an optional 'thank-you' page URL, to redirect the form to after submission, and also a checkbox to optionally open the form in a lightbox on page load.
The simple module I made is for the Sitefinity CMS - happy to share code with you if that helps!

How to make AJAX calls with Dynamic URLS in HDIV

When I make dynamic URLS in AJAX calls (based on some field value) then how to make HDIV work with this? Since the URL is dynamic HDIV won't know about this URL on server side. This would fail ultimately. Also we couldn't add it to exceptions. Then how to make it work?
These are some options:
Render all possible links, with all possible parameter values. Keep them hidden and choice the right one by JavaScript before submit.
Use a form instead of a link. You can create a hidden form and add multivalue parameters as select fields. Select the right values by JavaScript before submitting the form.
If the previous options are too complex, define the parameter as a startParameters. But note that it will not be validated.

Standalone Wordpress form does not post to specified action when fields are populated

So this is weird....
I have a form I've created myself (not a plugin, this is what I mean by standalone), and for some strange reason it does not post to the form's action when the form fields have data in them. However, when the fields are empty it successfully posts to the other page.
I have turned off all validators and really am not sure why this is happening.
Do I need to hook into a Wordpress function to allow for my own form submission?
I realized my permalink structure is /%category%/%postname%/ so perhaps it cannot properly post to the URL since it's not an actual file.
How can I achieve this?
Thanks
Wordpress uses query vars to route the request to posts/pages etc. My guess is that one/some of your field names are used by Wordpress internally.
Check http://codex.wordpress.org/WordPress_Query_Vars for the list of vars you shouldn't use

Is it a good practice to use an empty URL for a HTML form's action attribute? (action="")

I am wondering if anyone can give a "best practices" response to using blank HTML form actions to post back to the current page.
There is a post asking what a blank HTML form action does here and some pages like this one suggest it is fine but I'd like to know what people think.
The best thing you can do is leave out the action attribute altogether. If you leave it out, the form will be submitted to the document's address, i.e. the same page.
It is also possible to leave it empty, and any browser implementing HTML's form submission algorithm will treat it as equivalent to the document's address, which it does mainly because that's how browsers currently work:
8. Let action be the submitter element's action.
9. If action is the empty string, let action be the document's address.
Note: This step is a willful violation of RFC 3986, which would require base URL processing here. This violation is motivated by a desire for compatibility with legacy content. [RFC3986]
This definitely works in all current browsers, but may not work as expected in some older browsers ("browsers do weird things with an empty action="" attribute"), which is why the spec strongly discourages authors from leaving it empty:
The action and formaction content attributes, if specified, must have a value that is a valid non-empty URL potentially surrounded by spaces.
Actually, the Form Submission subsection of the current HTML5 draft does not allow action="". It is against the spec.
The action and formaction content attributes, if specified, must have a value that is a valid non-empty URL potentially surrounded by spaces. (emphasis added)
The quoted section in mercator's answer is a requirement on implementations, not authors. Authors must follow the author requirements. To quote How to read this specification:
In particular, there are conformance requirements that apply to producers, for example authors and the documents they create, and there are conformance requirements that apply to consumers, for example Web browsers. They can be distinguished by what they are requiring: a requirement on a producer states what is allowed, while a requirement on a consumer states how software is to act.
The change from HTML4—which did allow an empty URL—was made because “browsers do weird things with an empty action="" attribute”. Considering the reason for the change, its probably best not to do that in HTML4 either.
Not including the action attribute opens the page up to iframe clickjacking attacks, which involve a few simple steps:
An attacker wraps your page in an iframe
The iframe URL includes a query param with the same name as a form field
When the form is submitted, the query value is inserted into the database
The user's identifying information (email, address, etc) has been compromised
References
Bypassing CSRF protections with ClickJacking and HTTP Parameter Pollution
This will validate with HTML5.
<form action="#">
IN HTML 5 action="" IS NOT SUPPORTED SO DON'T DO THIS. BAD PRACTICE.
If instead you completely negate action altogether it will submit to the same page by default, I believe this is the best practice:
<form>This will submit to the current page</form>
If you are sumbitting the form using php you may want to consider the following. read more about it here.
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Alternatively you could use # bear in mind though that this will act like an anchor and scroll to the top of the page.
<form action="#">
I think it's best to explicitly state where the form posts. If you want to be totally safe, enter the same URL the form is on in the action attribute if you want it to submit back to itself. Although mainstream browsers evaluate "" to the same page, you can't guarantee that non-mainstream browsers will.
And of course, the entire URL including GET data like Juddling points out.
Just use
?
<form action="?" method="post" enctype="multipart/form-data" name="myForm" id="myForm">
It doesn't violate HTML5 standards.
I used to do this a lot when I worked with Classic ASP. Usually I used it when server-side validation was needed of some sort for the input (before the days of AJAX). The main draw back I see is that it doesn't separate programming logic from the presentation, at the file level.
I use to do not specify action attribute at all. It is actually how my framework is designed all pages get submitted back exact to same address. But today I discovered problem. Sometimes I borrow action attribute value to make some background call (I guess some people name them AJAX). So I found that IE keeps action attribute value as empty if action attribute wasn't specified. It is a bit odd in my understanding, since if no action attribute specified, the JavaScript counterpart has to be at least undefined. Anyway, my point is before you choose best practice you need to understand more context, like will you use the attribute in JavaScript or not.
When you put empty action then some security filtration consider it malicious or phishing. Hence they can block your page. So its advisable not to keep action= blank.