I'm currently building a website, using PHP, and looking into securing the website fully. Currently, and in the future, I don't plan on using SQL, or even user-submitted input anywhere on the website - the PHP pages are basically simply in place for ease in piecing together several different HTML fragments to create a full page, using requires.
What type of vulnerabilities, if any, should I be aware of to protect against?
There are no vulnerabilities in the situation you've outlined.
If you are using any query string variables to load pages, they may need to be secured. For example: article.php?page=php-page-security.
Otherwise just make sure that your server software is updated regularly to the latest versions, and access to the web server is properly secured. It sounds like your code is pretty basic and you aren't doing any processing in PHP, so you should be fine.
This is a huge topic that can't be answered in a single post. Some tips:
Secure physical access to your web server (your hosting provider should handle this)
Minimize remote access to the server. Setup a firewall, use proper passwords, regularly run updates
Secure your code (PHP and javascript). Make sure to "clean" any qstrings you might process and never use eval. Consider using a framework to simplify this step.
Keep server logs and review them regularly for mischief.
This is just a jumping point. A google search for "web application security" will turn up troves of information. Good luck!
Possible exploits are in the overall server security.
As you use PHP in that simple manner, there's a risk that you do not know it well enough and might overlook some hole: like user input option, or file access rights which would allow a bad guy to upload his php to the server.
PHP offers too much for a simple task of including files. More capabilities == more risk.
I'd use server-side includes for the sake of assembling several files into one web page, and just disable php — faster, more secure.
You should be sure that your software (e.g. webserver, operating system, PHP) is up-to-date, with the latest security patches and updates. You can also hide PHP (read the official guide or [search Google])(http://www.google.com/search?q=hiding+php)
By combining all the advice you get from the answers here, your application will be something more that perfectly safe.
As #Toast said, you had better block incoming traffic and only allow port 80 by using a firewall (Netfilter/iptables on Linux), except if you want to enable additional services, such as FTP.
And in case you want the data travelling between the server and the client to be safe, then HTTPS is the best solution.
If you're not basing the "piecing together" on any kind of user-provided data, and not including any user-provided data into the page, then you're about as vulnerable as a plain static .html file.
That means you're not doing:
include($_GET['pageName']); // hello total server compromise
or
echo "Hello, ", $_GET['username']; // hello cross-site-scripting!
and the like.
Related
This question stems from a job interview I had. The interviewer asked me about a website I had built.
I was fresh out of school and was still doing a lot of things wrong because I didn't know any better and
had no one to ask. When I laid out the website for my interviewer on the whiteboard he was surprised that
I didn't use a web service to access my database. He suggested that this was not secure
but didn't go into detail. They thought had never occurred
to me to do this as a security measure and I thought I was wrong for not doing it. My code was all one one page.
No MVC, my php connections and all my php/mysql select, inserts, etc were all written in php on the same file
as my html / javascript and everything else (wrong for various reasons but not the topic at the moment).
My page was protected by https and I thought that was enough. Also looking back on it he may not
have known my database was on the localhost. The confusion in the question steams from my lack of knowledge
at the time and now.
So the real question (I guess) should be, did I need to have a webservice like Soap acting
as an in between my database to make my site secure(even though it was a localhost)? My assumption being that
the soap server would do all of the mysql statements and return the values I was interested in. Or alternatively the SAOP Sever would
get the Mysql database to execute mysq functions and the values (which would I think add real security value).
I thought that because I was using server side php and https that I would be secure
(other than things like a mysql injection but I had other things to account for that like mysql_real_escape_string()
and some other stuff).
In Short
My question is would using soap to separate things between the main page file and the file that
actually did the php mysql select statements on a localhost add any security value vs https. Couldn't I just get the php to
connect and then use the Mysql server to execute some mysql functions with the pages protected with https ? Wouldn’t that be secure ?
Aside from me not using an MVC model can you offer some sage advice on the https vs SOAP?
I am trying to do some self-study in php. I am working in another language now mainly writing scripts.
I have a really passion for php and I want to learn but don't know where to reliably turn.
Thanks
You are mixing the concepts of protecting access to your database, and protecting access to your web service.
You must follow best-practices to protect your database, no matter what web service architecture you use (prevent SQL injection, certainly don't expose credentials, physically separate the DB from the web service server via a firewall, etc.).
If your web service is not meant to be available to the general public, you must separately control access to the web service. Both SOAP and REST provide solid mechanisms to do just that.
SOAP itself does not protect access to files on the server. It provides a mechanism to protect access to the web service.
UPDATE
It is a silly notion to require a web service between a website and a database for "security" purposes. A web service should be thought of as an alternative interface for accessing functionality, not as a security layer.
In fact, unless you hide your web service from the public, hackers will just attack the web service rather than (or in addition to) the website. If you do hide it from public view, you have invested quite a bit of Engineering effort for zero benefit.
From an architectural perspective it is wise to separate data access from the user interface (whether or not the layers run on the same or different machines). In the ASP.Net world, the Repository and Unit of Work patterns are quite common. I'm not sure which patterns are commonly used in PHP. Creating a separate web service for only for DB isolation is certainly not such a pattern.
Let's say I have a website where
PHP 5.3 is installed
every output is htmlspecialchars()ed.
PDO and prepared statements are the only way to interact with the database
error_reporting() is off
every request is passed to index.php (front controller) and no direct file access is allowed except for index.php via .htaccess
every input is properly escaped (why should I? i use Prepared statements, how could an user input mess up with my code?)
there's no use of evil()
Is it considered safe? What other things could be fixed to improve security? How could you attack it? Hack it? PHP/Server side is possible to improve security?
Check this page : PHP Security Guide. Most attacks are documented. If after implementing these security checks, you're still hacked, there are high chances that the problem doesn't come from your PHP application.
By the way, as #Jacco stated, there is some wrong stuff on the article I linked to.
Use prepared statements instead of mysql_real_escape_string(), but you already did that.
About salting, follow this answer instead : https://stackoverflow.com/a/401684/851498
Finally, checking ['type'] (for file upload) is unsafe since a malicious user can change this value. Instead, see the suggested solution of this link : http://www.acunetix.com/websitesecurity/upload-forms-threat.htm
I remember when I started web developing, I read allot about sanitizing data, creating numerous mysql users with a subset of permissions for specific queries, etc.
It gets you in the mindset of treating security with code, not with the operating system.
What use is all of this if you connect to your console with telnet, or use ftp with authentication?
I guess I should cut to the point. I think modern open source technologies such as php mysql etc have build up allot of security features, which gave me a false sense of security.
The damage you can do through these technologies is negligible compared to hacking into console with a brute force attack. If I were you I would worry much more about geting a proper firewal and only allowing port 80 or the bare minimum of ports you need. If you enable console access I would only allow your desktop IP... etc.
and make sure if you ever send a password, that it is encrypted through ssl
There is no absolute security guarantee, you can add the following to the answers above:
If you allow file uploads, make sure you do mime checking;
Make sure the public cannot upload an unlimited amount of files to
overload and eventually kill your server;
If you own the server make sure there are no other weak gates to your site, you can spend millions making your site bulletproof to any type of attack, but if someone gains access to it through another website hosted on the same server, you're out of luck;
Use a vulnerability scanner like acunetix, skipfish;
If you own the server make sure you stay up to date with the versions of the software running on your server (PHP/Apache/MySQL). Subscribe to get updates from the vendors;
If the budget allows it, you could offer a bounty to someone to find a security hole in a DEV release of your code;
Use a product like the following: https://www.cloudflare.com/features-security
security is a major concern for any product and it can not be achieved by some finger count policies but they are important so everywhere in the code think the negative possibilities and work against them to prevent them.
other thing you have to do
store sensitive data in encrypted formate in db
clean XSS every user input data
It is important to note that "safe" is a context-based term. It highly depends on your needs, and there are companies out there (I'm looking at you Google) who will not even consider installing PHP at all.
If you are working at a big company, I would recommend hiring the services of professionals.I heard from a friend that this company does sec checkups for all the big companies, which seems likely since they are the people that distribute Kali Linux.
https://www.offensive-security.com/offensive-security-solutions/penetration-testing-services/
There can be multiple other issues as well, such as session problems, sensitive information enumeration, authorization and authentication issues, and lot more. Issues like business logic bypass can not be resolved by traditional secure coding guidelines. However, looking at PHP Security Cheat Sheet and OWASP PHP Security Project would be a great help to understand the big picture of security issues.
You can learn more about exploiting PHP security issues and related attack techniques by solving the PHP security challenges by RIPSTech (https://www.ripstech.com/php-security-calendar-2017/) or by reading their writeups of real-world vulnerabilities found in popular PHP apps (https://www.ripstech.com/security-vulnerability-database/)
While installing an application onto a client's server, I would like to make sure that the client (or a future developer for them, etc) does not copy my application and place it on other domains/servers/local servers.
How can I verify that my application is running on the server I installed it on? I do not want any substantial lag in the script every time it runs, so I assume a 'handshake' method is not appropriate.
I was thinking the script could request a PHP page on my own server every time it runs. This could send my server their server info and domain name, which my script can check against a database of accepted clients. If the request is invalid, my server handles the work of emailing me the details so I can follow it up. This should not slow down the client's script as it isn't expecting a response, and will still operate on their 'invalid' server until I can investigate this and follow it up with them personally.
If this is the best method (or if there is better), what PHP call should I be making to request my server's script? file_get_contents, curl and similar seem to always retrieve the response, which I don't need.
UPDATE
Thank you all for your responses. I completely understand that PHP is open source and should be freely available to edit. I should have stated more clearly initially, but my intentions were for this verification method to assist me in finding anyone breaching my license agreement. The application is covered under a license, but I would also like to include this check so that I can monitor an initial misuse of my application.
Hence, somebody may still breach my license and it would most likely go unnoticed, but if I implement this script I have the advantage of any 'lazy robbers' who don't break apart my application and remove the verifier before ripping it.
Does this justify the use of such a script? If so, is cURL my best option?
Any checking code for verification is easily replaced with a return true;. Look at the faq at https://stackoverflow.com/tags/php/info :
Q. Can I protect my PHP code from theft? If so, how?
A. There is no effective technical solution to protect, encode or encrypt PHP source code. There are many products that offer some levels of protection, but all can be broken with time and effort. Your best option is not a technical solution, but a legal solution in the form of a license agreement.
You get a legal agreement and sue everyone.
SaaS is your friend. Host the application on your own secure servers, and charge a license fee for your customers to access it.
imo its worth checking out some joomla extensions that do this. There a few different implementations, some check the domain and validate it before executing, most are encrypted, along with a domain validation. I remember sakic's url sef extension used to do this. There are quite a few more commercial extensions that use the same thing. Apart from that I cant think of another way.Probably another good idea is to have a good license in place and a good lawyer....
Short answer: This can't be done.
Long answer: Whatever protection you put in your code, it can be removed with little difficulty by anyone with some experience in PHP. Even if the code is encoded with something like ionCube or Zend Guard, this too can be decoded with relative ease.
Your only option is to protect your intellectual property by actively pursuing copyright infringers. Even this is not foolproof, as our folks from RIAA and MPAA know very well. In this day and age, I'd say this is not a solvable problem.
You could integrate phone-home behavior into your software but you should probably consult a lawyer to discuss privacy issues about that and to work out privacy guidelines and terms of use for your clients' usage license.
One thing to be careful about is the data you send (and the way you send it, i.e. securely encrypted or not) to identify the client who is illegally using your product because it could potentially be used to compromise your client's infrastructure or for spying on your client.
Regarding your phone-home function, be warned that the client could just locate and remove it, so using a PHP obfuscator or compiler might provide some additional protection against this (though any sufficiently determined PHP developer could probably disable this). Note that your protection will only act as a deterrent aimed to make the cost of circumvention
approach or exceed the cost for legal use.
EDIT:
As poke wrote in the question comment, you could move parts of your code outside the software installed at your client's site to your servers but this may backfire when your servers are unreachable for some reason (e.g. for maintenance).
In the end, I think that customer satisfaction should be valued higher than protecting your software from the customer, i.e. try to avoid protections that are likely to make your customers angry.
You could encode it and hard code a license file that would allow it to only work on the domain it was intended for (e.g. use ioncube or zend to encode a file that checks if the HTTP HOST is the intended domain without doing a handshake). You could then make that file required in all other files (if everything was encoded).
I am creating a website that is using a perl script, PHP, a MySQL database, and HTML. My main concern is making sure there is not anyway someone can gain access to anything that give them access to my information. I mean is there anyway for someone to get my perl script and see my database information. I know about sql injection but I have no forms for information to be entered into. Is there anything I should keep in mind with this stuff.
is there anyway for someone to get my perl script and see my database information
This will only happen when the webserver doesn't parse/process the script and returns it as plaintext. Usually this parsing/processing only happens on specific file extensions like .pl for perl files and .php for PHP files. If you (or the hacker) renames it to .txt, the client will be able to obtain the entire script as plaintext. Nevertheless, if a hacker is able to rename it, it has access to the whole script anyway. This would then be done by a security hole in FTP or CMS.
Further, I've seen scripts which reads files (usually images or other static files) from (outside) the webapp context based on the path as a parameter. E.g. download.php?filename.ext If such a script doesn't do any sanity checks on the file path, a smart hacker may be able to obtain scripts as plaintext by download.php?%2Fserver%2Fhtdocs%2Fscript.php.
The breadth of this question is kind of overwhelming, but it's a great question and definitely important.
Much of the issues you are going to have with your server can be tied to server access itself, make sure you don't use any software you don't need. If you don't need a name server, turn off bind; same goes for ftp, even sendmail if you can. Use strong passwords and alternate ports if possible.
For PHP, see http://us3.php.net/manual/en/security.php and http://php-ids.org/; definitely use mysql_real_escape_string() and htmlentities().
For HTML/PHP/JS, see http://en.wikipedia.org/wiki/Cross-site_scripting
There is a lot to think about. I'd recommend trying to find a mentor to help you figure out what is important. I'm mentoring a guy right now and it helps him a lot even if I'm not perfect. SO can help, but a person you trust who can look at how you do things can make recommendations you just won't get here unless you post your entire code base.
Use placeholders for SQL, even PHP supports it.
Escape your output. Your templating system may help here.
Use cgi-bin directory. It really helps to protect accidental leaks. It is easy to make URLs without cgi-bin.
In Perl use taint mode, in PHP use hardened PHP.
Web application security is a big topic. However, you know about one of the biggest vulnerabilities out there, SQL Injection, so that's a good start.
A couple other big ones are Cross Site Scripting (XSS) and Cross Site Request Forgery (CSRF - "See-Surf")
XSS - http://en.wikipedia.org/wiki/Cross-site_scripting
CSRF - http://en.wikipedia.org/wiki/Csrf
As usual Wikipedia provides a good intro.
You may also want to look in to verifying request authenticity by using an HMAC
http://en.wikipedia.org/wiki/HMAC
Never ever trust any user input in any form.. Ever :)
The hard part is figuring out all the ways a user can supply input to your site..
I asked a recent question regarding the use of readfile() for remotely executing PHP, but maybe I'd be better off setting out the problem to see if I'm thinking the wrong way about things, so here goes:
I have a PHP website that requires users to login, includes lots of forms, database connections and makes use of $_SESSION variables to keep track of various things
I have a potential client who would like to use the functionality of my website, but on their own server, controlled by them. They would probably want to restyle the website using content and CSS files local to their server, but that's a problem for later
I don't want to show them my PHP code, since that's the value of what I'd be providing.
I had thought to do this with calls to include() from the client's server to mine, which at least keeps variable scope intact, but many sites (and the PHP docs) seem to recommend readfile(), file_get_contents() or similar. Ideally I'd like to have a simple wrapper file on the client's server for each "real" one on my server.
Any suggestions as to how I might accomplish what I need?
Thanks,
ColmF
As suggested, comment posted as an answer & modified a touch
PHP is an interpretive language and as such 'reads' the files and parses them. Yes it can store cached byte code in certain cases but it's not like the higher level languages that compile and work in bytecode. Which means that the php 'compiler' requires your actual source code to work. Check out zend.com/en/products/guard which might do what you want though I believe it means your client has to use the Zend Server.
Failing that sign a contract with the company that includes clauses of not reusing your code / etc etc. That's your best protection in this case. You should also be careful though, if you're using anything under an 'open source' license your entire app may be considered open source and thus this is all moot.
This is not a non-standard practice for many companies. I have produced software I'm particularly proud of and a company wants to use it. As they believe in their own information security for either 'personal' reasons or because they have to comply to a standard such as PCI there are times my application must run in their environments. I have offered my products as 'web services' where they query my servers with data and recieve responses. In that case my source is completely protected as this is no different than any other closed API. In every case I have licensed the copy to the client with provisions that they are not allowed to modify nor distribute it. This is a legal binding contract and completely expected from the clients side of things. Of course there were provisions that I would provide support etc etc but that's neither here nor there.
Short answers:
Legal agreement, likely your best bet from everyone's point of view
Zend guard like product, never used it so I can't vouch for it
Private API but this won't really work for you as the client needs to host it
Good luck!
If they want it wholly contained on their server then your best bet is a legal solution not a technical one.
You license the software to them and you make sure the contract states the intellectual property belongs to you and it cannot be copied/distributed etc without prior permission (obviously you'll need some better legalese than that, but you get the idea).
Rather than remote execution, I suggest you use a PHP source protection system, such as Zend Guard, ionCube or sourceguardian.
http://www.zend.com/en/products/guard/
http://www.ioncube.com/
http://www.sourceguardian.com/
Basically, you're looking for a way to proxy your application out to a remote server (i.e.: your clients). To use something like readfile() on the client's site is fine, but you're still going to need multiple scripts on their end. Basically, readfile scrapes what's available at a particular file path or URL and pipes it to the end user. So if I were to do readfile('google.com'), it would output the source code for Google's homepage.
Assuming you don't just want to have a dummy form on your clients' sites, you're going to need to have some code hanging out on their end. The code is going to have to intercept the form submissions (so you'll need a URL parameter on the page you're scraping with readfile to tell your code that the form submission URL is your client's site and not your own). This page (the form submission handler page) will need to make calls back to your own site. Think something like this:
readfile("https://your.site/whatever?{$_SERVER['QUERY_STRING']}");
Your site is then going to process the response and then pass everything back to your clients' sites.
Hopefully I've gotten you on the right path. Let me know if I was unclear; I realize this is a lot of info.
I think you're going to have a hard time with this unless you want some kind of funny wrapper that does curl type requests to your server. Especially when it comes to handling things like sessions and cookies.
Are you sure a PHP obfuscator wouldn't be sufficient for what you are doing?
Instead of hosting it yourself, why not do what most php applications do and simply distribute the program to your client with an auto-update feature? Hosting it yourself is complicated, from management of websites to who is paying for the hosting.
If you don't want it to be distributed, then find a pre-written license that allows you to do this. If you can't find one then it's time to talk to a lawyer.
You can't stop them from seeing your code. You can make it very hard for them to understand your code, which is a good second best. See our SD PHP Obfuscator for a tool that will scramble the identifiers and the whitespacing in the code, making it much more difficult to understand.