here i am trying to verify the token submitted from html form and the token in codeigniter controller.
HTML Form
<input type="hidden" class="txt_csrfname" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>" />
Controller
` public function storeForm(){
$TestModel=new TestModel();
$data=[
'name'=>$this->request->getVar('person_name'),
'email'=>$this->request->getVar('person_email'),
'pswd'=>$this->request->getVar('pswd')
];
$request = \Config\Services::request();
$token = csrf_hash();
$formToken=$this->request->getVar(csrf_token());
echo testVerifyCI4Token($formToken);
}`
Helper function
function testVerifyCI4Token($csrfToken){ $security = \Config\Services::security(); return $security->verify($csrfToken) ? true : false; }
After running this code i am getting this error
Error1
When i change the parameter in function to
`$request = \Config\Services::request();
$token = csrf_hash();
$formToken=$this->request->getVar(csrf_token());
echo testVerifyCI4Token($request);
`
I am getting this error
Error2
I need the solution how to verify token of HTML Form
Answers will be appreciated :)
I need solution for this problem and i want to know what wrong thing i am doing here
Related
When I want to share a page url from my site like mysite.com/page1#foo=bar, or want to visit this page when I am logged out, I am redirected to the login form as page1 route is in the auth middleware.
My problem is that after I log in successfully, I am redirected to mysite.com/page1 and I lose the hash value.
(the hash value is also not kept on the /login)
Is there any easy way provided by Laravel to keep the hash ?
As the hash is not sent to server, I kind of doubt it, but maybe there is something I missed somewhere !
Otherwise I would need to overwrite the login, maybe read the hash with JS and somehow re-inject it in the redirect after login, but would quite like to avoid doing that if there is an easy way :)
Thanks to Mruf direction, I managed to get to the bottom of this.
Not sure it is the best implementation, but it seems to be working.
Basically, I insert the hash value in the form as Mruf suggested, and then extended the handleUserWasAuthenticated function in AuthController
login.blade.php
<script type="text/javascript" >
$( document ).ready(function() {
$('.urlHash').val(window.location.hash);
});
</script>
<form id="login-form" role="form" method="POST" action="{{ url('/login') }}">
<input type="hidden" class="form-control urlHash" name="urlHash" value="">
....
</form>
AuthController.php
protected function handleUserWasAuthenticated(Request $request, $throttles)
{
if ($throttles) {
$this->clearLoginAttempts($request);
}
if (method_exists($this, 'authenticated')) {
return $this->authenticated($request, Auth::guard($this->getGuard())->user());
}
// old code: return redirect()->intended($this->redirectPath());
$newRequest = redirect()->intended($this->redirectPath());
$newRequest->setTargetUrl($newRequest->getTargetUrl() . $request->urlHash);
return $newRequest;
}
A simple JavaScript would do the trick:
$("#login-form").submit(function(){
e.preventDefault();
$(this).append("<input type='hidden' name='hash' value='"+window.location.hash+"'");
$(this).submit();
});
Now you can access the hash within your request object
function controllerAction(Request $request){
$hash = $request->get("hash");
// Parse Hash
....
// Redirect to somewhere
....
}
I have one controller and one Form Request Validation class: app\Http\Controllers\GuestController.php and app\Http\Requests\ItemValidation.php. In GuestController.php I use storeItem(ItemValidation $request) method to store item data which comes from <form> .
And in ItemValidation.php request class I redirect back to the form with following method if validation fails.
public function response(array $errors){
return Redirect::back()->withErrors($errors)->withInput()->with('type', '2');
}
The main thing I want is to pass value from <form> (which is entered by user in form) to response method. I tried with following but it did not work:
public function response(array $errors, Request $request){
return Redirect::back()->withErrors($errors)->withInput()->with('type', '2')->with('sub_menu_id',$request->sub_menu_id);
}
->withInput() flashes the previous input to the session.
In your form view, you should use the old() helper to repopulate the value if a previous input exists.
Blade:
<input type="text" name="username" value="{{ old('username') }}">
Plain PHP:
<input type="text" name="username" value="<?= e(old('username')) ?>">
If there is no previous input, it returns null, which echoes as an empty string.
Documentation: https://laravel.com/docs/5.3/requests#old-input
Well, In my website I am using PHP unique form token to prevent CSRF attacks. The unique form token and form token validation function is bellow :
// generate new token for every form
function generate_Form_Token($form_name) {
$token = md5(uniqid(microtime(), true));
$_SESSION[$form_name.'_token'] = $token;
return $token;
}
// validate form request
function verifyForm ($form, $url){
// call the form processing page
$actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
if($actual_link !== SITE_URL."$url")
return false;
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest')
return false;
if(!isset($_SESSION[$form.'_token']))
return false;
if(!isset($_POST['_token']))
return false;
if($_SESSION[$form.'_token'] !== $_POST['_token'])
return false;
return true;
}
Now If I have one form in one page then it's validating the form successfully.
BUT in my website I have a page called create-menu.php Here I am using 4 form So this 4 form will generate 4 unique form token and I am use following input field to every 4 form :
<input type="hidden" name="_token" value="<?php echo generate_Form_Token('menu_creation'); ?>">
But the problem is when I validating the form (Using Ajax) in process.php page. In this page only 1st form is validating but other 3 form is showing me error message (my custom error message if the form token is not match with session).
process.php page
if($_SERVER['REQUEST_METHOD'] == 'POST') {
if(verifyForm('menu_creation','menu-creation')) {
// my code.....
}
}
How can I solved this type of issue ? Can anyone assist me with that ? Thank You.
Call the function that generates the token once. Store the return value in a variable. Use that variable in each form.
I use <input type="hidden" /> to pass some value so I want to make the hidden field is safe I have a user profile page I get username of member by this
$userprofilename = $_GET['username'];
when some body post any thing to user I get username of profile by
<input type="hidden" name="userprofile" value="<? echo $userprofilename; ?>" />
but in google chrome any body can change userprofile value, how can I make it safe?
thanks
Then instead of storing it in a public form, store it inside a server session
Instead of
$userprofilename = $_GET['username'];
Do
session_start();
$userprofilename = $_SESSION['username'];
And when they login, add their value to the session
// on login
session_start();
$_SESSION['username']=$userprofilename;
The best would be to not pass the client at all but keep it on the server-side. This is what sessions are for: store the value in the server-side session then you can retrieve it on form submission.
However, if you don’t want to use sessions, you can at least detect whether the hidden values got tampered by signing the hidden values using a MAC like hash_hmac. Here’s a simple example:
function create_hmac($key, $uri, array $params)
return hash_hmac('sha256', json_encode(array($uri, $params)), $key);
}
$secret = '7wzvtNgAVCTLPZ27P4L52yzc';
# on form creation
$hidden = array(
'userprofile' => $_GET['username']
);
$hmac = create_hmac($secret, '/form/submit.php', $hidden);
echo '<input type="hidden" name="hidden" value="'.htmlspecialchars(json_encode($hidden)).'">';
echo '<input type="hidden" name="hmac" value="'.$hmac.'">';
# on form submission
$hidden = json_decode($_POST['hidden'], true);
if ($_POST['hmac'] !== create_hmac($secret, $_SERVER['REQUEST_URI'], $hidden)) {
// invalid HMAC
} else {
$_POST = $hidden + $_POST;
}
your form page
create a session variable like this
session_start();
$_SESSION['userprofilename'] = $userprofilename;
instead of this hidden
<input type="hidden" name="userprofile" valu="<? echo $userprofilename; ?>" />
on your submit page
you can retrieve it as follows
session_start();
$userprofilename = $_SESSION['userprofilename'];
// use it as $userprofilename and then unset it
unset($_SESSION['userprofilename']);
this would be safe because session resides on server and can't be seen by the client. by view html source or firebug etc.
You can try by encrypting the username and then decrypting it where ever needed, if you don't want to use sessions
I have a html form that has this markup.
<form id="login-form" action="/post/login">
<input name="username" type="text">
<input name="password" type="password">
</form>
I want to be able to assert this form action.
I try with this inside the test method, note I extended \PHPUnit_Extensions_Selenium2TestCase
$form = $this->byId('login-form');
$this->assertEqual('/post/login', $form->attribute('action'));
It seems like action always null.
Does anyone know how to test the form action attribute?
Thank you.
Unfortunately, $form->attribute('action') returns action with base url (http://localhost/post/login).
I did not find a way to get action without base and did not find how to get base url. There is my solution:
function testForm(){
$this->url('/test.html');
$form = $this->byId('login-form');
$this->assertEquals('/post/login', $this->getRelativeFormAction($form));
}
function getRelativeFormAction($form){
$action = $form->attribute('action');
$action = str_replace($this->getBaseUrl(), '', $action);
return $action;
}
function getBaseUrl(){
$urlComponents = parse_url($this->url());
$url = "{$urlComponents['scheme']}://{$urlComponents['host']}";
return $url;
}
There is successful full test code.