data type for emails - mysql

I have a program where the user can enter multiple email addresses to get notification. I'm creating a field in the database to keep track of this and I'm not sure what would be the best data type to choose for all the email addresses. At this point I believe we will limit it to 4 email addresses.
What data type would be appropriate here for mysql?
Not sure this is relevant but I plan to serialize the data (with php function) When processing the email addresses. Interested in any feedback on my plans and if there is a better way to do this.

This indicates that you have 1:many relation of user:email addresses. Create another table with user_id and email columns and link it up to your users table via user_id.
Never serialize data and stick it in a column, you'll regret it later.

Related

Should you put USER data in tables within a single MySQL database, or have a separate database for USER data?

Is there an advantage to separating user data into a separate MySQL database from the main application database? The number of tables in a db can add up, and separating them by function seems a good way to reduce the clutter.
The way I was told to think about your database data is that if you are going to be referencing the data again it should be in a separate table, just like if you are likely to enter the same data more than once it should be in a separate table and then linked or joined.
Using a separate Database is a little excessive.
For example lets say you have a user, who has an email address and a postal address.
There is a chance that the postal address could be used by more than one user (family members for example) so I would then put the User, eMail address and Postal Address into different tables each using the User row id as a join between each table.

Securing MySQL id numbers so they are not sequential

I am working on a little package using PHP and MySQL to handle entries for events. After completing an entry form the user will see all his details on a page called something like website.com/entrycomplete.php?entry_id=15 where the entry_id is a sequential number. Obviously it will be laughably easy for a nosey person to change the entry_id number and look at other people's entries.
Is there a simple way of camouflaging the entry_id? Obviously I'm not looking to secure the Bank of England so something simple and easy will do the job. I thought of using MD5 but that produces quite a long string so perhaps there is something better.
Security through obscurity is no security at all.
Even if the id's are random, that doesn't prevent a user from requesting a few thousand random id's until they find one that matches an entry that exists in your database.
Instead, you need to secure the access privileges of users, and disallow them from viewing data they shouldn't be allowed to view.
Then it won't matter if the id's are sequential.
If the users do have some form of authentication/login, use that to determine if they are allowed to see a particular entry id.
If not, instead of using a url parameter for the id, store it in and read it from a cookie. And be aware that this is still not secure. An additional step you could take (short of requiring user authentication) is to cryptographically sign the cookie.
A better way to implement this is to show only the records that belong to that user. Say the id is the unique identifier for each user. Now store both entry_id and id in your table (say table name is entries).
Now when the user requests for record, add another condition in the mysql query like this
select * from entries where entry_id=5 and id=30;
So if entry_id 5 does not belong to this user, it will not have any result at all.
Coming towards restricting the user to not change his own id, you can implement jwt tokens. You can give a token on login and add it to every call. You can then decrypt the token in the back end and get the user's actual id out of it.

Which data can I unhesitatingly send over a GET request?

I create a VueJS application with express and sequelize to access a mysql database (currently running with XAMPP). I have a database which consist of 3 tables:
users: [id (primary key), name, email, family_id (foreign key)]
families: [id (primary key), name]
hobbies: [id (primary key), name, user_id (foreign key)]
All of these IDs are auto_increment so the first user registered gets the ID 1 and so on.
Every user within the same family (so with equal family_id) is allowed to see the hobbies of the other family members. I have a SQL query, which gives me all the family members. On my websity I have a simple drop down menu, where I can select the member. With a GET request I then want to retrieve all hobbies of the selected member.
Now I can basically decide if I use the id or the email for the request parameter e.g. /api/hobbies/:id or /api/hobbies/:email. Email reveals more private information while id reveals information about my internal strucutre like "At least (id) number of users exists.". I think it is better to use the id.
Maybe there is also the possibility to assign a random id (not auto increment) in the database? But I dont know how to to this.
Nothing you send as a parameter to a GET request is private. Those parameters are part of the URL you GET, and those URLs can be logged in various proxy servers, etc, all over the internet without your consent or your users' consent.
It seem to me that family members' hobbies can be sensitive data. What if the whole family likes, say, golf? A cybercreep could easily figure out that a good time for burglary would be Saturday afternoons.
And if your app does GET operations with autoincrementing id values, it's child's play for a cybercreep to examine any record they want. Check out the Panera Bread data breach for example. https://krebsonsecurity.com/2018/04/panerabread-com-leaks-millions-of-customer-records/
At a minimum use POST for that kind of data.
Better yet, use a good authentication / session token system on your app, and conceal data from users if they're not members of that family.
And, if you want to use REST style GET parameters, you need to do these things to be safe:
Use randomized id values. It must be very difficult for a cybercreep to guess a second value from knowing a first value. Serial numbers won't do. Neither will email addresses.
Make sure unauthenticated users can see no data.
Make sure authenticated users can only see the subset of data for which they're authorized.
My suggestion to avoid REST-style GET parameters comes from multiple security auditors saying, you must change that.

most efficient way to organize a json data tree in firebase

what is the most efficient way to organize a json data tree in firebase since I need to post data and then check for repeated data
I am creating a simple email subscription structure
this model?
subscribers
RandomKeyCode
email
created_at
or this one?
subscribers
emailAsKey
email <--- repeat email field
created_at
(It seems to me more readable to use email as a key in this case, and I imagine I can check it more easily when the user tries to enter a repeated email.)
or some other way?
what is the most efficient way to organize a json data tree in firebase
Most efficient way would be to create a database where you can perform your queries very easily. The difference in your examples is the use of a RandomKeyCode vs. emailAsKey. When we are talking about users, the most common approach is to use the uid that is coming from the authentication process but according to the use-case of your app, you can store that data under a random key as well as under the email address. Is your choice whether to use one or the other approach.

MYSQL- Best design to store multiple emails/addresses for one user

I checked this question here but unfortunately the link to the diagram in not working so I'm stuck.
I am trying to have multiple emails for one user (work, business, personal, etc) and I'm not sure how to best approach this situation.
I am thinking to have 4 tables: user, email, email_type, and user_has_email (user N:M email).
I made two diagrams but I don't know which one would be the better one.
First diagram helps me if one user has the same email for both work and personal (because I don't have to store it twice). Second option is good as well but I would have to store emails twice or more even if one user uses the same email for work, business, personal, etc.
I am planning to use the same idea for storing addresses, which occupy more space than emails and I am thinking that the diagram 1 is more suitable for this.
What do you think?
Diagram 1
-explanation of user_has_email: I chose to make the email_type PK because there may be the case when a user has the same email for work or personal. If I don't PK the email_type I would only be able to have one email_type per user. Did I complicated it too much?
Diagram 2
Instead I would use
user (user_id, first_name, last_name)
user_emails (user_id, email_type_id, email)
email_types (email_type_id, email_type)
I would prefer Diagram 1 for the following reasons.
You can make the email field UNIQUE so that you can store it only once regardless of the type.
It does not seem right to make the email and the email type tightly coupled, if you face a situation where you have to establish a one-to-one relationship between the user and the email for some other feature.
Any kind of validation for the user-email relationship should be handled in the business logic (even if you have constraints in the database).
The following structure should fit the bill:
There is a 1:N relationship between users and e-mails, and each user's e-mail can have zero or more types, from the set of shared types.
If the e-mail types don't need to be shared among users, the model can be further simplified:
BTW, the case for using M:N for addresses is not clear either, due to the inherent "fuzziness" of addresses - see this post for some musings on the subject.