How should be test with phpunit for xss + sql injection? - php

How should be test with phpunit php web application for xss + sql injection?
I thinking to find program that output xss+ other attacks to test my application forms.
This program/service should be all time updated with new xss and other new attacks.
Does such service/program exist, if not how it done today?
Please give some examples if you can.
(I use php 5.3 + zend framework + mysql)
Edit:
I asking about testing!and not prevent techniques that I also know.
Thanks,
Yosef

I don't think you can easily do unit tests for this kind of thing. It would require that your application is written in a way conducive to mocking its component parts and definitely involve a great deal of continuous manual work (making sure there's tests and mocks for everything, testing for the myriad flavors of attacks, etc etc).
The only certain thing is that if you can get some automated tool of broad scope that's always up-to-date, whoever gave it to you didn't charge enough.
The forms of protecting against such attacks are pretty well known and easy to utilize:
Always escape variables in sql, or better yet use prepared statements
If you do not need to accept and preserve HTML input, always htmlspecialchars any variable that goes into HTML (note that there are many formats such as BBCode, MarkDown, Textile etc whose sole purpose is to allow a useful subset of formatting options without opening Pandora's box)
If you absolutely, most certainly need to accept, store and serve HTML data then there's HTMLPurifier that can help -- but do that only as a last resort
Therefore, I 'd say that it's much better value for your time to make sure that you follow these practices/use these tools.
Furthermore, if you funnel all access to these two subsystems (sql and HTML output) through a well-defined part of your application (database access methods that escape all input no matter what; HTML output functions that in the same manner escape input variables and inject them into a provided "HTML template" that you subsequently echo) then it becomes easy to unit test these subsystems. Decent PHP frameworks already do this.
At this point, the only real chance of introducing a vulnerability is by circumverting or misusing these subsystems. In my opinion you are better off spending effort on specifying and following good coding practices that writing unit tests to prevent vulnerabilities in your business logic (unit tests for you sanitization code are of course another thing entirely).
Finally, there are automated SQL injection tools and XSS-related tools that you can use to probe web applications. But unless someone hires you to do penetration testing, it's better to use these as you would use protection in sex: use it, but don't count on it.

I would not write unit tests for XSS or SQL injection detection.
What I would do is:
To prevent XSS, escape all user output with one of:
htmlspecialchars
filter extension (PHP 5.2+)
escape (Zend Framework)
http://htmlpurifier.org/ (External
library)
To prevent SQL Injection, use PDO and placeholders for everything.
ie)
"SELECT * FROM users WHERE uid = $_POST['id']";
becomes
"SELECT * FROM users WHERE uid = ?";
or
"SELECT * FROM users WHERE uid = :id";
Edit
You might also want to try some browser addons such as:
https://addons.mozilla.org/en-US/firefox/addon/hackbar/
https://addons.mozilla.org/en-US/firefox/addon/xss-me/
https://addons.mozilla.org/en-US/firefox/addon/sql-inject-me/
https://addons.mozilla.org/en-US/firefox/addon/access-me/

SQL injections are one of those classes of problems that can only really be found by auditing your code. You should be looking for places where you're dynamically building queries rather than using prepared statements - those are your SQL injection vectors. Change those to prepared statements, and you remove the risk of SQL injection.
Unit testing will help you with logic errors, but won't help you find security problems such as that. The only solutions are vigilance and code reviews/audits.
UPDATE: I almost forgot! You should check out PHP_CodeSniffer for doing automated auditing of your code. It should help you detect at least some instances of where people are doing potentially dangerous and insecure things in code, and you can extend it to detect more problems than the basic install will by default.

Use frameworks like sqlmap

Get the XSS Me add-on for firefox and run it against your pages to test.

Related

making php web application secure

to protect my project from attacks (example: SQL injection) im using the below for query
parameter pages(*.php?query=value) :
$id=strip_tags($id);
$id=mysql_real_escape_string($id);
if(is_numeric($id) && strlen($id)<=3) //id are numbers maximum of 3 digits
Apart from this im using client(JavaScript) & server side(php) validations, strip_tags() to filter data as required.
Passwords are encrypted using bcrypt()
All messages are encrypted using mcrypt_ecb()
Pages can only be accessed when isset($_SESSION["id"]) ie logged in.
error_reporting(0);to hide errors.
$_POST instead of $_REQUEST
mysql_real_escape_string(); for every input
actually my project will be used by college and im tensed about the security because backtrack makes it easy to penetrate, so im trying hard to make it safe. (i know it's a vast question, but any kind of help will be very useful) but as a student i want to know what else im missing to make it safe ?
Firstly:
Avoid PHP's MySQL functions like a plague
Use PHP's MySQLi functions instead at the very, very minimum or PDO instead. MySQLi and especially PDO functions, are better security-wise. But, of the two, PDOs are the best deal as they offer you higher abstraction with prepared statements which greatly increases your defense against SQL injection attacks:
Most SQL statements in PHP applications use variable input to
determine the results of the SQL statement. To pass user-supplied
input to an SQL statement safely, prepare a statement using parameter
markers (?) or named variables representing the variable input. When
you execute the prepared statement, you bind input values to the
parameter markers. The database engine ensures that each input value
is treated as a single parameter, preventing SQL injection attacks
against your application. Compared to statements issued through
PDO::exec(), prepared statements offer a performance advantage because
the database management system creates an access plan for each
prepared statement that it can reuse if the statement is reissued
subsequently.
Also, avoid using some of the older depreciated PHP functions.
Next, generally, if you're using PHP or any language that creates dynamic requests, that implies user input on some level, and most oftentimes, a subsequent interaction with the database. Rule 1 of web programming: never, ever under under any circumstances trust user input. At all. Everything entered must be cleaned, validated to avoid security problems. You can do this natively with PHP, but honestly it takes a lot of work and a lot of attention to detail - which of course, expands your development time.
If this is not an academic exercise or one dealing with self-training - try to use a framework if you can - it potentially can save you many headaches later down the road as good frameworks can take care of some of the overhead of dealing with escapes, validation and the like. What that means is that if you go commando and write your own code with no framework: most, if not all of the functionality you'll be implementing would be done for you and chances are - done better in a framework.
Plus, they make PHP development easier, and occasionally, fun. Of course, not all frameworks are created equal, and all frameworks have security issues, too. But, this is something you will have to keep in mind and keep yourself informed at all times, religiously.
If this is an academic exercise, or a self-learning one, read this:
Reasons to NOT use a PHP Framework?
A lot of the top StackOverflow PHP posts and Programmers.StackExchange posts can help you with your journey.
Here's a few to start with:
(This one's more of an overview of what most of these links discuss)
http://www.acunetix.com/websitesecurity/php-security-1/
PHP Session Security
Exploitable PHP functions
What's the best method for sanitizing user input with PHP?
https://stackoverflow.com/questions/325862/what-are-the-most-common-security-mistakes-programmers-make
What common web exploits should I know about?
Read up on security practices in your field. It's ever evolving.
If you're interested in frameworks, here are a few of the popular ones to pique your interest:
Yii
CakePHP
Zend
Symfony
Kohana (highly recommended)
But, either way - good luck!
I'd propose the review OWASP's website for web security related information (or even join OWASP).
This OWASP section provides PHP-related information.
Making a PHP application secure is a pretty complex process. There are lot of thing to think about when you write your application and SQL injection is not the only one threat.
I suggest to refer to the following useful articles:
25 PHP Security Best Practices For Sys Admins
How to secure your php application?
PHP Security Cheat Sheet

SQL Injection conundrum

As we know as usual sites use functions like mysqli_query() and mysql's PHP driver does NOT allow multiple queries in a single->query() call (But you can do as many in phpmyadmin SQL running section) so we cannot directly add DELETE/UPDATE/INSERT but abusing of possibilities to modify data under some circumstances. The 1st thing is that in that case I think 80% of potentially being at risk (maybe lost of data) is gone! & the 2nd one is, rely on this knowledge, why most of injecting tutorials are based and focused on multiple queries?
80% of potentially being at risk (maybe lost of data) is gone!
This assumption is wrong.
why most of injecting tutorials are based on multiple queries?
Because it's just a simple understandable example, a proof of concept. Just like one "If John have 2 apples and Mike five...". If real Mike doesn't feel like to spare his apples, it doesn't mean that arithmetics is all wrong.
SQL Injection Concudrum
There are NO conundrum in injections.
There is no point in musings on injections.
There is no percents of risk to be calculated but just a dichotomy: either you have your application compromised or not.
There is just one simple rule - always format your data properly, and you will forget of injections forever.
PHP for a long while has disallowed multiple queries running for a single query() statement. This is just part of preventing sql injection. You must also escape your inputs, use prepared statements, make your table names and columns hard to guess and such.
The simplest example of an sql injection attack does involve a query that's tricked into executing more than one query, but obviously php prevents a lot of such attacks by the limitation already mentioned. However, things like subqueries are still possible, so it's not fool proof. I don't think it's possible to make sql injections altogether impossible as people keep finding new ways to trick scripts.
The best you can do is know how such attacks are done and write your code according to currently accepted best practices to prevent such attacks. If you've done all this and still get hacked, then probably (but not certainly) it wasn't your sql that was the weakest link in your security. From what I understand, more often hackers succeed using social engineering techniques.
Making an un-hackable system is nigh impossible, so the best you can do is make it difficult to hack and thus, not be the 'low hanging fruit' or, in other words, don't be an easy target.

PHP user input data security

I am trying to figure out which functions are best to use in different cases when inputting data, as well as outputting data.
When I allow a user to input data into MySQL what is the best way to secure the data to prevent SQL injections and or any other type of injections or hacks someone could attempt?
When I output the data as regular html from the database what is the best way to do this so scripts and such cannot be run?
At the moment I basically only use
mysql_real_escape_string();
before inputting the data to the database, this seems to work fine, but I would like to know if this is all I need to do, or if some other method is better.
And at the moment I use
stripslashes(nl2br(htmlentities()))
(most of the time anyways) for outputting data. I find these work fine for what I usually use them for, however I have run into a problem with htmlentities, I want to be able to have some html tags output respectively, for example:
<ul></ul><li></li><bold></bold>
etc, but I can't.
any help would be great, thanks.
I agree with mikikg that you need to understand SQL injection and XSS vulnerabilities before you can try to secure applications against these types of problems.
However, I disagree with his assertions to use regular expressions to validate user input as a SQL injection preventer. Yes, do validate user input insofar as you can. But don't rely on this to prevent injections, because hackers break these kinds of filters quite often. Also, don't be too strict with your filters -- plenty of websites won't let me log in because there's an apostrophe in my name, and let me tell you, it's a pain in the a** when this happens.
There are two kinds of security problems you mention in your question. The first is a SQL injection. This vulnerability is a "solved problem." That is, if you use parameterized queries, and never pass user supplied data in as anything but a parameter, the database is going to do the "right thing" for you, no matter what happens. For many databases, if you use parameterized queries, there's no chance of injection because the data isn't actually sent embedded in the SQL -- the data is passed unescaped in a length prefixed or similar blob along the wire. This is considerably more performant than database escape functions, and can be safer. (Note: if you use stored procedures that generate dynamic SQL on the database, they might also have injection problems!)
The second problem you mention is the cross site scripting problem. If you want to allow the user to supply HTML without entity escaping it first, this problem is an open research question. Suffice to say that if you allow the user to pass some kinds of HTML, it's entirely likely that your system will suffer an XSS problem at some point to a determined attacker. Now, the state of the art for this problem is to "filter" the data on the server, using libraries like HTMLPurifier. Attackers can and do break these filters on a regular basis; but as of yet nobody has found a better way of protecting the application from these kinds of things. You may be better off only allowing a specific whitelist of HTML tags, and entity encoding anything else.
This is one of the most problematic task today :)
You need to know how SQL injection and other attackers methods works. There are very detailed explanation of each method in https://www.owasp.org/index.php/Main_Page and also whole security framework for PHP.
Using specific security libraries from some framework are also good choice like in CodeIgniter or Zend.
Next, use REGEXP as much as you can and stick pattern rules to specific input format.
Use prepared statements or active records class of your framework.
Always cast your input with (int)$_GET['myvar'] if you really need numeric values.
There are so many other rules and methods to secure your application, but one golden rule is "never trust user's input".
In your php configuration, magic_quotes_gpc should be off. So you won't need stripslashes.
For SQL, take a look at PDO's prepared statements.
And for your custom tags, as there are only three of them, you can do a preg_replace call after the call of htmlentities to convert those back before your insert them into the database.

Detecting potential SQL injection attacks, as well as other security issues

We all know it is nearly impossible to produce a large website without one or two flaws. As such I've written a small monitor that checks Apache access logs for potential SQL injection attacks (amongst other things), and it's working very well. I get an alert whenever someone attempts an attack, and I've had so few false positives that the default action is now to dump them into an iptables drop list. It's even helped me identify a few (non-security) bugs and remove them.
Here's my rules (case insensitive):
PathInjection = \./\.\./(bin|boot|data|dev|etc|home|lib|lib64|media|mnt|opt|proc|root|sbin|selinux|srv|sys|tmp|usr|var)/
Havij = 0x31303235343830303536
r3dm0v3 = 0x7233646D3076335F68766A5F696E6A656374696F6E
LogicBypass = '.*?(\bor|\band|\bxor|\|\||\&\&).*?--
UnionSelect = union[^a-z-_]+((all|distinct)[^a-z-_]+)?select[^a-z-_]
What I'd like to know is, how would you bypass these checks and still produce a valid injection? Can you think of a way to improve them without introducing false positives?
A few notes:
Case sensitivity is switched off.
I'm using MySQL.
The Havij and r3dm0v3 entries are used as a catch-all to prevent use of those automation tools.
I'm checking both raw and urldecoded strings.
I'm not looking for answers like "make more secure code instead".
I'm not looking for a different way to do this, just a way to improve my current logic.
EDIT:
Ok, so people seem to have misunderstood my intent. That's probably my fault, since I didn't fully explain. This is being requested as a tacked-on feature to a monitoring product, and is designed to offer minimal security monitoring. As part of our dialog with the client and our documentation, we're emphasising that this is not a catch-all, nor is it a replacement for proper security infrastructure (e.g. an IDS and firewall). It's simply an informational service to help provide basic threat detection and produce statistics about the number of potential attacks. I'm not trying to write an IDS or firewall. If it were up to me, I'd leave the feature out and tell them to go install a full suite of security infrastructure with its own monitoring systems, but this isn't my call. The current situation is that I've been testing the system on my own site. Right now, I'm just looking for a way to improve the regex strings to make this more effective. Hopefully this clears things up a little.
Edit again, in June 2021.
I posted this question back in 2011. Back when I wrote it I was a junior developer with an interest in security but lacking experience. Since then I've switched careers to security, worked as a pentester for 5 years, and a security researcher for another two. I'm also one of the top reputation users on Security StackExchange.
The answers given here are mostly correct - there's far more value in deploying something like ModSecurity with appropriate rules, since they've already done the work. A tacked on homebrew solution is not going to compare to a project with almost two decades of maturity.
The one major caveat, though, is that I was not making the decisions. Junior developers usually have neither the privilege nor latitude to veto product decisions made by management, especially those made at the request of a customer. One can certainly explain why an idea is bad, and provide supporting material, but that often doesn't translate into changed decisions. Being able to refuse a task from your employer without consequence is an unusual privilege - the concept is a complete fantasy in the context of most employment.
My advice for folks who respond to these types of question is this: explain why it is ill-advised, but be sympathetic and helpful to those who are in a difficult position. Actually answer the question, wherever possible, so that a best-effort solution can be implemented if all else fails. In the context of security features, it's also worth considering that if the alternative is no protection or detection at all - even if that alternative is artificially being imposed by external actors - a weak capability is almost always better than no capability at all.
I don't remember what I ended up implementing for this. It was so long ago. But if you're here now, looking for answers, I recommend using ModSecurity. They now have connectors for Apache, nginx, and IIS, so you can install it on any of those web servers. If changing the server configuration is problematic, you could instead run nginx as a reverse proxy with ModSecurity enabled, so that users hit the nginx server and it proxies the requests to your actual web server. This can also be done with Apache instead.
If you're looking for a more programmatic approach, ModSecurity has language bindings for C, C++, and Python. The ModSecurity API can also be consumed via any language that has interoperability support for C APIs (e.g. P/Invoke in .NET, or JNI in Java).
ModSecurity works on rules. One of the best free rule sets out there is OWASP Core Rule Set (CRS). The rules are significantly more powerful than simple regex patterns. This makes them very effective, but it also means that you probably shouldn't try to build your own ModSecurity-like internal feature that consumes the rules, because you'd need to put in a ton of work to support all the necessary features.
If you need to parse ModSecurity logs into a format that can be automated upon, take a look at ModSecurity Log Utilities.
Hopefull this info is of use to someone in future.
You're talking about writing an IDS. Unless your product is an IDS, just get and install one. Snort is well-known and has a free version.
I'm not looking for a different way to do this, just a way to improve my current logic.
Sometimes when it comes to security, the wrong approach simply is. How would I mess with your current logic? Unicode or hex encoding.
Here is a nice example of IT threat detection using deep-neural-network vector embedding and a similarity search engine.
Can you think of a way to improve them without introducing false positives?
I wouldn't think of improving this silly approach at all. I'd rather improve the site security itself.
We all know it is nearly impossible to produce a large website without one or two flaws.
I disagree with that. At least for SQL injections. Injections are quite silly thing and protection is not a big deal.
sql injection is top rated web Application attack these days. There are many insecure code over the net and also there are several ways to protect application from sql injection attacks. sql injection can occur when an application uses input to construct dynamic sql statements or when it uses stored procedures to connect to the database. Methods of sql injection exploitation are classified according to the DBMS type and exploitation conditions Vulnerable request can implement Insert, update, delete. It is possible to inject sql code into any part of sql request Blind sql injection Features of sql implementations used in various dbms. Successful sql injection attacks enable attackers to execute commands in an application's database and also take over the server.
my recommendation:
Basically, make sure your web server is up-to-date with latest security fixes/patches.
Make sure you have filter every user input and output as proper encoding like UTF-8.
Read the full testing guide: https://www.owasp.org/images/8/89/OWASP_Testing_Guide_V3.pdf
try tom imlement web application scanner , check this link http://trac.ush.it/ush/wiki/SecurityTools
I do ex. watchfile now IBM aapscan tools http://www-01.ibm.com/software/rational/offerings/websecurity/ to scan all my web application
check google more how to protect against sql injection
Microsft http://msdn.microsoft.com/en-us/library/ms998271.aspx
http://www.sans.org/ "sql injection"
WASC: http://projects.webappsec.org/SQL-Injection
OWASP: http://www.owasp.org/index.php/SQL_Injection
CodeProject http://www.codeproject.com/KB/database/SqlInjectionAttacks.aspx

What security issues should I look out for in PHP

I just starting out learning PHP, I've been developing web apps in ASP.Net for a long time. I was wondering if there are any PHP specific security mistakes that I should be looking out for.
So, my question is what are the top security tips that every PHP developer should know?
Please keep it to one tip per answer so people can vote up/down effectively.
(In no particular order)
Always check that register globals are OFF
Always check that magic quotes are OFF
Make sure you understand SQL injection attacks
Turn OFF error reporting in production
EDIT: For the "newbies" out there this is a basic why (and since I have time to explain this):
Register globals is an aberration. It's the ultimate security hole ever. For example, if register_globals is on, the url http://www.yourdomain.com/foo.php?isAdmin=1 will declare $isAdmin as a global variable with no code required. I don't know why this "feature" has made it's way to PHP, but the people behind this should have the following tattooed on their forehead: "I invented PHP Register Globals" so we can flee them like pest when we see them!
Magic quotes is another dumb idea that has made it's way to PHP. Basically, when ON PHP will escape quotes automatically (' become \' and " become \") to help with SQL injection attacks. The concept is not bad (help avoid injection attacks), but escaping all GET, POST and COOKIE values make your code so much complex (for example, have to unescape everytime when displaying and data). Plus if one day you switch this setting OFF without doing any change to your code, all your code and/or data is broken and (even more) vulnerable to injection attacks (yes even when ON you are vulnerable).
Your databse data is your most valuable thing on your site. You don't want people to mess with it, so protect yourself and read things about it and code with this in mind.
Again this can lead to security concerns. The error message can give hints to hackes on how your code works. Also these messages don't mean anything to your visitors, so why show them?
Avoid using register_globals.
Warning: This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
Cross Site Scripting (XSS) Wiki, Google
Cross Site Request Forgery (XSRF/CSRF) Wiki, Google (thanks Rook)
Session Fixation Wiki, Google
SQL Injection (SQLi) Wiki, Google
Turn off error messages in Production environments
Keep any "include" code in a directory that is not web-accessible (either deny access or keep it outside of the webroot)
Here's an article I wrote about storing passwords in a secure way, and if you don't feel like taking my word for it, check the links at the bottom.
Also linked in my article, but given its own separate link here, is a paper published by M.I.T. called The DOs and DON'Ts of Client Authentication on the Web [PDF]. While some of its info (recommendation to use MD5 hash, for one) is somewhat out of date simply because of what-we-know-now versus what-we-knew-then, the overall principles are very strong and should be considered.
One of Rooks' links reminded me of another important set of restrictions
Turn off Register Globals (This is the default now, so I hadn't mentioned it before)
When dealing with file uploads, be sure to use is_uploaded_file() to validate that a file was uploaded and move_uploaded_file() instead of copy() or rename().
Read this section of the PHP Manual if you need to know why (and you do).
Since I've now mentioned him twice, check out Rooks's Answer (https://stackoverflow.com/questions/2275771/what-are-the-most-important-safety-precautions-that-a-php-developer-needs-to-know#2275788) as it includes a link to a document which contains (Non-PHP-Specific) information on the most important security concerns (and this therefore probably the right answer).
here is a link of good PHP security programming practices.
http://phpsec.org/
Most of the security issues revolve around user input (naturally) and making sure they don't screw you over. Always make sure you validate your input.
http://htmlfixit.com/cgi-tutes/tutorial_PHP_Security_Issues.php
Always sanitize and validate data passed from the page
In conjunction with #1, always properly escape your output
Always turn display_errors off in production
If using a DB backend use a driver that supports/emulates prepared statements and use without prejudice :-)
don't use "Register Global Variables" and filter user input for xss and injections
Language Vs Programmer. You can write the most serious vulnerability and you won't get a warning or error message. Vulnerabilities can be as simple as adding or removing 2 characters in your code. There are hundreds of different types of vulnerabilities that affect PHP applications. Most people think of XSS and Sql Injection because they are the most popular.
Read the OWASP top 10.
If you're using a mysql database make sure you call mysql_real_escape_string when sending data to the database
There are tons of safety precautions. I can recommend a book Chris Shiflett: PHP and Web Application Security.
http://phpsecurity.org/
Have a look at the Suhosin Hardening Patch, and check out the security vulnerabilities that it addresses.
The PHPSec Guide gives a good overview.
Most of the security issues related to PHP come from using unparsed "outside" (GET/POST/COOKIE) variables. People put that kind of data directly into file paths or sql queries, resulting in file leakage or sql injections.
OWASP provides a lot of insight into security issues that are the biggest problems in applications today. It is nice to see that they have a PHP dedicated page available
http://www.owasp.org/index.php/PHP_Top_5
Always Close you SQL Connection.
Always Release SQL results.
Always Scrub all variables your putting into a database.
When deleteing or dropping from sql use limit 1 just in case.
When developing make sure you have a lock on things to keep the undesirable out. If its open and you know not to load the page right now because it could break something, doesn't mean other people do.
Never use Admin or Root as your server log in name.
Whenever possible, use prepared statements (tutorial. It's almost a must whenever dealing with user input (I say "almost" because there are a few use cases where they don't work), and even when not dealing with input, they keep you in the habit. Not to mention they can lead to better performance, and are a LOT easier, once you get into the swing of things, than piecemeal sanitizing.
Often introductory tutorials don't talk at all about checking data from users. Like all programming environments, never trust the data you get from users. Learn to use functions like is_numeric(), isset(), and mysql_real_escape_string() to protect your system.
There are also features that allow you to access remote files, and other creative things. I'd avoid those until you have a good understand of how and when they work (often they are disabled for security reasons).
Use POST method for data passing from one page to another.
Use trim while getting data like trim($_POST).
Also, use strip_tags for variables before you passing into the queries.
I am suggesting you use any framework link Codeigniter, Laravel, YII, Cake PHP because they maid framework with all securities
I suggest Codeigniter for small projects and Laravel for big projects.
Always use POST and not GET for important Data...

Categories