CakePHP CSRF token mismatch when multiple forms on page - cakephp-3.0

I'm making a connection/registration form on a single page (using hiding elements to show one at a time) but there is a problem :
CakePHP returns a "CSRF token mismatch." in the method I passed in the 'url' option of the FormHelper for the registration.
The connection works, I'm using an ajax request for it and for reasons I have to use a classic redirection with the action for the registration
I checked both CSRF tokens, they're the same. But the registration form gives me an error.
Here is my method :
function registerCheck(){
$data = $this->getRequest()->getData();
dd($data);
}
Here is the form creation :
<?= $this->Form->create(null, ['class'=>'ui form attached segment', 'type'=>'file', 'url'=>'/register']) ?>
And the HTML returned for both tokens :
<input type="hidden" name="_csrfToken" autocomplete="off" value="f118d0131f835f74665f9ad5a8ce03501abf8ad943131c09fe805da797215acad199f56d2f35442271382b88c046eab1602b85c1171d1aa52c36ab5bc94022c9">
Did I do anything wrong ?

Related

HTML validation error message reveals correct value unintentionally

I am trying to use an HTML number input field to validate a one-time code a user has. The one-time code is a Django model attribute under the user model, with the user object passed into the HTML template. Currently it is set up as such:
<input type="number" name="auth_code" value="" min="{{user.auth_code}}" max="{{user.auth_code}}" onchange="this.setCustomValidity('')" onkeypress="this.setCustomValidity('')" oninput="this.setCustomValidity('')" oninvalid="this.setCustomValidity('This authorization code is incorrect.')" required />
If the user's code is 100000, and I enter 100001, I get the oninvalid message (as expected). However, if I delete a digit (or the whole number), I get a message stating "The value must be user.authcode." Clearly I don't want this value shown.
If I set any message in the onchange or oninput field other than ('') (i.e. ('Enter a code.')), I can't validate any code (correct or incorrect). I run into the "This authorization code is incorrect." message even when validating 100000.
How can I get around this?

Do not change the router values ​in the address

I have a page (index) with an #ActionLink that opens another page to edit an invoice, the page will appear correctly, but the [Url-address] shows the number for the invoice, and when I change the number for the invoice in the [Url-address], it means that he opened another invoice, and I want the modification page not to open from By modifying the [Url-address] or using a direct link, I found a nice way, but it is used with [Post] and not Get. Is there a way to protect the [Url-address] of the page from being modified and its values?
View Index:
#Html.ActionLink(
linkText: "Edit_Invoice",
actionName: "Invoice_Edit",
controllerName: "Invoice",
routeValues: new { ID_Invoice = 2 },
htmlAttributes: new { area = "Pro"})
Controller :
[HttpGet]
public ActionResult Invoice_Edit(int id_invoice)
{
Table.Invoice invoice = (from i in Cn.Invoice
where i.ID_Invoice == id_invoice
select i).FirstOrDefault();
return View(invoice;
}
View Invoice_Edit:
#Html.TextBoxFor(m => m.ID_Invoice)
#Html.TextBoxFor(m => m.Date_Invoice)
<button>save</button>
When you open the invoice modification page, its number will appear in the address as in the link below
https://localhost:44320/Pro/Invoice/Invoice_Edit?ID_Invoice=2
I only want to open invoices that are selected from the page only.
Update 1 : Change Title Answer
if you what users to open only invoices that they are allowed to open, antiforgery token has nothing to do with it. You neeed server side validation, authentication and authorization. All of these should be implemented on the server side. Client side javascript code is not enough.
Anti-Forgery Tokens don't make a lot of sense for any request where you're not modifying and persisting data. So I recommend to remove [ValidateAntiForgeryToken] from your GET since GET request will be returned to the user, not the attacker.
AntiForgeryToken is designed for POST requests and it expects the token in Request.Form collection. You can just use post instead of get to receive data. Or you can use ajax. Google and you will find some examples.
But make sure that you are using them when you're creating, updating or deleting data.

Passing variables with Jinja2 within 3 templates

I have this problem:
I have 3 templates:
Search_user
Show_user
Edit_user
Whit the search_user I'm getting the name value with the post method, then I'll search the data in the db, save the data in an array called user and then pass the array to the Show_user template.
In the Show_user template I show the data with {{ user[0] }}, {{ user[1] }}...{{ user[7] }}, under this data I have a button that bring me to the Edit_user template.
But in the Edit_user template I don't know how to pass the previous data, I don't know hot to export data with the post method or any other methods.
A walk around could be <input type="text" name="surname" value="user[0]" required> but I don't want to show the textbox in the Show_user template.
You don't need to pass any data except some kind of user identifier (a number or a user name) to fetch the user back from the database when needed.
It can be done in multiple ways:
add it to the endpoint URL in the form action (/user/edit/<user-id>)
or use your web framework session to store the user identifier
or add the identifier to your templates as a hidden form field (type=hidden)
...
In any case you just need to get that piece of information (from the URL endpoint, from the session, from the form data...), use it to fetch the user from the database, then pass the user to the edit template.
If you're using a web framework just read the docs, this is a trivial use case that we'll be very likely well documented.
If you need more details, please, share a few code fragments.

Field value fetch when field name is not known

I am using a form builder using which my admin side can create forms and store it as JSON. They are rendered dynamically when the client accesses these forms. When the client submits the form at the back end I need to get the value of all the fields.
Currently I am trying to do this as follows:(Node Server)
router.post('/increase', function (req, res, next) {
req.session.counter++;
var ans = req.body;
console.log(ans+" this got printed");
res.redirect('docfill');
});
I cannot specify a name after req.body as i dont know the field name due to the dynamic nature of the forms.
The console prints [Object object]. The currently rendered form has a date field I need. And if I put it through JSON.stringify() it prints {}. Is my fetched data coming out to be blank? Could it be a problem with using the data field.
EDIT
its not because the filed is a date type, dosnt work with text either
There could be 2 reasons for this:
You have not installed/required the bodyParser module.
In your form tag you're using the enctype attribute as enctype="multipart/form-data". Reason for this being you're not using any module for handling the multipart/form-data type which is unreadable by the browser. Use enctype="application/json" instead.

Same request Parameters in Url String and POST request

I have observed a confusing thing while checking some basics of query parameters and POST requests.
Below is a code portion in index.jsp
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Index Page</title>
</head>
<body>
<form name = "testForm" action="index.jsp?username=uname1" method = "POST">
Username : <input type="text" name="username" value=""/>
<input type="submit" value="Submit">
</form>
<%
String username = request.getParameter("username");
out.println("Username = " + username);
%>
</body>
</html>
On running this code, When I enter the value in textbox username as 'uname2' and click Submit button, the output is shown as 'uname1'.
After that I change the method of form 'testForm' as 'GET' and then re-run the file on server.
When I enter the username as 'uname2' and click submit button, I get output as 'uname2'
I am not able to understand this behavior. Can anyone please help me understand why is this happening ?
Because multiple parameters with the same name can be submitted using GET, POST or by a combination of both. The order in which they are applied is completely arbitrary.
Look at the Servlet API documentation and you will see the following:
getParameterValues
java.lang.String[] getParameterValues(java.lang.String name)
Returns an array of String objects containing all of the values the given
request parameter has, or null if the parameter does not exist. If the
parameter has a single value, the array has a length of 1.
Parameters: name - a String containing the name of the parameter whose
value is requested Returns: an array of String objects containing the
parameter's values See Also: getParameter(java.lang.String)
The method getParameterValue(String name) is provided as a convenience:
getParameter
java.lang.String getParameter(java.lang.String name)
Returns the value
of a request parameter as a String, or null if the parameter does not
exist. Request parameters are extra information sent with the request.
For HTTP servlets, parameters are contained in the query string or
posted form data. You should only use this method when you are sure
the parameter has only one value. If the parameter might have more
than one value, use getParameterValues(java.lang.String).
If you use this method with a multivalued parameter, the value
returned is equal to the first value in the array returned by
getParameterValues.
http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html
Because getParameter() in this case is grabbing it from your GET, not your POST.
See, your action is explicitly specifying the username to be uname1, and then your POST says uname2, I'm not really sure how java decides which parameter to accept, off the top of my head, but you can just remove the query trying parameter of your post form and it should work fine.
By default http uses GET method, here you are mentioning explicitly username in the action and trying to send them using POST. I think http is sending that data through GET method rather than POST.