This is a short but general question. I am relatively new to programming in general. My site, which is predominately written in PHP, will be launched soon and is undergoing some security tightening. This started with converting the whole thing to PDO with prepared statements (from what was a MySQL set up) to making sessions more secure.

My issue is this: I make quite a lot of use of the $_GET superglobal to pass user IDs around and thread IDs in the Q/A section. If a member clicks on another member's pic, they are sent to that user's profile page invariably using a $_GET['id'] to send the info - usual newbie type stuff.

I am concerned that this may pose a security risk as the members' ID numbers are essentially visible throughout the site.

I am not sure that creating forms with hidden $_POST variables is the answer. I have searched for answers on this, without success regarding this exact question.

I know this is not code, but I would appreciate some steerage on whether this actually does represent a problem, and if so, how.


3 Answers 3


Seems that my comment did not make it here, so i'll post it as an answer:

No, it is not a serious security concern. If your site has for example a blind sql injection vulnerability, this would make it easier to attack a specific user. It probably also makes it a lot easier to scrape your website for user profiles, if that is a concern of yours. But other than that, I cannot think of a way to attack this.

But if you are still concerned: No, hidden post variables are not the answer. Instead, do not pass the ids, but pass slugs of usernames/postnames/etc instead (the slugs should be sanitized, so that they do only contain valid url characters). This is also more user and seo friendly.

But do make sure not to output any user supplied data directly to the enduser. You have to sanitize it first to prevent xss attacks (and it does count as user supplied even when it comes from the database - if the data in the database is user supplied).

  • Apologies Tim. What is a slug?
    – GhostRider
    Jul 28, 2014 at 20:25
  • @GhostRider wikipedia has a pretty good definition of what a slug is
    – tim
    Jul 28, 2014 at 20:45

Using POST instead of URL parameters has zero benefit for security. POST data can be changed just like URL parameters. In fact, you must not trust any data coming from the user, be it a URL parameter, a POST parameter, a cookie, an HTTP header or whatever. Almost all input is under the user's control and can be anything they want.

The key is to treat every value which isn't hard-coded as a potential threat and make sure it doesn't cause any harm. Prepared statements are a good choice for dynamic queries, because they ensure that the values are treated as data rather than SQL statements. To insert values into your HTML document, you need to HTML-escape them; shell commands require the values to be shell-escaped and so on.

  • It doesn’t matter where the data came from or whether one considers it as untrusted or as trusted. It should all be handled the same.
    – Gumbo
    Jul 28, 2014 at 22:38
  • Isn't that exactly what I just said?
    – Fleche
    Jul 29, 2014 at 1:21
  • No, you said “you must not trust any data coming from the user”. And my point is that it’s neither about where the data comes from nor about whether someone considers it as trusted. People may misjudge whether a user can manipulate a value and erroneously think they can trust it. This may also lead into thinking it suffices to ‘clean up’ or ‘sanitize’ just the $_* values and everything is fine, which seems to be a popular (bad) practice among PHP developers.
    – Gumbo
    Jul 29, 2014 at 7:05
  • You need to read more carefully and get rid of the clichés you seem to have about PHP developers. I said two things: User input cannot be trusted. This answers the question about whether POST parameters are somehow more secure than URL parameters. Then I said that every value which isn't hard-coded needs to be treated as if it was harmful. This makes it clear that all dynamic data (regardless of its origin) must be escaped or, in the case of queries, be bound to a parameter of a prepared statement. I hope this clears it up for you.
    – Fleche
    Jul 29, 2014 at 10:04
  • as I understood this question, it was asked if exposing ids is a security risk (and if using hidden post parameters hides the ids, which it does not). So while this answer is definitely true and important, I don't think that it really answers the question.
    – tim
    Jul 29, 2014 at 12:30

There's two aspects to the question here:

  1. Is using the ID from the URL (GET) safe? Short answer, no. Like any other data it needs to be validated and filtered before use. This prevents issues like SQL injection from coming up and leaving the application vulnerable. Validate that it's an ID, validate that it's a valid ID and use prepared statements to reduce the risk even more.

  2. Since they're IDs (integers) is it safe to use something the user can change? This is where things get a bit more complex. This part of the problem is less about the data they're giving you (that's #1) and more about access and authentication. For example, in most applications a "view" on a user is okay for anyone to see. An "edit" however might only be allowed to the user themselves and an admin. This is where you need that protection layer that checks who the user is and what permissions they have for that page/resource. This is related to OWASP's "Insecure Direct Object References" item in their Top 10. It's a pretty common problem but the right answer is auth* protection, not obfuscation though POST or hidden form fields.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .