Zend Framework - Secure way to pass parameter from view to controller - php

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.

Related

Checking script caller

I wrote a API for a system. It is a PHP file, which is called with some parameters. It is called like this: "https://abcdefg.de/api/api.php?test=test". This script returns sensitive data when it is called. To make sure only the right api users get the information the parameters has to contain correct credentials.
To make the api more secure the idea was to check in addition who is calling the script. For example only the website "https://test.de" should be able to call the api script. But how to achieve this in PHP? How to check what is the url of the "caller"?
I already tried $_SERVER['HTTP_REFERER']; but I read that it can be easily manipulated and in our case it returns always null, because we use https instead of http.
Is there a solution to our problem?
Thanks in advance,
Filip.
HTTP_REFERER will not be working in real with API, it's related to the form submitted from another page or website, in case this is the situation this is called cross-site request forgery, the solution here is to create a token in every rendered form and send it with the submitted data, from the backend, you will validate this token (most of the time is saved in the sessions), you can check it

GET vs POST when requesting data on button click?

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.

Avoiding or alternative to use $_GET

I am currently using to process results via $_GET variable from querystring (URL) http://example.com?id=c02df and to update etc, as you know user can see what id being sent to the next page via url (from above example id is c02df) and can change the id from the URL himself. Kindly let me know is there any alternative way to exchange the ids between pages to process the functionality accordingly which user can't see or mess with?
The best solution would be to use $_SESSION, if you don't want to allow users to tamper with the request.
If you provide more info on your code, I can provide more info on the solution.
EDIT: Here's a "workaround" for using both $_SESSION and $_GET (still without seeing your code at all):
You set $_SESSION['allowed_gets'][] = 'c02df';
Then, when the user is making the request, you check whether they are allowed to do that request:
if (!in_array($_GET['id'], $_SESSION['allowed_gets'])){ die(); }
If you have content users shouldn't be able to see, you should have a login system.
If you just want unguessable URLs, avoid sequential IDs for the $_GET parameter. You could, for example, generate a salted MD5/SHA1 hash of the ID, store it in the database alongside the ID, and use that in the URL.

Setting $_SESSION['HTTP_REFERER'] for redirection after login?

I'm trying to redirect people to the page they came from after they login.
$_SERVER['HTTP_REFERER'] is unreliable so what do you think of me setting $_SESSION['HTTP_REFERER'] to the page they were on before they get directed to the login page in the first place?
I'm building an ajaxy-fadey-pretty-poncy-looking type app with rewritten URLS so don't want to use something ugly like the querystring to send data.
Any thoughts? Should I use $_POSTs instead (bit of a pain)?
It is a good approach - many frameworks offer an implementation like that (symfony 1.4 f.e. $this->getUser()->setReferer($url);. You could also choose to keep it as a parameter in your $_GET (login.html?from=somepage). Both are very common. A third possible solution is that you display the login box on the same URL so that you won't need to do any redirect-logic.
$_SESSION['HTTP_REFERER'] is generally a bad idea because it's not the HTTP Referrer so the name is misleading which is bad.
You can however solve your problem by using $_SESSION as well as you could with any other information you add to the login query, like a hidden form field $_POST or a query info parameter $_GET.
Take care that when you do the redirect, the value is properly encoded, a valid URI and in a valid context, e.g. only redirecting to your site (not some other site).

Edit in Place Update Script Security

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.

Categories