I'm using Laravel 5.3.
Essentially, when a user clicks a button on the screen, I need to get data from the database (using AJAX), and then display that data on the screen.
However, I'm not sure if I should be using a GET or POST request? I've only ever used GET requests for routing when the user wants to get to a specific page, like a GET request for /index or /profile.
Which should I use?
There is a difference between GET & POST method in Laravel
GET is used when we want to get some data from the server and we do not send any parameter in request. And the security threat is not a concern, like you are opening a page on browser
POST is used when we want to send some parameter to the server and based on that parameter some processing is done. In laravel it is mandatory to include CSRF token wit the request for security concern.
So choose as per your requirement.
easy! Use GET when you're to getting data, and POST when you're posting data.
There are even more of these request methods (or verbs, if you like). For example a PUT request to edit data, DELETE request to delete data etc. However, these aren't supported in most browsers yet, but i know laravel has a clever workaround so you can use them anyway. check this links:
https://laravel.com/docs/5.3/routing
This is actually something of your own choosing. If the operation is a sensitive one you might consider using POST so that you can have protection over CROSS-SITE REQUEST FORGERY from attackers but if not so you can simply use GET
If you only want save data in database(no return data) so you should use POST. And whenever you want to get data from database so you should use GET.
Ex - If you want to insert a new user information in database so here you use GET method and if you want to edit existing user information and return updated information so you will use GET method.
Related
I'm trying to protect my backend from multiple post requests to avoid duplicate data on the database and the server overload.
I've already blocked the frontend disabling the submit button after a first click, but it will not prevent some "smart user" to submit my form from the console or disable javascript from the page and try something.
So I want to know if Laravel has some solution for this case.
PS: I've already tried some solutions on the backend too if you want I can post here.
As requested:
So one of my alternatives is check if the incoming data is already on the database and denied the request if is it, it will prevent the duplicate data but not the server overload.
Another alternative is to create a token in session for one use only on Create() method from the controller, send the token to the view and put it on a hidden field, retrieve it from post request and check the post token with the session token. If the two tokens are the same, then unset it to avoid others requests try using it and if they try I deny the request.
If you know who your users are (because they have an ID) then this is somewhat easy to do. Possibly use some sort of quick-access system such as Reddis to check-in that a user is in a state of edit while the action is being carried out.
However that creates complications of its own. Also doesn’t work if you don’t know who your users are.
The safer thing would be to make sure that your requests can handle potential problems. Consider using database transactions to ensure the integrity of the data.
It would depend really on what you’re trying to avoid, why you are, and what kind of data you’re worried about duplicating.
if it's too important for you to protect for multiple submit u can put a random string in hidden input in your form and also put it in a special session for each form you have and check it every time and after that try to change your session after each time you end your proccess
I am using Laravel 5.2.15.
There are list of records in a webpage with Edit and Delete button with each record. I have two approaches for deleting the record
Use JQuery and send Ajax Request to server.
Place a form tag for delete button in each row.
I have following question
In case I use Approach 1, can it cause any issue when the site will be viewed from Android or iPhone? I have another option to do Server side validation using Request class.
In case of Approach 2, Will it make the page heavy? I am using Pagination, so 10 records will be displaced per page.
Please guide me if I should go with which approach or please suggest if both approaches are incorrect.
The questions you have don't really focus on the main reasons to choose one above the other. They differ mostly in how the request is sent to the server and how the page is refreshed to show the results.
Using Ajax is a very common approach and relies on using Javascript, a technology that has been available in all browsers for a very long time. Compatibility will not be a problem as most of the internet wouldn't function without it anyways (and you can even make it work using your second approach as a fallback mechanism). The request you sent is typically a HTTP DELETE request to a REST endpoint so that the server then knows to delete the record1. Upon receiving the success response from the server the page is responsible for updating itself by removing the row corresponding with the just deleted record, and possibly fetching new records to still have 10 rows on that page. No page refreshes required, but some Javascript required.
Your second approach is kind of old school in that the form you submit contains some kind of identifier such that the server knows what to do. This is a full page load and should be a HTTP POST request if you want to do it properly2. Following the Post/Redirect/Get idiom the server then sends a Redirect response so that the browser will then trigger yet another normal page load as GET request to show the user the updated list of records. You do not have to update the page manually by yourself, at the cost of having annoying page reloads (this isn't really expected anymore in the current day and age).
My advise would be to go with the first approach. It is the modern way of doing things and allows for having non-reloading pages. It does however require some additional work on the client side (in Javascript) to update the page accordingly.
As a side note, CSRF must be taken care of in both instances really. Always include a CSRF token with every 'update' action you perform on the server.
1 You have to program this yourself, of course :)
2 Browsers don't generally support anything other than GET and POST, although the HTTP specification allows for much more request methods.
It depends upon your requirements. But you should go with the 1st approch. If you will use 2nd approch the you will have to refresh the page since you can not handle the response. So basically if you delete 5 items the page needs to be refreshed 5 times and you may not send more than 1 delete request at a time. Now If you use 1st approch since It's ajax and javascript you can display appropriate message depending upon the result and no need of unnecessary page refresh.Plus as you mentioned you can do validaton using Request class. So you can handle bad or malicious request. And I am sure CSRF won't be that much of a problem since you can check whether the request is ajax or not using Request::ajax(). So 1st approch is better mostly because of that no page refresh.
Both approaches are fine ;)
But 2nd approach would be better than first one; Using this approach you can prevent CSRF attacks too;
I would suggest you to use method 1 with certain modifications.
Use get request to delete the record.
Send a CSRF token and dont forget to encrypt your id for the record
add your delete URL to href
Then when you do ajax request, use the url from href and you could send some additional parameter like is_ajax=1, but laravel already checks for the jquery header so Request::isAjax() method will let you know if the request was an ajax request or normal request.
Now all you need to do is send different response for ajax and normal request.
HOPE THIS HELPS :D
Another drawback of your second approach which haven't been mentioned is displaying validation errors. Specifically from your edit and even your delete actions.
If you have multiple forms for each set of data showing errors from validation would be a pain. But if you follow approach number 2 just by getting the reference of the row element submitted, you could easily append an alert div if ever an error from validation has occurred.
as for the delete action, somebody else might have already delete some shared data so you might also want to tell the user somebody already threw this out.
I have been googling a lot but i am still without an answer so i decided to ask this question here:
Is there a way in PHP how to check that the data i am receiving in some script are from the specific form on the page? I am asking because everyone can see the name of the script i am using for saving the data to my database, so if somebody is able to find out the whole URL, he is also able to send some fake data to the script and i need a condition, that the saving process is triggered only when the data comes from the proper form on my page.
I am using jQuery to call AJAX function, so basically if i click on the button "send", the $.POST() method is triggered to call the script for saving the data.
Thanks,
Tomas
Use tokens to check if request is valid
You could always add some kind of security token when submitting data:
Tokens can be easily extended for many different uses and covers wide area when it comes to checking if some request is valid, for example you could let your non critical forms open for public, ask users to get their secret keys from some page (forcing them to open that page) and then use those keys to identify them when submitting data.
Of course all of this can be completely transparent to user as you could give keys from front page via cookies (or session cookies, it does not matter here, no more or less security as server keys should change after use and invalidate within specified time or when user's identity changes).In this example of use, only user that opened front page can submit data to server.
Another case is when cookies is given away at same page which contains form for submitting data to server. Every user that open page will have their keys to submit data straight away, however if someone tries to make request from outside it will fail.
See OWASP Cross Site Request Forgery
and codinghorror.com Blog CSRF and You
Only with AJAX?
Here is my answer to another question, this answer covers different methods for inserting additional data to ajax request: Liftweb: create a form that can be submitted both traditionally and with AJAX (take a closer look at
$.ajax({
...
data: /* here */
...
Currently I am using tokens this way:
Form used to submit
This hidden input can be added to form, it is not requirement as you can use methods described earlier at another answer.
<input type="hidden" name="formid" value="<?php echo generateFormId(); ?>" />
Function generateFormId()
Simply generate random string and save it to session storage
function generateFormId() {
// Insert some random string: base64_encode is not really needed here
$_SESSION['FORM_ID'] = 'FormID'.base64_encode( uniqid() );
// If you want longer random string mixed with some other method just add them:
//$_SESSION['FORM_ID'] = 'FormID'.base64_encode( crypt(uniqid()).uniqid('',true) );
return $_SESSION['FORM_ID'];
}
Processing submitted form data
if (!isset($_SESSION['FORM_ID']) || $_SESSION['FORM_ID'] != $_POST['formid']) {
// You can use these if you want to redirect user back to form, preserving values:
//$_SESSION['RELOAD_POST'] = $_POST;
//$_SESSION['RELOAD_ID'] = uniqid('re');
echo 'Form expired, cannot submit values.';
//echo 'Go back and try again';
exit(1); // <== Stop processing in case of error.
}
If you need to check which form is submitting data
Then you could just add prefix when generating id's and check for that prefix when processing form data.
This is case when one php script deals with many different forms.
Remember that only ultimate answer to prevent evil users is to pull off all wires from your server...
This is an interesting topic, but you are missing an important point: A spam robot / bad user could also bomb your database by using that specific form page (!).
So, the question is not how to check if the request comes from that page or not, the question is how to check if he's a regular user or a robot/spammer/bot.
Do it with a captcha, like http://www.recaptcha.net
In case i slightly misunderstood the question: If you want to be sure that the request comes from a "real" user you will have to work with a login system / user system and check for users id / password (via db or sessions) every time you want to do a db request.
You can verify that the page is being requested via AJAX with checking against this:
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest'
You could also check the HTTP_REFERER.
But it sounds like you're trying to protect a page that processes vulnerable data. This requires more than just the two things above. I'd recommend googling 'CSRF Forgery' to get more information on this.
These are something that you should take a look at.
Capthcas.
Referer check.
Use POST than GET. [Still Curl can automate it.]
I used Zend Framework for near 3 month and I'm searching for a method to pass parameters from the view to the controller in a secure way. I prefer to pass the parameters like $_POST method, but I don't want to use forms.
Is there any method to use in ZF? I only know the url() method but I don't know if this method is works well to passing important data to the controller.
HTTP is a stateless protocol and you can basically choose from four solutions to preserve information between requests (as this is, I think, what you are trying to do, isn't it):
Query string
Hidden elements in forms
Cookie
Session
Session would be the safest. In ZF you have Zend_Session component to help you with session managment.
As far as sending POSTs without form it is rather difficult. Have a look at: Zend Framework: How to POST data to some external page (e.g. external payment gate) without using form?. However, if you only want to sent POST data than you could do it in PHP using cURL.
I think you might be looking for Session variables.
You want to send something that can't be seen from URL into the next request, right? Session is ideal for that.
Update:
I read your question as:
"There is this variable in page, that somehow changes. I want the user to send it to the server, but it should not appear in the URL. But without using forms."
There is no way to initiate POST request (like let the user post a password or sth like that) from browser without forms or javascript axaj call. To send some data via POST you can use Zend_Http_Client(), but that's done server-side and you still need to make a GET request first.
May I ask you how would you implement it using GET? That would help us to understand what exactly you'd like to do.
And the last idea:
I'm searching for a method to pass
parameters from the view to the
controller in a secure way
JUST BEACUSE IT'S NOT IN URL IT'S NOT SECURE! :)
I think what you can use is a digest key
The method has nothing to do with security GET, POST, Cookies or Session a person on the client side can manipulate the params.
Example:
mywebsite.com/widget.php?id=1234&action=delete
A person can change the GET param id and delete whatever they want. Obviously, your controller should implement Auth and perhaps an ACL, for authentication and authorisation, but this still wont prevent URL tampering. For example, what's the stop Bob logging in and altering a URL to edit John's widget.
you generate a digest key by concating the params into a string:
1234+password = "1234password" then generate the MD5 of the result = d5b1ee4b463dc7db3b0eaaa0ea2cb5b4
pass this along the url.
mywebsite.com/widget.php?id=1234&action=delete&mac=d5b1ee4b463dc7db3b0eaaa0ea2cb5b4
inside widget.php you can use the same formula to calculate the digest key and check to see if it matches. If they attempt to change the id to say 4567 the MD5 result would be 09fef3620249f28ae64adc23bded949, so you can deny the request.
If you have more than 1 param on your URI, string them together, add the password and generate an MD5 or SHA1.
I'm using an Edit in Place jquery plugin which needs to post the data to a script that will do the actual database update.
The URL to this update script is easily viewable in the html source as well as with Firebug, so I need to add some sort of authentication check before the update is processed. This is of course so the user can't just pass in any old userid / field / value they want and mess with other people's records.
I was initially passing their username and password in as well, but this isn't ideal as it's in a GET request so it's all in the URL. The site itself is SSL at least, but still not a best practice by any stretch.
What's the best way to authenticate this type of update?
FWIW, the update script is in PHP, and the Edit in Place plugin is: jeditable.
Edit: To clarify: The actual data payload is POSTed to the script, but the edit in place plugin has no explicit method for authentication, so I was passing the authentication as part of the URL to the update script, which was then taking those variables via GET and using them to check.
Edit 2: Yes, I can access the session info from the update script, so I've decided to just pull the previously saved User ID and using that in the db update statement. That would appear to be the most secure method.
I think you'd be best off switching the script to a POST method as most edit-in-place uses will be too big to use GET practically. You should never use the SessionId or the password as a URL parameter and I wouldn't use the username for anything but viewing a public profile. If your AJAX URL is a PHP file, I'm fairly certain it should be able to access the session without needing to pass it in either a GET or POST array. As an additional note, make sure that you validate and sanitize all information before updating the database.
Update (based on comment and question updates): You could pass the username/password as submitdata option to Jeditable, like so:
$(".edit_area")
.editable("http://www.example.com/save.php", {
submitdata: { userid:'johnsmith', passwd:'god' }
// ..other settings, etc.
});
Quick and dirty solution - dirty because it exposes the user's privates in plaintext (via View Source).
Since you do have access to the userid/sessionid on the server, using that by far the sanest option.
Hmm... since you say Jeditable uses GET, I can only assume you're using the loadurl option (since the Jeditable uses $.post() to save the changes, and $.post() always uses POST).
So, have you tried switching Jeditable's loadtype setting to "POST", and send the username/password like before?
$(".edit_area")
.editable("http://www.example.com/save.php", {
loadurl: 'http://www.example.com/load.php',
loadtype: 'POST'
// ..other settings, etc.
});
That sounds like the quick and dirty solution - granted you don't have any standard user/session handling on the server end.
Isn't the site still vulnerable to Cross-Site Request Forgery if you simply look up the user in the session?
You can POST all needed information if you include a salted hash field calculated from values of non-editable POST fields. If you include a timestamp, you can prevent script replay as well.
Example:
$(".edit_area")
.editable("http://www.example.com/save.php", {
submitdata: {
userid: 'johnsmith',
pageid: '123', // or other value unique to the page
timestamp: '1324354657', // time when page loaded
hash: '0bee89b07a248e27c83fc3d5951213c1' }
// ..other settings, etc.
});
The hash could be e.g. an MD5 of 'johnsmith$123$1324354657$' + $secret_salt. Check that it matches before saving. Optionally reject if too little or too much time has passed.
The ditch-pycrypto branch of django-magicforms implements this as a re-usable Form base class for Django. It's not directly applicable to AJAX requests, but the documentation and unit tests should provide a good basis for other implementations.
To pass the information you should use the session id in the actual GET string. This way the php script can connect to the session, validate the user, and see if the user has the rights to edit what they've posted. Then if they have the rights, proceed, or else return an error message.
I believe you can, in javascript, get the session id so it needn't be passed overtly.