Stop user from getting data by changing id via URL - php

Showing user data on a page by query:
$query = "SELECT * FROM COLLECTIONS WHERE uid = $_GET['user_id']";
But problem is that user can see other users data by changing that uid.
How to solve this problem.

Take your website offline. NOW. Somebody is going to either wipe the data or steal the data or inject malware that's served to all of your customers
Breathe. You've bought yourself some time, assuming it hasn't already been breached.
A small subset of the security measures you NEED to take
These mitigate, in order of "has biggest immediate benefits" to "is probably most important", one problem each. (Apart from number 3, which mitigates anywhere from 4 to 32241 problems of equal or greater magnitude to number 1.)
Look through every instance of every database request, and make sure that you are never using double quotes or the . operator when defining your query string. Rebuild all of your database handling code to use some sort of parametrised SQL query system.
Use an authentication library, or at the very least a crypto library.
Ask about your setup on Security Stack Exchange using an account that is in no way traceable to your website. Not even to your company, if your website is associated with your company.
Why?
Yes, I know, that website is probably important and needs to stay up so people can use it. But try this:
www.badwebsite.com/your/page/here?uid=1 OR 1
All of the data is visible! You are accepting code from the user and running it in your database. Now what if I decided to delete all of your database tables?
That's just covering the first point I made. Please trust that there are bigger problems for your users if you haven't done step 2, the least of which is hundreds of their accounts on other websites (e.g. Gmail, Example Bank) becoming known to cyber criminals.
Take a look at this comic strip:
There's also a unicode-handling bug in the URL request library, and we're storing the passwords unsalted ... so if we salt them with emoji, we can close three issues at once!
This is made to be more funny, but the problem described in this comic strip is probably less bad than the problem you are facing. Please, for the sake of whoever has entrusted you with their data, turn it off for a few days whilst you try to make it something resembling secure.
You might want to bring in a technical consultant; if your developers are not experienced in creating intrusion-proof software then they're probably not up to the task of making insecure software secure (which is orders of magnitude harder, especially if you're new to that sort of thing).

Related

Randomising database for insert

Evening all, I've recently been reading the following blog post about sharding at Pinterest and I think there's some great stuff in there https://engineering.pinterest.com/blog/sharding-pinterest-how-we-scaled-our-mysql-fleet
What I'm unsure on though, is how best to decide where a brand new user should be inserted.
So for those that don't know or have bothered to read the above article, Pinterest have a number of shards, each with a number of databases on. They generate IDs for objects based on a 64 bit shifting that determines a shard, the type of object (user,pin etc..) to determine a table and the local auto-increment id for the object in question. Now they try to put pins etc. on the same database as the 'board' they are on. But for a brand new object, what would be the best way of determining the 'shard' it lives on?
For users that sign in via Facebook they use a modulus e.g
shard = md5(“1.2.3.4") % 4096 //4096 is the number of shards
But if I had a simple email/password registration form, do you think using a similar approach on email address would work for working out an initial shard? I'd assume it would have to be email in this case, otherwise they would have no way of knowing what database to validate the logging credentials against. Also I know that post is from 2015 so not too old and computing power moves quickly, but would there be a better option then using md5 here? I know the chance of a collision is minor - especially as we're just talking about hashing the email address here, but would it be worth using a different algorithm? I'm basically interested in the best way to determine a shard here and to work out how to get back to it (hence why I think it has to be email address)
Hope this all makes sense!
(p.s didn't take this with the Pinterest tag as it looks like that's just for api dev, but if someone thinks it might get better 'eyes' on the question then feel free to add it)
When using MD5 to determine the shard, there is no risk on collisions: If collisions occur then it just ends up in the same shard. The MD5 is not the key in that shard (so that is where the collision risk is removed).
The main issue in this shard method is that the number of shards is fixed, so performance in the end might be an issue (re-distributing a running environment is not easy, so in this design you are still dependent on faster machines if there is more growth then expected).

Design concept to prevent duplicate orders being received into my system

I have a web system that I built that is an online ordering portal for our customers. We store their stock and they place orders for it through this portal.
We do a duplication check on the customer reference number so that the same order cannot come through twice, however we have been experiencing some issues whereby if a customer sends the order to our API multiple times (within milliseconds, if that, of eachother), our system doesn't have enough time to mark the order as received and as such, the system is allowing duplicates.
I am trying to decide on ways to combat this. I don't want to use database constraints for this as I find this an application issue rather than a database issue and don't believe this is a good solution.
Any design ideas on how to combat this? One solution I thought of was to use a mutex with the reference number so that if a mutex is locked for that reference number, then it might retry in a second etc? My understanding is that Mutex's are almost fool proof as they are enforced by the filesystem?
Any ideas would be appreciated
You could try employing a nonce strategy. The idea is to set random number to a hidden form field and store it in the session. Verify the id on post. The user has to deliberately refresh the page to obtain a new id and be able to post a second time.
update
So since you are using API service, then I would have to say you could use a batch system. Where an order comes in and gets stored in a holding area. A chron job runs through the batch and does the necessary pruning operations.

Store some records in the application and some in the database?

I have an application where it seems as if it would make sense to store some records hard-coded in the application code rather than an entry in the database, and be able to merge the two for a common result set when viewing the records. Are there any pitfalls to this approach?
Firstly, it would seem to make it easier to enforce that a record is never edited/deleted, other than when the application developer wants to. Second, in some scenarios such as installing a 3rd party module, the records could be read from their configuration rather than performing an insert in the db (with the related maintenance issues).
Some common examples:
In the application In the database
----------------------------------- ------------------ ----------------------
customers (none) all customers
HTML templates default templates user-defined templates
'control panel' interface languages default language additional languages
Online shop payment processors all payment processors (none)
So, I think I have three options depending on the scenario:
All records in the database
Some records in the application, some records in the database
All records in the application
And it seems that there are two ways to implement it:
All records in the database:
A column could be flagged as 'editable' or 'locked'
Negative IDs could represent locked values and positive IDs could represent editable
Odd IDs represent locked and even IDs represent editable...
Some records live in the application (as variables, arrays or objects...)
Are there any standard ways to deal with this scenario? Am I missing some really obvious solutions?
I'm using MySQL and php, if that changes your answer!
By "in the application", do you mean these records live in the filesystem, accessible to the application?
It all depends on the app you're building. There are a few things to consider, especially when it comes to code complexity and performance. While I don't have enough info about your project to suggest specifics, here are a few pointers to keep in mind:
Having two possible repositories for everything ramps up the complexity of your code. That means readability will go down and weird errors will start cropping up that are hard to trace. In most cases, it's in your best interest to go with the simplest solution that can possibly work. If you look at big PHP/MySQL software packages you will see that even though there are a lot of default values in the code itself, the data comes almost exclusively from the database. This is probably a reasonable policy when you can't get away with the simplest solution ever (namely storing everything in files).
The big downside of heavy database involvement is performance. You should definitely keep track of all the database calls of any typical codepath in your app. If you rely heavily on lots of queries, you have to employ a lot of caching. Track everything that happens and keep in mind what the computer has to in order to fulfill the request. It's you job to make the computer's task as easy as possible.
If you store templates in the DB, another big performance penalty will be the lack of opcode re-use and caching. Normal web hosting environments compile a PHP file once and then keep the bytecode version of it around for a while. This saves subsequent recompiles and speeds up execution substantially. But if you fill PHP template code into an eval() statement, this code will have to be recompiled by PHP every single time it's called.
Also, if you're using eval() in this fashion and you allow users to edit templates, you have to make sure those users are trusted - because they'll have access to the entire PHP environment. If you're going the other route and are using a template engine, you'll potentially have a much bigger performance problem (but not a security problem). In any case, consider caching template outputs wherever possible.
Regarding the locking mechanism: it seems you are introducing a big architectural issue here since you now have to make each repository (file and DB) understand what records are off-limits to the other one. I'd suggest you reconsider this approach entirely, but if you must, I'd strongly urge you to flag records using a separate column for it (the ID-based stuff sounds like a nightmare).
The standard way would be to keep classical DB-shaped stuff in the DB (these would be user accounts and other stuff that fits nicely into tables) and keep the configuration, all your code and template things in the filesystem.
I think that keeping some fixed values hard-coded in the application may be a good way to deal with the problem. In most cases, it will even reduce load on database server, because some not all the values must be retrieved via SQL.
But there are cases when it could lead to performance issues, mainly if you have to join values coming from the database with your hard-coded values. In this case, storing all the values in database may have better performance, because all values could be optimized and processed by the database server, rather than getting all the values from SQL query and joining them manually in the code.
To deal with this case, you can store the values in database, but inserts and updates must be handled just by your maintenance or upgrade routines. If you have a bigger concern about not letting the data be modified, you can setup a maintenance routine to check if the values from the database are the same as the code from time to time. In this case, this database tables act much like a "cache" of the hard-coded values. And when you don't need to join the fixed values with the database values, you can still get them from the code, avoiding an unnecessary SQL query (because you're sure the values are the same).
In general, anytime you're performing a database query if you want to include something that's hard-coded into the work-flow, there isn't any joining that needs to happen. You would simply the action on your hard-coded data as well as the data you pulled from the database. This is especially true if we're talking about information that is formed into an object once it is in the application. For instance, I can see this being useful if you want there to always be a dev user in the application. You could have this user hard-coded in the application and whenever you would query the database, such as when you're logging in a user, you would check your hard-coded user's values before querying the database.
For instance:
// You would place this on the login page
$DevUser = new User(info);
$_SESSION['DevUser'] = $DevUser;
// This would go in the user authentication logic
if($_SESSION['DevUser']->GetValue(Username) == $GivenUName && $_SESSION['DevUser']->GetValue(PassHash) == $GivenPassHash)
{
// log in user
}
else
{
// query for user that matches given username and password hash
}
This shows how there doesn't need to be any special or tricky database stuff going on. Hard-coding variables to include in your database driven workflow is extremely simple when you don't over think it.
There could be a case where you might have a lot of hard-coded variables/objects and/or you might want to execute a large block of logic on both sets of information. In this case it could be beneficial to have an array that holds the hard-coded information and then you could just add the queried information to that array before you perform any logic on it.
In the case of payment processors, I would assume that you're referring to online payments using different services such as PayPal, or a credit card, or something else. This would make the most sense as a Payment class that has a separate function for each payment method. That way you can call whichever method the client chooses. I can't think of any other way you would want to handle this. If you're maybe talking about the payment options available to your customers, that would be something hard-coded on your payment page.
Hopefully this helps. Remember, don't make it more complicated than it needs to be.

PHP - Is this a good method to prevent re-submission?

This is related to preventing webform resubmission, however this time the context is a web-based RPG. After the player defeats a monster, it would drop an item. So I would want to prevent the user from hitting the back button, or keep refreshing, to 'dupe' the item-drop.
As item drop is frequent, using a DB to store a unique 'drop-transaction-id' seems infeasible to me. I am entertaining an idea below:
For each combat, creating an unique value based on the current date-time, user's id and store it into DB and session. It is possible that given a userid, you can fetch the value back
If the value from session exists in the DB, then the 'combat' is valid and allow the user to access all pages relevant to combat. If it does not exist in DB, then a new combat state is started
When combat is over, the unique value is cleared from DB.
Values which is 30mins old in the DB are purged.
Any opinions, improvements, or pitfalls to this method are welcomed
This question is very subjective, there's things you can do or can not do, depending on the already existing data / framework around it.
The solution you've provided should work, but it depends on the unique combat/loot/user data you have available.
I take it this is what you think is best? It's what I think is best :)
Get the userID, along with a unique piece of data from that fight. Something like combat start time, combat end time, etc
Store it in a Database, or what ever storage system you have
Once you collect the loot, delete that record
That way if the that userID, and that unique fight data exists, they haven't got their loot.
And you are right; tracking each piece of loot is too much, you're better off temporarily storing the data.
Seems like a reasonable approach. I assume you're storing the fact that the player is in combat somewhere anyway. Otherwise, they can just close their browser if they want to avoid a fight?
The combat ending and loot dropping should be treated as an atomary operation. If there is no fight, there can't be any dropping loot.
That depends on your game design: Do you go more in the direction of roguelikes where only turns count, and therefore long pauses in between moves are definitely possible (like consulting other people via chatroom, note: in NetHack that is not considered cheating)? Can users only save their games on certain points or at any place? That makes a huge difference in the design, e.g. making way for exploits similar to the one Thorarin mentions.
If your game goes the traditional roguelike route of only one save, turn basement and permadeath, then it would be possible to save the number of the current turn for any given character along with any game related information (inventory, maps, enemies and their state), and then check against that at any action of the player, therefore to prevent playing the turn twice.
Alternatively you could bundle everything up in client side javascript, so that even if they did resubmit the form it would generate an entirely new combat/treasure encounter.

Should I use "id" or "unique username"?

I am using PHP, AS3 and mysql.
I have a website. A flash(as3) website. The flash website store the members' information in mysql database through php. In "members" table, i have "id" as the primary key and "username" as a unique field.
Now my situation is:
When flash want to display a member's profile. My questions:
Should Flash pass the member "ID" or "username" to php to process the mysql query?
Is there any different passing the "id" or "username"?
Which one is more secure?
Which one you recommend?
I would like to optimize my website in terms of security and performance.
1) Neither is inarguably the thing it should do.
2) The ID is probably shorter and minisculely faster to look up. The ID gives away slightly more information about your system; if you know that a site uses serial IDs at all, and you know what one of them is, that's pretty much as good as knowing all of them, whereas knowing one username does not tell you the usernames of any other users. On the other hand, the username is more revelatory of the user's psychology and may constitute a password hint.
3) Both have extremely marginal downfalls, as described in item 2.
4) I'd use the ID.
The primary key is always the safest method for identifying database rows. For instance, you may later change your mind and allow duplicate usernames.
Depending on how your ActionScript is communicating with PHP, it will likely also require sending fewer bytes if you send an integer ID in your request rather than a username.
Arguments for passing id number:
People never change their id. People do change their names. For a casual games site with disposable accounts, that might not be a problem, but for long-term registered users it can be. I've had to handle a demand by an upset woman that her ex-husband's surname be purged from her user name. A process for doing this had to be rapidly established!
Shorter
Easier to index and partition.
Arguments for passing user name:
Slightly harder (but not impossible) to guess a legal, existing account - e.g. to peruse random people's records, if that's your thing.
Probably you should get intimately familiar with "PHP Sessions", maybe using a framework that already has this in place, because it's non-trivial and you don't want to mess it up. The session management software will then handle all this for you, including login screens, "I forgot my password", etc.
Then you can focus your attention on what your site is really primarily there for.
Sounds like fun (actionscript + php + mysql) - good luck!

Categories