Busy building my first web application in CodeIgniter and wanted to work out the best way of gathering ID in my Admin function for Edit, Delete statements.
I realised I can use any of the following:
Pass the ID through the controller.
Collect the ID from the URI segment.
Collect the ID from a hidden form field.
Which is the best based on security concerns. i.e. People fiddling with the URL, etc.
I prefer to use the URL for unique IDs, that way you get nice-looking URLs that people can bookmark. You shouldn't rely on how you pass the data for security, you should be doing input validation within your controller regardless of how you pass it.
If this is for an admin section, it should may no difference. Unless a user is authorized to view the output of say, the Admin Controller, they should see "page does not exist" for each one of those methods.
Collect the ID from the URI segment. is my choise..nice url!
Related
I am wondering about the security of my application. I'm simply using twig loop to display all of my records in database. And everything is all right when I make separate site to display the details and there are buttons to e.g. delete this thing. It usually happens DELETE method and somebody can display only own details. But I want to have button to delete specific record in basic view where every records displayed e.g. next to title of item.
I cant do this by CreateFormBuilder because I cannot send the current id of the item from the form (or I just don't know how to do it). But is it secure? Everyone can change the id parameter of button and delete other record.
I can use AJAX and simply button in twig but this is the same case. Everyone can change e.g. data-id parameter in button and delete other record.
What I should to do in this situation? How you usually solve this problem?
Summarising I want to make a secure button to delete item next to each displayed record.
Have a nice day!
One of the way to secure AJAX routes is to use JWT (json-Web-Token) (see this : https://jwt.io/) instead of random string token. This token is crypted with the user's information to ensure the person who clicked on the button is allowed to do someting (and the token is send with the request in header of the request).
Anyway, you have to send something to identify the id of the element you want to erase or modify in your database. I would personnaly implement this JWT system, but the access to the page where you can see and click on these buttons must be protected too. This way, you can assume that the users don't have bad intentions.
Theis bundle (https://github.com/lexik/LexikJWTAuthenticationBundle/blob/master/Resources/doc/index.md#getting-started) can help you to implement this on symfony very easily (i'm new to this framework and i did this in a few hours - just a thing: if you use Apache, don't forget to allow override in your Apache configurations to allow the .htaccess of symfony to do his job, or headers will be strip by Apache - it makes me several hours to find why things did not work !).
Hope this will help !
It really boils down to what kind of app you want to build:
more traditional app - with full page refresh/navigation cycle
AJAX based - with all sorts of async calls to your server
In any case you choose, it is your responsibility to check whether the current user is authorized to make any change (deletion included) to an object. This comes as especially important in case of id being integer, which is predictable.
So, first, make sure your routes are protected from anonymous users, and second, make sure that you put in place permission strategy which allows/denies user's specific action.
Most of the permission-related stuff can be achived via Voters, but if you are really in need of heavy-lifting you can turn to ACL.
Hope this helps...
I am developing a dynamic website using PHP. When a user of the website creates an account, a profile page should be created for that user. Say, a user called 'dev23' creates an account on my website, his profile should be accessible through the link www.mysite.com/dev23
How do I create such a thing? Should I create a standard page like userprofile.php which is populated with data specific to the username provided? Or should I create a permanent webpage for every user?
Please let me know the right approach to this porblem.
Is the www.mysite.com/dev23 meant to be public or only visible to the logged in user?
If it is only visible to the logged in user, you can create a myprofile.php file which retrieves the logged in user from the session and retrieves data accordingly.
If it is meant to be a URL that other users can hit, you probably want some sort of userprofile.php page with data passed along to identify the user to be viewed. For example, the url might be www.mysite.com/userprofile.php?user=dev23. If you are using Apache for your web server, you can look at using mod_rewrite to make the URL prettier. Thus, you could have the URL www.mysite.com/user/dev23 routed to userprofile.php?user=dev23 and your PHP processes the same. It is just a means of making URLs be more user friendly than a naked query string. This is common amongst many PHP-based CMS systems such as WordPress, Joomla, etc.
Ideally you should be creating a single file that handles all users.
Certain frameworks like SkyPHP allow this by defining the attributes after a valid page as "queryfolders" which can be used much like GET/POST variables.
If you are not using a framework, I might suggest you look into using one to simplify your tasks.
SkyPHP also has a functionality where a single field in a table can be used to pull this data simply by defining the page as _table.field_name_
It will check to see if there is a matching table and field to pull the data from and will automatically pull the id of the record whose field's value matches that of the url and assign it to a variable.
Example... If we have a table called category and a field named slug, one would create a page named _category.slug_.php
Then the url... http://mydomain.com/watches would look for "watches" in category.slug and pull back the identifier of the record as $category_id with $category_slug available also.
It would solve your issue if you are willing to give it a shot.
Again refer to the documentation here... http://switchbreak.com/skyphp
I am very curious because I would like to be able to check this myself on my own site, as I am currently in the process of designing it. An example would be:
www.somesite.com/product.php?id=1356
When using Facebook, a user can change it and they get the user associated with this id. But in other sites, specifically Ecommerce sites, when I change it, it either fails or goes to the homepage.
There isn't any way to see if the user changed it. This is part of secure coding. From the server's perspective, you need to validate all of your inputs, and validate that the current user actually should have access to the resource they're requesting.
See https://www.owasp.org/index.php/Top_10_2010-A4 for some additional details and examples.
Facebook may seem to allow this only for the example that you've given because the user profile ID that you're attempting to access may be public to you. However, you won't have access to all other user profiles - only user profiles that you have permission to access. If you tried to access my Facebook profile ID, you would also see your access be denied here.
Since this is tagged as e-commerce, you should also be aware of the PCI DSS if you aren't already - where 6.5.4: "Insecure direct object references" applies specifically to this scenario.
When using Facebook, a user can change it and they get the user associated with this id. But in other sites, specifically Ecommerce sites, when I change it, it either fails or goes to the homepage.
Facebook does the same thing.
https://www.facebook.com/profile.php?id=102934810293841029348 goes to an error page titled "Profile Unavailable", because that ID doesn't exist.
You're likely just changing it to nonexistent IDs.
That works via $_GET method (or $_REQUEST)...
The reason you can change some site id (or any other parameter which is part of the url), and it works, is that because they programmed it to behave like that. It actually depends of how this url parameter is used in the background. For example, in product.php you will have something like this:
if(isset($_GET['id']) {
$id = $_GET['id'];
$id = filterid(id)..... and so ...
// Maybe check for id and redirect if id is not ok
// Maybe check for id and some additional secrete parameter ...?
// What is the id? What kind of behavior you want?
}
Reason why you have different behaviours across different websites - in dependence of url parameters (in this case "id") - is because different behaviours are implemented under different circumstances...
Some of them implement strict checks (especially for id's) because of the security!? For example, if you have page and you know that your id must be a number, and you know, that the max id in your database is for example 15000, you can write something like this....
if(isset($_GET['id'] && strlen($_GET['id']) <= 5 && isNumeric($_GET['id']) {
//if everything is ok you can execute your code here
}
else {
$id = 1; //if someone try to put something else in id, you will simply redirect him on first id(firs product)
}
That is just one example of behaviour. Now consider what else can be done? What do you want to do? How do you want it to behave? What kind of behaviour you will implement on your side - in dependencie of the parameters within the url is to totally up to you. User can follow up your logic on your web app by clicking on your predefined links - or he can manipulate with the url how ever he wants. You dont have possibility to check this. All what you can do is properly validate all of the inputs (no matter are they coming from the URL or some kind of post request)
I am looking at writing a application that requires search engine friendly URLs for a lot of pages. So for example to access say site.com/blah could be a user or a page. For this I was thinking of having a table where I have the URL and then I have a column with the controller, action and any parameters such as id of a page or a user.
I know a db look-up can be slow so I am wondering if this is the best way of going about things?
If you have to use the same route URL (site.com/blah) for two different controller/action, the only way is to use database lookup. When a new user signs up, store the username and the user ID in the database and the route type to 'User' for this username. When a new page is created, store the page name and the page ID in the database and the route type to 'Page'.
When a URL is requested, check the name against the database and get the route type and forward accordingly.
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.