I would like to request a change in the configuration file (config.php) and standardization of any writeable directories in OpenEMR.
Upgrading and backups would be simplified if we put all of the writeable directories in the same location. This would include (I think) the following directories:
This would also make upgrades a lot easier as I would not have to transfer the images in and out of the documents in directory. As the number of documents grows it gets harder and harder to move all the images in the documents directory. Instead it would only be necessary to overwrite the old OpenEMR folder with the new folder and then fix the permissions where needed.
This is also true of any file that contains the database user and password such as:
The credentials are stored in a file outside the webserver root, read one time as the Apache engine starts and then used as needed to make the database conncetions but credentials are not in the Web server root to be accessed by an attacker. As an example, the XOOPS project uses this technique to get the database user and password out of the Web server path so that it not accessible to a skilful attacker.
I’ll second that idea and add one more:
Move all global variables into the database.
All we really need in a static text file are the database credentials.
Several big projects here, mostly backend, with no real improvement in perceived functionality. That being said, agree it would be nice.
Several things to note:
Forgot the following write directories:
openemr/interface/main/calendar/modules/PostCalendar/pntemplates/cache
openemr/interface/main/calendar/modules/PostCalendar/pntemplates/compiled
openemr/documents/library/freeb is only writable for one stupid log file so easy to deal with. Although for some reason it has recently been noted OS-X needs this writable.
The only place that database user/password is kept (as of CVS version and next openemr release) is in openemr/library/sqlconf.php. I’ve set it up so gacl uses the sqlconf.php file to collect this info. So that will help simply things a little bit.
If we can get somebody to take on this thankless task here’s the order I would do it in:
1) Develop upgrade mechanism first in openemr/setup.php (this actually would not be too difficult to do), since a manual upgrade to this new re-organized directory structure of openemr would be horrendous. If had upgrade mechanism in setup.php, then user wouldn’t feel any pain.
2) Untangle the globals.php and config.php stuff and place almost all of it in the sql database for user and server settings.
3) Migrate the write directories to one place, and while doing this could consider changing most of it to blobs; would be nice to require no writable except for the smarty cache directories (ensure this is all done in one release cycle to simplify the upgrade process ins etup.php). Like step 2, this step will require lots of untangling of the source I suspect.
I suppose any time could migrate the sqlconf.php out, but I’m concerned this will complicate the installation. Since installation would no longer be a drop folder into webroot and start it process anymore.
This is a lot of work, and with our limited resources I’m thinking we should focus more on front end things to increase our user base like CCHIT stuff, internationalization, and interoperability. But just my opinion.
In terms of blobs. Are these directories for temporary files? or are they things that need to be saved?
I don’t know what interest there is but I put all of my scanned files as blobs into the database? I know previously this was last visited in about 2004. The vote was 2 to 2 (of 4 counted votes). (I just thought i would ask.)
I think with more people and organizations using OpenEMR in a SAAS type environment these are some basic security issues that we ought to fix now.
XOOP also uses a module called "Protector" that helps prevent
- DoS
- SQL Injection
- XSS
- System global variable pollution
I am not sure how difficult this would be but I wanted to bring it up. It might be worth investigating.
To further clarify,
Front end stuff would include migration of settings from globals.php to database and an upgrade mechanism in setup.php.
Back end stuff would include directory structure changes including migration of sqlconf.php .
I’m not a security expert but the DOS, SQL injection, global stuff seems much more of a priority than “hiding” sqlconf.php. Isn’t sql only set up to be logged in from localhost or specific ip address. So even if attacker gets your database username and passord that’s useless to them unless they get into your box anyways. And if they get into your box, then all is lost anyways regardless of the security mechanism.
One of the outcomes of the "UTF8" project is ensuring all sql calls go through sql.inc. Then should be able to filter for bad stuff at this point. Also will need to think about a global input form filter to deal with this stuff and ensure properly encoded characters coming through.
The problem is anybody who knows anything about the LAMP stack knows there is a database, a user name, a password and a host. They also know from reading and looking at OpenEMR that these credentials are in openemr/library/sqlconf.php. When an attack comes in it comes through the normal web interface. The attaacker tricks Apache into doing what it always does, read sqlconf.php, then execute a connection using mysqli which is being executed by Apache on localhost. The query is usually some what simple and states:
select * from patient_data;
The output is pumped into a text file. He/she then has x number of very carefully groomed, names, addresses, phone numbers, social security numbers etc. Which are quite valuable one the open market. This is a "rogue call" that does not use or need sql.inc. The use of sql.inc for all normal mysql connections is a good idea but it does not prevent this type of attack.
If the Apache reads the credentials as it starts up, which is normal operation, it doesn’t actually need to read the credentials again until it starts up the next time. It is much harder to hack Apache than it is to read the sqlconf.php file and let Apache do its normal job.
The first most important way to secure a web enabled LAMP stack is to move the database credentials out of the normal webserver path and have them referenced by variable only.
It is important to prevent DoS, SQL Injection, XSS, System global variable pollution but solving these problems is a much bigger issue than simply moving the sqlconf.php out of the web server path.
hey,
I’m not clear what you mean here. Yes, a user can get apache to read the sqlconf.php file. But how can they then “execute a connection using mysqli to run their own query via apache locally”? Am I missing something simple here? If you don’t want to post how to do this, then just email it to me. I’m still not yet convinced that this is a security threat.
-brady
Another point regarding sqlconf.php placement. Many LAMP stacks distribute the config file with the name/password of mysql database within the path, and the world has not ended yet. A specific project is Joomla which seems to be a very conscientious project and they include their configuration.php file with mysql database name/password right in the main web directory. So does php-gacl which is a "security" program.
Again, I would really need convincing because the strategy of removing the config file from the web directory is not simple. It would definitely complicate installation process, which is now simple and basically platform independent. Migrating the config file would go counter to this.
We could protect the credentials themselves by having sqlconf make the connection to the database and then immediately unset the $host, $port, etc. variables. Though I’m not sure how that would work with all of our borrowed projects.
This area is a topic of great interest to me. Our office has 20+ locations scattered across the southeastern corner of Connecticut. Our remote offices will be accessing OpenEMR via an HTTPS connection. The URL is not publicly available so there is some security-by-obscurity here. But it’s by no means, foolproof.
I’d like to see some examples of SQL-injection attacks against OpenEMR so that we can tighten up the system.
First, as Brady suggests, all SQL calls should go through sql.inc. In that library we can capture various attack methods in addition to sanitizing the input from forms. I believe some of this is already being done.
Second, the config file that defines the user, password, and database name is partially safe. Because it’s a PHP file, Apache will process it before sending it to the client. But my hacking days are far past and I no longer have the nefarious tools to dig deeply. I tried pulling down sqlconf.php with a browser and with wget. Both returned blank results. I’d be interested in hear of other methods to retrieve a PHP file from a web server without the server first processing it.
Third, Sam has a good point that all writeable folders should be contained in one place. I’m not sure a database table with BLOBs is a better idea. I do not have any experience with multi-gigabyte sized MySQL databases. We need to keep the database size in mind if we switch to BLOBs.
Fourth, global variables and user-preferences should be kept in the database and administered via a web-interface. As Brady said, this is a big transition and will likely take 40+ hours of work to accomplish. Perhaps this is v4.0 task to be added to the feature request list?
Migration of sqlconf.php would kill the current method of simple platform-independent installation. So, a reason would be needed to do this. If you can demonstrate to me (probably best to detail in email to me) how the following to steps are accomplished, then it would make sense. Feel free to use one of my demos at bradymd.com/appliance as guinea pig (sql-database:openemr sql-password:openemr):
1) Simply read and collect the sqlconf.php file over a browser to collect the password.
-----The php server will return nothing, so good luck there
2) Then with this information (find it above if fail step 1) grab the users information from the openemr database.