How to use A HREF with $_POST? - php

I have an HTML menu with links like <a href="input&db=<some database>" There are multiple menu items and multiple databases, so I am using GET as my form method and using it in my menu item links.
However, that shows up in the browser's address bar (as /inout&db=mydatabase) & might lead the user to start guessing as to database names.
How can I have a list of links to the same page, in which only the database varies, using $_POST ?
EDIT: oops, my bad Shoulda said server-side only, so no JS

POST values will be just as obvious to anyone who would be savvy enough to do anything with this information. Unless you're building something like phpMyAdmin, you should never pass such internal information to the client side to begin with. And if you are, where's the harm? You do have proper authentication in place, don't you?

I think the only way to send request via post using links is to use JavaScript. But sending it via post is not secure at all; anyone can install FireBug to see the request.
Instead, I'll suggest a change to your design. Databases are usually at the bottom tier in an application hierarchy, and coupling page details with database sounds unnecessary. Maybe you should try to encapsulate pages so that they don't need to know which database they are reading from?
Granted, I have no idea of the scope of your application (you may be doing something like phpmyadmin). Then it may be unavoidable, and I will just suggest the usual combination of verification and sanctification all users' input and their rights.
Or you can just encrypt your database names. Still I would prefer a change to design.

Use the onclick event of the anchors to submit a hidden POST form, or to perform AJAX POST actions.

No. There are a few narrow and dangerous solutions you can apply:
Use an iframe : everything will work as before, but the actual address will not appear in the browser address bar.
Use AJAX to fetch data.
Replace the link with a form-submitting button or javascript: link.
These all solve the "database name appears in address bar" issue, however:
Anyone with even basic technical skills and appropriate tools (chrome, firebug) can determine the database name anyway by looking at the requests being sent out.
Not using GET can mess up the browser's back and refresh buttons, and prevent deep linking.
My suggestion would be to keep using GET as you currently are, but add a secret token to the URL (such as HMAC(db_name,secret_key)) that cannot be guessed by the user but can be easily checked for validity by the server. This way, unless you give the user a link to the database (with both database name and secret token), all the guessing in the world will not let them access it.

Neither GET or POST will hide your database name.
Even you using POST, view source will reveal the HTML.
In the first place, you should not expose your database name.
Or replace it with some fuzzy mapping
such as
input&db=A
input&db=B
Internally, do string matching and convertA to actual database name

Related

What should I do in my webpage so that only a user from a web browser can request a page and post some data and not from user using Fiddler?

I recently created two pages, front-end.php and back-end.php.
front-end.php post some data to back-end.php on mouse click (I am currently using ajax for this).
Now if I use Fiddler, then also I am able to post data to back-end.php. I do not want this to happen. What should I do?
I searched on Internet for answer and came to a word 'Setting User_agent', but solution is not given clearly.
Regarding what I want, Actually I do not want some bot or some other type of automatic program to get some data from some source and post it to my back-end.php. I want to assure that the user comes to my webpage and then post some data.
User Agent is a header that your browser sends to the web server with each request identifying itself. Here you can see what it is like.
Fiddler sends "*" or "Fiddler" as user agent, so you can ignore requests having those values. However, this is far from optimal solution to your problem because one can simply spoof the user-agent header by sending whatever she likes.
An other non-secure condition would be to check the referer. So, you can ignore all requests except those coming from "front-end.php". Keep in mind that this, too, can be spoofed by the user.
You should keep also in mind that since a user can send data to the web-server using her browser, there is nothing that can stop her from sending data or making requests using any other way.
In general, web developers should respect the user's freedom and not force such tactics, so please be more specific and tell us what exactly is the real problem you want to solve and a more elegant/secure solution may exist.
EDIT: If you do not want crawlers to index some/all of your pages you should add them in your robots.txt file.
Regarding all other automations/programs I'm afraid there is no perfect way to be sure if the request was made from a human being or a robot. I would do two things: a) Make sure to add validation rules to my backend and b) as a last resort implement a CAPTCHA test.
I would use CAPTCHA only if absolute necessary because it irritates most users and makes their lives difficult.
You should add a hash of some internal secret and the value you want to send. As you are the only one who knows how to make the hash, a fiddler cannot know how to create the secret.
For instance, you make a hash of "asdflj8######GJlk" concatenated by whatever your value in your form is. Now the hacker cannot change the form. The problem is, you can post the same value (with the same hash) from another place. To stop this from happening you should make sure all hashes can be used only once. The only thing a hacker can do now is to post your request from fiddler instead of from your site, but not at the same time. As a final step you can add something as a time-limitation
So what you need is a hash with:
a secret
a method to make the hash single-use
a methode to make the hash time-limited
add this as a field. Specific implementation is left as an exercise ;)
I would not use user_agent, these can be easily faked.
(these methods are the same that payment-providers use to ensure the data (e.g. the amount to be payed!) is not tampered with)
The shortest answer is that anything your browser can do, Fiddler can do. It can send any header it wants using any value it wants.
If your goal is to be able to pass some values from one page to another, without ANYONE changing them (either the browser or Fiddler) you use a Message Authentication Code (a signed hash of the data).
ASP.NET builds this feature in for their "ViewState" data; see http://msdn.microsoft.com/en-us/library/system.web.configuration.pagessection.enableviewstatemac(v=vs.110).aspx
However, that precludes the client (e.g. your JavaScript) from changing the values at all; if JavaScript can change the values, it means that it has the key, and if it has the key, so does Fiddler.

php security should I hide query string in url

A number of my pages are produced from results pulled from MySQL using $_Get. It means the urls end like this /park.php?park_id=1. Is this a security issue and would it be better to hide the query string from the URL? If so how do I go about doing it?
Also I have read somewhere that Google doesn't index URLs with a ?, this would be a problem as these are the main pages of my site. Any truth in this?
Thanks
It's only a security concern if this is sensitive information. For example, you send a user to this URL:
/park.php?park_id=1
Now the user knows that the park currently being viewed has a system identifier of "1" in the database. What happens if the user then manually requests this?:
/park.php?park_id=2
Have they compromised your security? If they're not allowed to view park ID 2 then this request should fail appropriately. But is it a problem is they happen to know that there's an ID of 1 or 2?
In either case, all the user is doing is making a request. The server-side code is responsible for appropriately handling that request. If the user is not permitted to view that data, deny the request. Don't try to stop the user from making the request, because they can always find a way. (They can just manually type it in. Even without ever having visited your site in the first place.) The security takes place in responding to the request, not in making it.
There is some data they're not allowed to know. But an ID probably isn't that data. (Or at least shouldn't be, because numeric IDs are very easy to guess.)
No, there is absolutely no truth to it.
ANY data that comes from a client is subject to spoofing. No matter if it's in a query string, or a POST form or URL. It's as simple as that...
As far as "Google doesn't index URLs with a ?", who-ever told you that has no clue what they are talking about. There are "SEO" best practices, but they have nothing to do with "google doesn't index". It's MUCH more fine grained than that. And yes, Google will index you just fine.
#David does show one potential issue with using an identifier in a URL. In fact, this has a very specific name: A4: Insecure Direct Object Reference.
Note that it's not that using the ID is bad. It's that you need to authorize the user for the URL. So doing permissions soley by the links you show the user is BAD. But if you also authorize them when hitting the URL, you should be fine.
So no, in short, you're fine. You can go with "pretty urls", but don't feel that you have to because of anything you posted here...

Is hiding GET parameters by rewriting it to POST and redirect a good idea?

I want to hide parameters from URL. I'm using uuids instead of ids and when I pass it in URL it looks a bit long and ugly. First thought was to use little forms with hidden inputs istead of anchors, but it will be uncomfortable to replace every one anchor with form, also it will not work when an anchor is placed in another form already.
So second thought was rewriting $_GET to $_POST/$_SESSION and then redirect again to this script. All variables will be available and the URL will be clean and short.
But what with performance of this solution? Is it a good idea to do it this way?
Any help or other ideas will be appreciated. Thanks in advance.
PS.
Don't change GET to POST or vice versa for prettiness. Both HTTP methods are handled very differently in many contexts, and you don't want to cause these kind of side effects.
POST requests cannot be self-contained in a URL, i.e. try to send someone the link to a site that requires a POST request. POST requests screw with browser history, i.e. try clicking the back button to go back to a page submitted via POST. POST requests aren't indexed by search engines.
POST requests are supposed to be used to modify data on the server. Don't use them for all regular requests.
If you need prettier URLs, find some other way to reference your records. Or just stop caring about it, it's really not that important.
you will of course loose ALL search engine benefits across the entire width of your site if you universaly adopt this strategy. you should only really use $_POST when you are submitting data that needs to be saved to a storage medium (or where you are sending secure data https etc), otherwise the recommendation is $_GET for 'requested' data. So, you'll need to identify the use case here and follow that pattern.
I understand what you are saying about 'ugly' URLs, but would advise you to be cautious on looking for remedial action on this. One way of course would be to do a urlrewrite on the incoming parameters but this would require database lookups etc (to get the mapped nice url string), so could be costly.
I'll get back with any other thoughts as they occur.

How to reject direct query?

I am using a URL to query some posts by their ID.
http://domain.com/page-name/?id=123
Visitors click the URL and will open the page and get the right post.
However, if anybody want, he can input this URL in browser and get the post, he can even get a lot of different posts if he knows other IDs. How can I reject this kind of query?
By the way, my site provide embed code for post. So, I need to enable access from other website.
The easiest way probably would be to check the HTTP Referer via $_SERVER['HTTP_REFERER'] and make sure the visitor clicked the link on one of your pages. This will, however, prevent any kind of bookmarking as well.
Another solution would be to use something else than IDs as URL parameter. Those would be hard to guess. You could use an MD5-Hash of the id + date or something instead of just the ID. (Of course you would have to store the hash in the database!)
On some pages you can see another approach. It is mainly used for search engine optimization, but can work for you as well. Generate a string from the title of the post (something like "news_new_blog_software") and store that in the database. Then use mod_rewrite to redirect all calls of http://domain.tld/post/* to a PHP file and over there check if the string after /post/ is in your database. This might look a little nicer than MD5 hashes, but you would have to ensure URL strings are not used several times.
If you want to make it really secure there is basically no other way than using some kind of login to check the access privileges.
However, if anybody want, he can input this URL in browser and get the post, he can even get a lot of different posts if he knows other IDs.
Exactly. That is the purpose of the World Wide Web.
And there is absolutely no reason in rejecting direct queries.
In fact, from the technological point of view, every request to you site is a "direct" one.
You are probably trying to solve some other problem (most likely imaginary one). If you care to tell it to us, you will get the right solution.
You can generate some kind of secret key and append it to the link URL, something like
http://domain.com/page-name/?id=123&key=1234567890
Some specific data required to generate this key is stored in cookie.
You can use md5 hash of random value + timestamp + page id, saving that random value to cookie. Every time you get a request, you check if key is present in request parameters, if user has cookie, then calculate hash and compare it with the one in the request.
you can pass id in hidden field and use post form method.
You need authorisation, not this. This would stop people clicking through to your site from search engines or other websites.
If you don't want to implement authorisation/login, then why not try implementing the First Click Free: http://support.google.com/webmasters/bin/answer.py?hl=en&answer=74536

The RESTful flow?

So...
I've been reading about REST a little bit, and the idea behind it sounds nice, but the question is, can it be easily integrated into the standard flow of a webpage?
For example, a user creates some sort of item, a blog post or what have you, and now he wants to delete it, so he clicks a 'delete' link on the page. Now what? How do we issue a DELETE request to, say, http://mysite.com/posts/5? And how do we handle that request? I have no experience with cURL or anything, but from the looks of it, I would have to curl_init('http://mysite.com/posts/5') and then work some magic. But where would I even put that script? That would have to be on another page, which would break the whole idea of REST. Then I would just be GETing another page, which would in turn DELETE the page I originally intended?
Is this why people rarely use REST or is there actually a nice way to do this?
Looks like I need to clarify. People are suggesting I include words like "DELETE" and "POST" in the URL. I believe REST dictates that we have a unique URL for each resource but not for each action on that resource. I assume this also means that we only have one and only one URL for each resource. i.e. I want to be able to DELETE or VIEW the contents of a particular post from one URL (by sending either DELETE, PUT, POST, or GET), not different URLs with additional params
With a restful server, the same url (say /books/1) can respond to many different verbs. Those verbs, GET, POST, PUT, and DELETE, together with the path, indicate what you want to do to the data on the server. The response tells you the answer to your request.
REST is about accessing data in a predictable and sensible way.
If you come from a strong PHP background, where every url has to map to a particular file, you're right, it doesn't really make sense. The two most visible RESTful development environments, ASP.NET MVC and Rails, each have special servers (or server logic) which read the verbs and do that special routing for you. That's what lets the "normal flow" of the application go through as you'd expect. For PHP, there are frameworks that help with this, such as WSO2's WSF.
How REST works with Web Browsers
Take, for instance, your example. We have posts, and we want to delete one.
We start by visiting a url like /posts/4. As we would expect, this shows post 4, its attributes, and some actions you could take on it. The request to render this url would look like GET /posts/4. The response contains HTML that describes the item.
The user clicks the "Delete Item 4" link, part of the HTML. This sends a request like DELETE /posts/4 to the server. Notice, this has re-used the /posts/4 url, but the logic must be different.
Of HTML forms and web browsers, many of them will change a link with method="delete" into a method="post" link by default. You will need to use Javascript (something like this) to change the verb. Ruby on Rails uses a hidden input field (_method) to indicate which method is to be used on a form, as an alternative.
On the server side, the "delete an item" logic is executed. It knows to execute this because of the verb in the request (DELETE), which matches the action being performed. That's a key point of REST, that the HTTP verbs become meaningful.
After deleting the item, you could respond with a page like "yep, done," or "no, sorry, you can't do that," but for a browser it makes more sense to put you somewhere else. The item being deleted, responding with a redirect to GET /posts makes good sense.
If you look at the server log, it will be very clear what everybody did to the server, but that's not as important as...
How REST works with Arbitrary Data
Another key point of REST is that it works well with multiple data formats. Suppose you were writing a program that wanted to read and interact with the blog programmatically. You might want all the posts given in XML, rather than having to scrape the HTML for information.
GET /posts/4.xml is intuitive: "Server, please give me xml describing post #4." The response will be that xml. A RESTful server makes it obvious how to get the information you want.
When you made the DELETE /posts/4.xml request, you're asking, "Server, please delete item #4." A response like, "Okay, sure," is usually sufficient to express what's happened. The program can then decide what else it wants and make another request.
Well one way is to make an AJAX call using the DELETE method.
Facebook's REST server is a pseudo one, you can do it like them, asking for the post method: POST, GET, etc. the action and the other values you need for that request.
Why I say facebook is a pseudo REST server? : well, one of the Principles of REST says
Every resource is uniquely addressable using a universal syntax for use in hypermedia links
in facebook you only have /server.php and there is where you make the request, even for (POST, GET, PUT, DELETE...)
the other way is using mod_rewrite and parse the url the client is requesting
EDIT: just found this, looks interesting. Have fun!
I don't think REST is rarely used. You're using it right now, on StackOverflow. As far as your specific example goes, you can send DELETE requests though XMLHttpRequest in browsers that support it. When JS is off, or for non-compliant browsers, you can do something like:
POST http://foo.com/delete?post=5
Not ideal, but still more restful than many sites.
EDIT: Changed to POST
Depending on what framework you use, there are models that determine how actions are handled for each resource.
Basically using another parameter, you want to send the resource what action to perform. That parameter may be sent through AJAX/JS for example.
If you want to do it without javascript/ajax (in case it's disabled), then a form POST method would work as well, sending the resource the extra ACTION parameter.
Of course, in both cases, you have to consider security, and make sure that they're not sending the resource an action they shouldn't be. Make sure to do your checking on the backend, and send an appropriate response or error message.
Client side scripting, whether through JS/Ajax or form POST or other methods require the extra security precaution.
Edited after clarification from poster.
Don't overthink it. You're not going to be able to do this with straight HTML forms and a browser. They do not support DELETE method. Ajax can do it.
I want to be able to DELETE to VIEW
the contents of a particular post from
one URL (by sending either DELETE,
PUT, POST, or GET), not different URLs
with additional params
Delete to view? I'm not sure I understand it, but your delete should be done through the headers, not through the URL. The delete method should not return a view. REST is a service, not all requests are meant for visual consumption.
If you really have no choice about using the DELETE verb then I would suggest something like the following:
POST http://mysite.com/Trashcan?resourceUrl=/Customer/75
What url you use really does not matter to REST, however, it is easier to understand the REST way of interacting if your urls avoid verbs completely.
I have seen so many questions from both Rails and ASP.NET MVC users who need to go beyond the standard "actions" and it is so tempting to just add a new action on the controller. The problem with doing this is that you just threw away the uniform interface constraint of REST.
The trashcan metaphor is not the only way of doing deletes restfully but I would argue that it is just as clear to read as putting a "delete" in the url.
Here are some more "noun-based" ways of replacing verbs.
POST http://mysite.com/Printer/75/PrintQueue?url=http://mysite.com/Document/xyz
POST http://mysite.com/CurrentLogins?user=bob
POST http://mysite.com/QueryProcessor?query=FindMyInformation
POST http://mysite.com/SearchEngine?searchTerms=cat,blue,furry
POST http://mysite.com/OrderProcessor?cart=http://mysite.com/user/2323/cart
Sometimes you have to think out of the box a little to come up with a noun based url, and may seem pedantic to try and do this, but for me the benefit comes from the ability to manage my variables. I am going to have a variable number of resources in my interface, no matter what I do, if I can fix the number of verbs that can operate on those resources then I reduce one of my variables.
Another way of doing it, assuming a webbased/webapplication-based request, is have 2 submitbuttons. Since PUT and DELETE use the same uri/url. You could add a specific delete form and attach a specific name to this delete-button, so when this is sent via a post, you can use this button-name to turn the action into a DELETE

Categories