
It's not the language
It's the people who use them.
In the same way that it's not the BMWs who drive like twats; it's the people behind the wheel.
Java applications have been found to have many fewer common vulnerabilities than those coded using web scripting language. Less than a quarter of Java apps sport sporting SQL injection vulnerabilities, compared to more than three quarters of those written in PHP. So says Veracode's new State of Software Security report (PDF …
Yes, using C would explain how Microsoft's OS and apps managed to avoid all those exploits over the years ... Oh, wait...
Historically, writing apps in low-level C has been by far the largest source of actual exploits, lately due to lack of language support for even basic protections. C is all very well for device drivers and kernels, but "programming without a net" s a bad methodology fir today's networked application environment.
No surprise.
As I have banged on in these pages many times:
1) We see the same old stupid flaws
2) We see a huge proliferation in poor languages, though good programmers can write good programs in them.
3) We see learning a language confused with learning programming (see points 1 & 2)/
Server vs mobile client.
Sqli is an attack on a server application that uses a database and doesn't properly sanitise inputs given by the user before passing it to the database.
Crypto problems is probably referring to https handling during communication, allowing a cipher downgrade or simply allowing the use of old ciphers. This could affect the server side as well, however most server apps hide behind some sort of front router that does ssl termination. Think nginx or apache. So, this type of flaw will be reported against those products rather than against the language used to implement t app behind them.
I was trying to learn PHP earlier in the year, and though I hadn't reached the part of the book I was using that covered accessing databases I had given it a quick check. I was concerned that it was a bit reliant on the idea of creating SQL strings in the PHP and firing them at the database without going through the filter of a stored procedure that checked for dangerous SQL. The book was basically too basic and not focussed enough on security quality.
It's important to make sure that coders learn good practice with regards to infosec right from the start, and that applies to all languages, from C to Javascript and beyond.
I was able to get hold of the book today and check out the section in a bit more detail on database activities, and to give the author credit he does cover SQL injection safety later in the chapter. It was just that his initial introduction to the subject wasn't injection safe, which was what I'd quickly looked at previously.
Very often what's in the introductory books is the wrong way to do it. The introductory books tend to be written to let students get something working as quickly as possible. Once you've got the basics of PHP down, you need to read some up to date more advanced books to find the correct way to do things.
Books and tutorials have awful examples like:
$name = from the outside;
executeSql("SELECT * FROM Table WHERE Name = '$name'");
In order not to confuse the tiny brain of the reader with details irrelevant to the subject.
These examples then get copied into production. But the thing is, whenever building SQL queries, SQL injection prevention is completely relevant! The "Security" section of the book isn't even reached because the reader is already at the point where their code "works".
This is what the minimal example should look like:
$name = from the outside;
$a = prepareSql("SELECT * FROM Table WHERE Name = @name");
$a->addParameter("@name", $name);
$a->execute();
Can you elaborate?
Quick answer: https://xkcd.com/327/
Slightly longer answer: in the first example, the programmer creates the query string as the concatenation (or interpolation) of the query (s)he intended to do, plus user data. There's nothing stopping the user from supplying data that turns the query from being "intended_statement" to "intended_statement; malicious_statement". This is called an SQL injection attack, by the way.
By using prepare, there are checks to ensure that user data can't morph the intended statement into some other arbitrary SQL command. Most easily done by escaping any metacharacters like ', ", ; and so on.
How Bobby Tables would work in real life... First, the code would have to select the student name and store it in a variable. Then, there would be some other query that's intended to, eg, show some details of that student. It could look like:
select * from Students where name = '$name'
Without input sanitisation, this becomes:
select * from Students where name = '$name' ; DROP TABLE Students; -- '
(-- introduces a comment in SQL, so the parser won't complain about the extra trailing apostrophe)
It's more secure but it's still set up to allow the web server to run any query it likes on the DB. If someone hacks the server and gets their own page on there, they've got the DB.
So books should give both your first and second examples as examples of what not to do, explaining why. Instead there should be a chapter on stored procedures for the most popular DBs, stressing that the stored procedure is responsible for sanitising inputs and preparing the output for presentation (e.g. putting asterisks over CC numbers), and the associated PHP code to call them.
It's more secure but it's still set up to allow the web server to run any query it likes on the DB.
Not necessarily, since most DBMSes have some concept of user permissions.
So books should give both your first and second examples as examples of what not to do, explaining why. Instead there should be a chapter on stored procedures for the most popular DBs, stressing that the stored procedure is responsible for sanitising inputs and preparing the output for presentation (e.g. putting asterisks over CC numbers), and the associated PHP code to call them.
"a chapter on stored procedures" would be woefully inadequate, even for a single DBMS. A single chapter attempting to cover all of "the most popular" would be insane.
Stored procedures certainly are a superior approach, as they offer much better separation of concerns, a much smaller attack surface, and minimal permissions. (In particular, if your DBMS has a separate "execute" permission, you can restrict the app's database account to just that.) But they're also much more complex, particularly for beginners. They're much harder to debug, especially when the DBMS is running on a remote server owned by a hosting provider. And they're application-specific, whereas it's quite easy to write a data access layer in PHP using prepared statements that's generic enough for simple projects.
For beginning students, prepared statements are a huge step forward from the typical concatenation-and-interpolation ad hoc queries that fill the tutorials and textbooks, with only a small increase in complexity.
Anyone with any sense writing with PHP is using one of a number of MVC frameworks which all provide structured database interfaces giving 'free' SQL injection protection. They also provide input filtering interfaces to HTTP get/post. Using either (or normally both) will ensure with minimal effort that 'Little Bobby Tables' won't ruin your day.
The difference between PHP and C#, Java etc is that in those languages such interfaces come as standard, whereas in PHP you need to make a conscious (although not difficult) effort to use them.
Can't say I'm shocked by the results though, when I started my current job I inherited a huge estate of classic ASP with basically no code reuse (essentially every page was a self-contained application) full of 'handmade SQL' with absolutely no user input filtering whatsoever. But 'stakeholders' never care about such things until it bites them in the ass, unfortunately.
Unfortunately, it's not uncommon for those filtered methods to have exploits found in them, and when they are it means every site built using those frameworks (since they largely assume the filtering will work) are sitting ducks until they're able to apply patches or upgrade, which depending how heavily modified the rest of the system is might take a while to achieve
This hasn't been an issue using the frameworks I have commonly used, perhaps I have been lucky.
And if one takes care to use both input filtering and a structured database interface, it would be necessary for BOTH sets of methods to have exploits in order to inject SQL, which seems somewhat unlikely. I strongly suspect that the vast majority of SQL injections found result from programmers not even making an effort to program defensively, rather than cases where the effort has been made but a library has subsequently been found to be vulnerable.
You're right that it's a risk though, and having such features built into the core language to some extent would be preferable.
"If you aren't passing parameters into a prepared statement then you are doing it wrong. It is the DB's job to handle the parameters."
That's the approach that PDO uses in PHP for exactly this reason. If you're using it then really the input filtering is largely going to be focused on filtering out things like cross site scripting attacks rather than sql injection. That said, a lot of sites don't use it, or use it wrong (technically it's possible to pass a full query through it rather than using prepared statements), in which case the sql injection prevention which is still part of the input filtering will kick in. It's not ideal, but it does add an extra layer of protections just in case it's necessary (the security, not the raw SQL which really isn't necessary)
in which case the sql injection prevention which is still part of the input filtering will kick in. It's not ideal, but it does add an extra layer of protections just in case it's necessary
I've yet to see any kind of input filtering with respect to the database that wasn't basically a farce. It's a sticking plaster on a sieve. It adds to the maintenance but not to the value.
Sack any developer who writes code that doesn't pass the data in as parameters.
One of the big Magento vulnerabilities from this year (I think April it came out?) was exactly this, a sql injection attack against a large scale framework using a vulnerability in the framework itself rather than in code that had been added. Basically the bigger the framework gets and the more used it is the more likely it will be targeted for this kind of compromise, and the more chance one will be found. This is why I'm not sure doing it at the language level would help, you'd have people looking to compromise the entire language rather than one framework, and any success would apply to *anything* built with it.
Honestly though it does reduce the risks a lot over hand written stuff, and if you couple it with a WAF to filter out attacks you're going to catch 99% of what's out there. There's even the OWASP NAXSI project to provide a plugin for NginX to provide WAF functionality, so it isn't like it's expensive to implement this stuff, just takes a bit of extra time and effort planning your server architecture which often gets skipped over (especially in the PHP world)
C/C++ is difficult to learn (relatively speaking) and develop with. Those who use it have generally spent a lot of time learning to use it correctly.
PHP & Javascript are easy to learn and develop with. People can "develop" with it just by copy-and-pasting from W3Scools and Stack, then modifying until it does what they want, without really understanding what they are doing.
So, is it a problem with the language or the the people using it?
As noted by another poster: it's often both.
As a language PHP contains more than a few design flaws which make code inherently unsafe: not being strongly typed is certainly one of the biggest problems. It's certainly convenient but you can end up paying a lot just for that.
So SQL injection attacks are the way to decide if a programming language is secure or not? I would have thought maybe vulnerabilities in the core might be a better or fairer way to judge.
How securely languages are used is another question - PHP is commonly used for CMS type systems which by usually take input and parse it into sql statements, Java apps may have less sql injection as they don't receive as much input which is parsed into sql statements.
After many years of working with most of the mainstream languages (I'm closer to retirement than graduation) before I encountered PHP I found it depressingly awful, but never spent the time explaining why. But then I found that others have:
http://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/
I'm surprised that everybody is simply taking this report at face value. It's an advertising paper by a company called "Veracode" who do super-special patented proprietary security analysis that doesn't actually look at the source code.
Let's look at a few examples of problems with this report. Why aren't Python or Perl listed despite those being widely used in web apps? It's because their software either doesn't work at all, or doesn't work very well with those languages. I imagine that Python is probably quite difficult to trace using Veracode's binary scanners.
How do they analyse programs without looking at the source code? They have a bunch of proprietary algorithms that they run over the binaries (byte code or machine code) that look for certain things. However, how well those work will vary greatly by language. For some languages they can't really tell very much. For others, they will spew out large numbers of false positives (rather like compiler warnings that may not actually indicate a problem). Customers love seeing lots of security alerts. It makes them feel like they're getting something for the money they are paying.
Comparing one language to another doesn't really tell you anything other than how many warnings Veracode will spit out. Surprise, surprise, some languages are easier to trace than others, and some languages will produce more false positives than others.
There are also sampling issues, which they readily admit to at the end of their report. The report was based on samples provided by customers, which means there is a degree of self selection going on. If for example a lot of their Java customers submitted everything they did as a routine part of their business process, while their PHP customers only used them after they had a series of serious security breaches, guess which one will show the most flaws (leaving aside any biases caused by the analysis methods themselves)? Now think about what languages the "money is no object, let's tick lots of certification boxes" development crowd use, and think about what languages the "one man developing small sites on a shoe string" development crowd use. The former will see lots of routine scans, while the latter will be motivated to buy Veracode's services only when they've had problems.
A further problem is that some types of programs take longer to scan than others (scans can take hours to a day or more), so some customers with large systems will abort the scan before it is done. Guess which types of languages tend to be be used in very large programs (or at least ones that have a lot of code)?
The two methods they use don't agree with each other. For example they say that DAST found SQL Injection problems in 6% of programs, while SAST found it in 29%. For insufficient input validation, it was 4% and 37% respectively. In other words, the number of results depend heavily on the algorithms used, and it is quite reasonable to assume that those will work "better" (produce more warnings) with some languages than with others.
I won't comment on Veracode in particular, as I haven't done business with them. However, if you read about user impressions of companies that work in the application security field, the term "snake oil" seems to come up rather a lot.
I'm not a fan of PHP, but quite frankly I think the report is rubbish. Even if you feel their cloud service is worth the money, there is absolutely no reason to believe that it is equally effective and accurate across all languages.
PHP has had support for SQL prepared statements for years (which while they don't make SQLi impossible, they do make it very very difficult).
Yet time and time again I see people on Stack overflow showing code examples where SQL is constructed from strings, even worse from $_GET/$_POST/$_REQUEST etc. And then I see that coding style all over the place in live codebases too. It's depressing.
One problem is I think most people who learn Java do so at university or as part of some formal learning process, whereas a lot of PHP programmers are self-taught and learn from tutorial sites. There are far too many PHP tutorials knocking around that date back to the PHP 4 days so you see the same bad practices being learned even though there are far better options now.
There's also the issue of Java being hard and PHP being easy. With Java you really have to understand it at least on a basic level to get it to do anything at all, whereas it's ridiculously easy for a complete beginner to write a PHP script that does something. While everyone bitches about Java's strictness, it does force programmers to be a bit more careful.
But really, there's no excuse for bobby tables any more.
This report is utter bullshit.
In any ranking of languages by web security vulns, C/C++ will naturally come out on top because essentially nobody uses it for webdev, and PHP's on the bottom because every idiot does. And most use PHP with MySQL so of course it's rife with SQLi. Blame that on SQL. And blame C/C++ for all the low-level vulns in PHP, MySQL, libPNG, OpenSSL, Linux kernel, bash, etc.
They're ALL crap languages. And so is Java, but thankfully web developers have learned to avoid it.