Safe submitting primary keys - php

I don't know how to program webpages very well so I have the following question. I have a MySQL database which a user can manage. I have two tables: persons, videos.
I want my page for the user to select a person from the persons table (by name for example) and then associate this person with a video link.
Selecting the person from database is easy,
SELECT personID, name
FROM persons
WHERE name LIKE '%John%'
So now the user has to insert a video link to the videos table which has a foreign key the personID.
I could store the primary key of the person after the "select" in a hidden html input form but I assume this is not very secure as they can edit it?
My question is: Where would you store such a key value in between a select and an insert call?
Is it safer to store all this data in a session instead?

This sort of thing happens quite a lot, and it's completely fine as long as you don't mind people seeing your primary keys (if they're numbers, it shouldn't be anything to worry about).
Let's say you're retrieving a list of rows from a table, and displaying them in HTML. If you want each table row to have a 'delete' button for deleting that row, both from the DOM and in the Database, say via an XMLHttpRequest, it's typical for each row to have an "id" attribute, with the id being the primary key value of the row you wish to delete.
Typically, your primary key will be:
The id field in your table
The field with AUTO_INCREMENT set
In short, give each dropdown a data-id attribute, which you access in your JavaScript via the .data selector. That's good enough. Just make sure you're also protecting yourself from SQL Injection and using PDO and prepared statements, and you'll be fine.
For extra protection, and to make sure nobody has altered the data-id attribute client-side before submit, check that the id corresponds to the name field in the database, and you're golden.

I think storing this type of data in the session is secure and a good choice. After all, it's session-scoped, so there's no reason to output it.
It would be more secure to store it in the session and, ofcourse, easier to access and manage.

Related

html table with data from database without populating database row id php

I am constructing html table with data queried from database using php. I also need to perform edit,delete operations on that table. I am saving the
database row id as hidden input field in each table row.
What I am doing is when user clicks on the particular row I getting the row id using jquery and performing edit/delete operations on the database table
using ajax,php
But the problem here is when user inspects element he can see the ids of each row. So if the user is technical expert he can edit the row id and change the
value of other rows in database table.
Generally how to handle this type of situations without populating database row id in table.
If the user is that kind of expert to look in inspector and manipulate that hidden info, and that is something that has to be strictly not possible to change, you could send guid or some custom backend function that encrypt / decrypt the info from user table..
Populating the row id is a correct, but if the user can change the values of some records but not others, the correct solution would be check server-side if the user has the privileges to edit the row that is currently trying to edit
You can take more info from the any cell of the row.
You save the id in your hidden input then take with jquery any cell and if the data cell and the id are not same in DB don't do anything if have relation then Delete.
hope it will be useful
For more security you have to create hash of each row and send to ajax page and verify both the hash . since it is a one way encryption so you hash for each row is unique..
Here is what i am saying to you
https://www.owasp.org/index.php/How_to_protect_sensitive_data_in_URL's

What is the proper way to store user preferences in a database?

I have a MySQL database that stores user emails and news articles that my service provides. I want users to be able to save/bookmark articles they would like to read later.
My plan for accomplishing this was to have a column, in the table where I store the users' emails, that holds comma-delineated strings of unique IDs, where the unique IDs are values assigned to each article as they are added into the database. These articles are stored in a separate table and I use UUID_SHORT() to generate the unique IDs of type BIGINT.
For example, let's say in the table where I store my articles, I have
ArticleID OtherColumn
4419350002044764160 other stuff
4419351050184556544 other stuff
In the table where I store user data, I would have
UserEmail ArticlesSaved OtherColumn
examlple1#email.com 4419350002044764160,4419351050184556544,... other stuff
examlple2#email.com 4419350002044764160,4419351050184556544,... other stuff
to indicate the first two users have saved the articles with IDs 4419350002044764160 and 4419351050184556544.
Is this a proper way to store something like this on a database? If there is a better method, could someone explain it please?
One other option I was thinking of was having a separate table for each user where I can store the IDs of the articles they saved into a column, though the answer for this post that this is not very efficient: Database efficiency - table per user vs. table of users
I would suggest one table for the user and one table his/her bookmarked articles.
USERs
id - int autoincrement
user_email - varchar50
PREFERENCES
id int autoincrement
article_index (datatype that you find accurate according to your structure)
id_user (integer)
This way it will be easy for a user to bookmark and unbookmark an article. Connecting the two tables are done with id in users and id_user in preferences. Make sure that each row in the preferences/bookmarks is one article (don't do anything comma seperated). Doing it this way will save you much time/complications - I promise!
A typical query to fetch a user's bookmarked pages would look something like this.
SELECT u.id,p.article_index,p.id_user FROM users u
LEFT JOIN preferences ON u.id=p.id_user
WHERE u.id='1' //user id goes here, make sure it's an int.. apply appropriate security to your queries.
"Proper" is a squirrely word, but the approach you suggest is pretty flawed. The resulting database no longer satisfies even first normal form, and that predicts practical problems even if you don't immediately see them. Some of the problems you would be likely to encounter are
the number of articles each user can "save" will be limited by the data type of the ArticlesSaved column;
you will have issues around duplicate "saved" article IDs; and
queries about which articles are saved will be more difficult to formulate and will probably run slower; in part because
you cannot meaningfully index the the ArticlesSaved column.
The usual way to model a many-to-many relationship (such as between users and articles) is via a separate table. In this case, such a table would have one row for each (user, saved article) pair.
Saving data in CSV format in a database field is (almost) never a good idea. You should have 3 tables :
1 table describing users with everything concerning directly the user
1 table describing articles with data about it
1 table with 2 columns "userid" and "articleid" linking both. If a user bookmarks 10 articles, this table will have 10 records with a different aticleid each time.

Using HTML Input's Tag Attribute for SQL Query Without Revealing Database Table Row ID

I have a code that loads each row of a mysql table as a "value" attribute of an HTML input element. The idea is that to show the current value and also give the user the ability to update the value.!
The issue is when the user wants to update/change the value, I have to know which row of the table is to be updated. I am using the "id" attribute for this purpose. Currently, I have two solutions, both very similar (please refer to the image above):
Use the current value as the "id" attribute, i.e. id="Foo", then use AJAX to form a query that locates the id value through a "SELECT id FROM user_comment WHERE comment='$currentValue'" and then update the comment
The image above: have another table with temporary "alias" for each address. assigned_add[ress] is a random value and will be overwritten once the user is done with page; or the table will be dropped.
The goal is to hide the "real" user_comment.id from the user and not expose it through the "tag" attribute. I am not sure if there is a more common way of doing this, I haven't been able to find anything on SO.
Is there a better way of hiding the id?
What's wrong with using the actual id ?
You might want to secure your code against SQL injections too
SELECT id FROM user_comment WHERE comment='$currentValue'

Dynamically change mySql db table

I am working on a web application that manages the clients of the company. Details such as phone, address, email and name are saved for each client and there are corresponding fields in the database table where I save these details.
The user of the application has to be able to change the different details. For instance, he might decide that we need an extra field to save the fax number of the client or he may decide that the address field is no longer needed and delete it.
Using NoSql is not a option. I have to use PHP and mySql.
I have been considering using a JSON string to save database table fields but I have not come up with a solution yet.
Is altering the structure of my db table the only solution to my problem? I would like to prevent dynamically altering the structure of the db table, if possible.
Would it be a could idea to implement dynamic views? However, I guess that this would not address the necessity to insert new fields.
Thank you in advance.
Wouldn't it make more sense to have another table, let's call it 'information' which has the user_id as a foreign key?
So you have:
CREATE TABLE user (
user_id ...
/* necessary information */
);
CREATE TABLE information (
user_id ...
information_type /* maybe enum, maybe just string, maybe int, depending how you want to do that */
information_blob
);
You then retrieve the information with JOIN, and do not have to alter the table every time somebody wants to add another bit of info.
What you need a key-value pair system for MySQL. The idea of NoSQL databases is that you can create your own schema based on key/values, using essentially anything for the value.
Create a table special_fields with a field_name column, or something named more specifically to field names. Use this table to define the available field names, and another table to store the client_id and special_field_id and then a value.
So client #1 would have an address (special_field record #1) value of "123 x street"
The only other way I can think of is to actually change the schema of a table to add/remove columns. Don't do that.

How can we re-use the deleted id from any MySQL-DB table?

How can we re-use the deleted id from any MySQL-DB table?
If I want to rollback the deleted ID , can we do it anyhow?
It may be possible by finding the lowest unused ID and forcing it, but it's terribly bad practice, mainly because of referential integrity: It could be, for example, that relationships from other tables point to a deleted record, which would not be recognizable as "deleted" any more if IDs were reused.
Bottom line: Don't do it. It's a really bad idea.
Related reading: Using auto_increment in the mySQL manual
Re your update: Even if you have a legitimate reason to do this, I don't think there is an automatic way to re-use values in an auto_increment field. If at all, you would have to find the lowest unused value (maybe using a stored procedure or an external script) and force that as the ID (if that's even possible.).
You shouldn't do it.
Don't think of it as a number at all.
It is not a number. It's unique identifier. Think of this word - unique. No record should be identified with the same id.
1.
As per your explanation provided "#Pekka, I am tracking the INsert Update and delete query..." I assume you just some how want to put your old data back to the same ID.
In that case you may consider using a delete-flag column in your table.
If the delete-flag is set for some row, you shall consider program to consider it deleted. Further you may make it available by setting the delete-flat(false).
Similar way is to move whole row to some temporary table and you can bring it back when required with the same data and ID.
Prev. idea is better though.
2.
If this is not what you meant by your explanation; and you want to delete and still use all the values of ID(auto-generated); i have a few ideas you may implement:
- Create a table (IDSTORE) for storing Deleted IDs.
- Create a trigger activated on row delete which will note the ID and store it to the table.
- While inserting take minimum ID from IDSTORE and insert it with that value. If IDSTORE is empty you can pass NULL ID to generate Auto Incremented number.
Of course if you have references / relations (FK) implemented, you manually have to look after it, as your requirement is so.
Further Read:
http://www.databasejournal.com/features/mysql/article.php/10897_2201621_3/Deleting-Duplicate-Rows-in-a-MySQL-Database.htm
Here is the my case for mysql DB:
I had menu table and the menu id was being used in content table as a foreign key. But there was no direct relation between tables (bad table design, i know but the project was done by other developer and later my client approached me to handle it). So, one day my client realised that some of the contents are not showing up. I looked at the problem and found that one of the menu is deleted from menu table, but luckily the menu id exist in cotent table. I found the menu id from content table that was deleted and run the normal insert query for menu table with same menu id along with other fields. (Id is primary key) and it worked.
insert into tbl_menu(id, col1, col2, ...) values(12, val1, val2, ...)

Categories