Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I have a question for people who have experience working with Oracle and PHP. Please this is not to open a meaningless debate. I just want to make sure everything is considered correctly in my system.
I am working on a project in which there are thousands of users, divided into groups and sub groups. Each group has its different access rights and each subgroup has its own privileges.
I need to have your opinion about these two approaches:
Implementing access rights and privileges in PHP with one big
application user(oracle account),(I am clueless as to the advantages
and disadvantages of this approach).
Implementing access rights and privileges in Oracle database(each
user would be an Oracle account) and use the virtual private
database, caching, secure roles.... from a performance stand point
this is the best approach. Security! well I know it is good but I am
afraid I am missing good things not implementing it in PHP.
I did some research on the net but in vain(I scratched my head a lot). I am new to PHP but I have good knowledge about Oracle.
Any suggestions, Ideas?
As you say you're going to have 1000s of users, i assume your software is going to be used in a big company, which probably means there's not one IT department, but several of them - one providing managed basic hardware (OS level but no applications), another managing databases, and a third one putting it all together (hardware+os, database, application) and providing the managed application as a service for the end user. My decision might be heavily influenced by working for such a department for over 10 years now.
I've seen one application that used the "one database user per OS user" approach (VPM by Dassault Systems, an attachment to the Catia V4 CAD system - and it's a horror to maintain. You want to have your permissions in ONE place, not several. Possibly you have a nice GUI to change them, but when your user calls you saying "i can't do X", and your GUI says he should be able to do X, it's simply too tedious to search everywhere. We've had cases where views didn't have the access roles they should have, views were wrongly defined, users had permissions on some tables but not all of them, all that stuff.
Additionally, our database department has - at the moment - about 600 "databases" that are used by diffent departments. So they are running about 20 real "databases" on several clusters, and they have implemented quite a rigid scheme of database names and corresponding user names. Each database has a base name XXX, with XXX_A the user name DDL statements, and XXX_U for DML. Applications may ONLY use XXX_U, which also means applications may not do DDL. This allows the database admins, in case of load issues on the cluster, to move an entire schema, including all users, roles and tables, to a different instance on a different cluster easily, without knowing too much about the individual databases. Of course, our VPM database doesn't fit into that schema, so we had to argue with the DB people a lot - and our monthly charge by the DB department is much higher than normal, because they have much more trouble administrating it.
Bottom line: Don't expect you can do whatever you want within your database. In a large company, with a department managing the databases, you will have restrictions what your application is allowed to do and what it isn't.
Also, your management might, at one time, decide they want to move to a different database system like DB2 for political reasons. This has much less to do with technical advantages than with who's invited whom to golf. You might, at one time, be asked if your system could be moved to a different database, by people you don't want to say "no" to. I wouldn't want to be dependent on too specific oracle features in this case.
Also keep in mind that requirements change over time, and there might be new, more granular, requirements in a while. This strongly favours doing the permission stuff in software, because it's much easier to add another column to a permission table that specifies something new, instead of having to implement something new in a database permission structure that just isn't meant to handle this kind of thing.
If you were developing a native application that runs on individual users' PCs, using only one oracle account might be a big security hole. But as you're using PHP, it's only the server that's communicating with the DB, so noone can extract login information from userspace anyways.
In my opinion, create an api for permission management first. Do not use oracle users, groups and roles for that; instead, manage your permissions in some SQL tables. Create an api (a collection of check_if_user_X_may_do_Y functions), possibly in pl/sql if you feel more comfortable there, better in PHP if you want to be portable. Build your application on this API. It might be more dev work at the start, but will result (imho) in much less administration work later.
Although Guntram makes some very salient points, he has missed what I consider to be fairly essential considerations:
1) you describe a 3 tier model of authorization which the Oracle permissions model does not accomodate (although it is possible to represent this as a 2-tier model but at the cost of creating work and complexity).
2) using the user supplied credentials to authenticate against the database pretty much precludes the use of persistent database connections - which is rather important when your connection setup time is as expensive as it is with Oracle.
By all means store the representation of the groups/sub-groups/users/permissions in the database but not as Oracle users. But use a single (or small number) of oracle accounts for the access from PHP to the DBMS.
If you want to implement strong security, then you should also store mappings between sessions ids and users (not necessarily the session data itself) in the database, allow no direct access from the designated Oracle accounts to the data - only via stored procedures - and pass the session id as an authentication token to the stored procedure and validate it there (but note that this will be rather expensive if you are using trivial ORM).
Related
I've recently taken over a project linking to a large MySQL DB that was originally designed many years ago and need some help.
Currently the DB has 5 tables per client that store their users information, transaction history, logs etc. However we currently have ~900 clients that have applied to use our services, with an average of 5 new clients applying weekly. So the DB has grown to nearly 5000 tables and ever increasing. Many of our clients do not end up using our services so their tables are all empty but still in the DB.
The original DB designer says it was created this way so if a table was ever compromised it would not reveal information on any other client.
As I'm redesigning the project in PHP I'm thinking of redesigning the DB to have an overall user, transaction history, log etc tables using the clients unique id to reference them.
Would this approach be correct or should the DB stay as is?
Could you see any possible security / performance concerns
Thanks for all your help
You should redesign the system to have just five tables, with a separate column identifying which client the row pertains to. SQL handles large tables well, so you shouldn't have to worry about performance. In fact, having many, many tables can be a hinderance to performance in many cases.
This has many advantages. You will be able to optimize the table structures for all clients at once. No more trying to add an index to 300 tables to meet some performance objective. Managing the database, managing the tables, backing things up -- all of these should be easier with a single table.
You may find that the database even gets smaller in size. This is because, on average, each of those thousands of tables has a half-paged filled at the end. This will go from thousands of half-pages to just one.
The one downside is security. It is easier to put security on tables than one rows in tables. If this is a concern, you may need to think about these requirements.
This may just be a matter of taste, but I would find it far more natural - and thus maintainable - to store this information in as few tables as possible. Also most if not all database ORMs will be expecting a structure like this, and there is no reason to reinvent that wheel.
From the perspective of security, it sounds like this project could be described as a web app. Obviously I don't know the realities of the business logic you're dealing with, but it seems like regardless of the table permissions all access to the database would be via the code base, in which case the app itself needs full permissions for all tables - nullifying any advantage of keeping the tables separated.
If there is a compelling reason for the security measures - say, different services that feed data into the DB independently of the web app, I would still explore ways to handle that authentication at the application layer instead of at the database layer. It will be much easier to handle your security rules in that way. Instead of having rules set in 5000+ different places, a single security rule of 'only let a user view a row of data if their user id equals the user_id column" is far simpler, easier to understand, and therefore far more maintainable (and possibly more secure).
Different people approach databases in different ways. I am a web developer, so I view databases as the place to store my data and nothing more, as it's always a dedicated and generally single-purpose DB installation, and I handle all other logic at the application level. There are people who view databases as the application itself, who make far more extensive use of built-in security features for their massive, distributed, multi-user systems - but I honestly don't know enough about those scenarios to comment on exactly where that line should be drawn.
I'm currently developping an application which allows doctors to dinamically generate invoices. The fact is, each doctors requires 6 differents database tables, and there could be like 50 doctors connected at the same time and working with the database (writing and reading) at the same time.
What I wanted to know is if the construction of my application fits. For each doctors, I create a personnal Sqlite3 database (all database are secure) which only him can connect to. I'll have like 200 Sqlite database, but is there any problems ? I thought it could be better than using a big MySQL database for everyone.
Is this solution viable ? Will I have problems to deal with ? I never did such an application with so many users, but I thought it could be the best solution
Firstly, to answer your question: no, you probably will not have any significant problems if a single sqlite database is used only by one person (user) at a time. If you highly value certain edge cases, like the ability to move some users/databases to another server, this might be a very good solution.
But it is not a terribly good design. The usual way is to have all data in the same database, and tables having a field which identifies which rows belong to which users. The application code is responsible for maintaining security (i.e. not to let users see data which doesn't belong to them), and indexes in the database (which you should use in all cases, even in your own design) are responsible for making it fast.
There are a large number of tutorials which could help you to make a better database design; a random google result is http://www.profsr.com/sql/sqless02.htm .
You'll have to bear with me here for possibly getting some of the terminology slightly wrong as I wasn't even aware that this fell into the whole 'multi-tenant' 'software as a service' category, but here it does.
I've developed a membership system (in PHP) for a client. We're now looking at offering it as a completely hosted solution for our other clients, providing a subdomain (or even their own domain).
The options I seem to have on the table, as far as data storage goes are:
Option 1 - Store everything in 1 big database, and have a 'client_id' field on the tables that need it (there would be around 30 tables that it would apply to), and have a 'clients' table storing their main settings, details, etc and the domain to map to them. This then just sets a globally accessible variable containing their individual client id - I'd obviously have to modify every single query to check for the client_id column.
Option 2 - Have a master table with the 'shared reference' tables, and the 'clients' table. Then have 'blocks' of other databases, which each contain, say 10 clients. The client would get their own database tables, prefixed with their client ID. This adds a little bit of security to protect against seeing other client data if something went really wrong.
Option 3 - Exactly the same as option 2, except you have 1 database for each and every client, completely isolating them from other clients, and theoretically providing a bit more protection that if 1 client's tables were hacked or otherwise damaged, it wouldn't affect anyone else. The biggest downside is that when deploying a new client, an entire database, user and password need setting up, etc. Could this possibly also cause a fair amount of overhead, or would it be pretty much the same as if you had everyone in one database?
A few points as well - some of these clients will have 5000+ 'customers' along with all the details for those customers - this is why option 1 may be a bit of an issue - if I've got 100 clients, that could equal over half a million rows in 1 table.
Am I correct in thinking Option 3 would be the best way to go in a situation where security of customer data (and payment information) is key. From recommendations I've had, a few people have said to go with option 1 because 'its easier' however I really don't see it that way. I see it as a potential bottleneck down the line, as surely I can move clients around much easier if they have their own database.
(FYI The system is PHP based with MySQL)
Option 3 is the most scalable. While at first it may seem more complicated, it can be completely automated and will save you headaches on the future. You can also scale more efficiently by having client databases on multiple servers for increased performance.
I agree with Ozzy - I did this for an online database product. We had one master database that basically had a glorified user table. Each customer had their own database. What was great about this is that I could move one customers database from server A to server B easily [mysql] and could do so with command line tools in a pinch. Also doing maintenance on large tables, dropping/adding indexes can really screw up your application, especially if say, adding an index locks the table [mysql]. It affects everyone. With, presumably, smaller databases you are more immune to this and have more options when you need to roll out schema level changes. I just like the flexibility.
When many years ago I designed a platform for building SaaS applications in PHP, I opted for the third option: multi tenant code and single tenant databases.
In my experience, that is the most scalable option, but it also needs a set of scripts to propagate changes when updating code, DB schemes, enabling applications to a tenant, etc.
So a lot of my effort went in building a component based, extensible engine to fully automate all those tasks and minimize system administration stuff. I strongly advise to build such an architecture if you want to adopt the third option.
I'm part of a team currently developing a dedicated SaaS service for a specific crowd of organizations.
I have knowledge in PHP and mySQL, so I am developing it on these platforms. Will be deploying this on the cloud and releasing in multiple countries.
Ive come to the point of separating organizations/main-users in the database and wanted to see what you guys think.
When the SaaS manages invoices and many other sensitive information what would be the best process of distributing it on the mySQL server? Ive thought of the below options:
1) having all information in a single database in single tables and separated by a organization identifying row. - does seem secure and may be slow when there are a few thousand users and 10,000 rows?
2) having a single database but separating tables with a user id eg. '1000_invoices' - again may be faster but not as secure.
3) have separate databases created on each organization signup and a specific user used to access the database and the database name is stored in the sessions/cookie? per organizations users.
Anyway i was wondering what you guys think will be the best option? and if not the above then what do you recommend? and why? also anything regarding security will be greatly appreciated. Have not worked with large multi-organization applications before.
thanks in advance!
I've developed numerous SaaS applications in the past and we've found the "single application deployment, single datatabase" setup as used by large "public" SaaS services (like KashFlow, possibly Salesforce?) didn't make much sense. Here's why:
Number 1: Client companies with confidential information are going to want assurances their data is more "secure" and it's easier to make these promises when their data is partitioned beyond the application tier.
Different clients sometimes want their software application customized to them, such as their own extra database fields, a different login screen visual design, or different (or custom) system "modules" - having different application instances makes this possible
It also makes scaling easier, at least when beginning. It's easier to load-balance by provisioning a single client's application to its own server separate from the others, whereas with a single application it means you need to spend longer developing it to make it scalable.
Database primary keys are easier to work with. Your customers might start asking questions such as why their "CustomerID" values increment by 500 each time instead of by 1.
If you've got customers located around the world, it's easier to provision a deployment in another country (with its own local server and DB server) rather than deploying a giant application abroad or forcing users to use intercontinential (i.e. slow+laggy) connections to your servers located thousands of miles away.
There are downsides, such as the extra administrative burden of managing hundreds, possibly thousands of databases, in addition to application software deployments, but the vast, vast simplifications it makes to the program code make it worthwhile. Besides, automating provisioning and deployment is easy with a bunch of shell-scripts.
This isn't about a specific problem I'm having, but I have to clear something up as I have alot at stake with this project.
I'm creating a web application that will deployed to some BIG companies in the UK and if we get this wrong it could cost us hugely!
I need to keep each companies data VERY secure, so what I was wondering is would it be a good idea to create a new database for each organisation, this way their data is totally seperate and if one database is compromised the data for all the organisations wouldn't be effected - this would give us time to react to the security problem before all the data is compromised. My Questions are:
What are the short term and long term benefits of this (if any)
What are the short term and long term drawbacks of this (if any)
Is this good practice?
Would it even solve a security issue in the way I anticipate?
Thanks in advance
I'm assuming this is a question about building a "multi-tenanted architecture" for a "software as a service" style application.
The first issue is that separating your databases may or may not be a good idea - but it's not the first question to ask. Someone who can get access to your databases at the level where this matters has already penetrated your application in ways that are hugely damaging - they can almost certainly execute arbitrary commands on your database server. This means that you're not just dealing with damage to one account, but to your entire infrastructure. It's a "lights out" moment, and you have to shut down the whole system whilst you recover.
If they haven't established a shell on your database server, it would mean there's an application-layer security issue - SQL injection, or some way of escalating privileges in your authentication scheme. Again, both are "lights out" moments.
So, make sure all that stuff is totally covered. Include security testing in your development lifecycle; consider using automated penetration testing tools as part of your continuous integration system. Make sure the infrastructure guys harden the whole environment, and consider having a 3rd party security audit when you get close to a release candidate. Consider a code review process focussed on security issues, and agree coding standards with specific security considerations. Tell all your developers about cross site scripting, SQL injection and other application-level vulnerabilities.
Once you've done all that, you've locked the doors and bolted the windows; your database strategy is the equivalent of how you keep the jewelry safe.
Separate databases offer some additional security - but only if you have a corresponding strategy for user management. In most web applications, there are only 2 types of user: "admin" and "web app". "Admin" can create/modify databases (creating databases, tables, views etc.), and can usually also modify data. "Web app" should have only data modification rights, but no rights to modify databases objects.
For splitting the databases to make sense, you must ensure that:
an attacker who can get access to your web application's file system cannot get access to valid user names and passwords, or if they can, only for one client.
an attacker can never get access to the "admin" credentials
However, there are other reasons (beyond security) where it makes sense to split up your databases. It reduces the risk of human error, it allows you to scale your system at a more granular level, and it allows you to offer different levels of hosting ("gold" users get their own server, "silver" their own database, "bronze" take their chances).
The big issue you have to solve to make this happen is deployments - how will you deploy new versions of the code, with changes to the database? This in turn may complicate the testing process.
Separate databases, almost certainly. As #Anigel says, perhaps even separate servers, although the management and cost of that is more complex, so will depend on your exact requirements.
One benefits is that at some point in the future, perhaps one client's data gets bigger, so it's easier to split to a new server, or perhaps they get an upgrade of your platform but another doesn't.
Backup and restore is easier if you can dump/load whole databases, rather than picking out all the tables with names beginning with clientX_.
Performance measurement will be easier on separate databases.
Just a few quick ideas to get started.
#Lee Price, Maintaining the separate database for every company will be great thing.
Advantages:
It will keep your database secure
In long time when the size of the tables are limited to a single company that will give you a drastic performance. The operations will be fast.
Easy to manipulate the data company wise.
Help out in terms of support
Disadvantages:
Need to Keep track of the schema change for every company
Maintain Separate databases
Maintain separate backups
Occupy more space as compare to a single database
But i will personally suggest you to go with the separate database for each company.