ars aranea. the web, the way we make it. | |||
66 Code injection on the WebPosted: Jun 30, 2006, under Security. Updated: Jan 14, 2007. Add a comment!This article is an overview of code injection on the Web, in general, and describes some types of code injection, in particular. The point of view is that of a PHP programmer, because PHP is an easy to learn and popular Web-programming language and is thus used by many beginners. 1. IntroductionBy code I mean data which can be interpreted in a special way by your Web application, altering its normal behaviour. Injection is when you, the developer of that application, unintentionally allow text provided by a visitor to reach a part of your application that will interpret it as more than just plain text (ie. as code), thus producing unforeseen consequences which can be exploited by an attacker. Any website receives data from its visitors, whether you, the developer of that website, realize it or not. Often you take that data and do something with it. Every time you do this you run the risk of putting that data in the position to mean more than just a simple string of characters. What if you output that data on your site’s pages and it contains HTML code? What if you use that data in an SQL query and it contains SQL code? There are many possible scenarios and I will try to describe some of them. 2. How to avoid code injectionNever trust anything that came from the visitor, be it HTTP headers or GET/POST/cookie data. Anything that comes from them can be faked or altered with evil intentions in mind. Always assume “they” are out to get you and you’ll have a head start. Security, on the Web and elsewhere, is a battle of wits between the designer of the defences and the people who want to break in. Most often than not it comes down to the attacker eventually finding something that the designer missed. Code injection is a classical way of illustrating this point.
3. Examples of code injection3.1. HTML and JavaScript injectionDo you output stuff directly in your webpages? Did some of that stuff come from the visitor in some manner? You may be vulnerable to HTML and JavaScript injection. That text you’re putting on your pages may well contain markup code, be it HTML or XHTML. In other words, code that has a special meaning to any browser that tries to display it. Consider this scenario: the attacker puts markup code in their comment to an article. Everybody else that views that comment will have their browser interpret the markup. Instantly, you have a recipe for disaster. It gets worse. Nowadays at least 90% of Web surfers have the JavaScript capability enabled in their browsers. If the attacker can inject markup freely, they can also inject JavaScript. What you have next is madness. Using markup and JS liberally, the attacker can truly own your website. Anybody who views the page where he injected his stuff will be taken for a ride. The implications are vast. He can pull more markup and more JavaScript from his evil lair and increase his capacities for attack. He can redirect visitors to anywhere on the Web. He can steal their cookies and take a peek at their recent browsing history. He can mangle your site’s pages to look like anything he wants, such as making visitors think they’re seeing the login form and have them input their username and password again. Incidentally, this kind of attack receives a lot of publicity. You may have heard of XSS (Cross Site Scripting). The name is misleading, and so’s the public’s perception of it. There’s not just scripting (JavaScript) at work, it’s the combination of markup and JavaScript. Or, to make it more clear, it all starts with unfiltered HTML. The solution is rather straightforward: don’t blindly print in your webpages the text you receive from untrusted remote parties. The safest way to deal with this is to apply filters to the text you receive as soon as you receive it or, even better, strip all markup completely. Some developers try to cheat and usually end up still having problems at some point. Trying to filter only JavaScript and leave markup alone, or to filter markup selectively, is an incredibly difficult task. Online email services, such as Yahoo, Hotmail or Gmail have time and time again been affected by this kind of injection. If you don’t have their resources and don’t plan to spend a lot of time and write a lot of code trying to do such filtering, the solution is simple. I’ll say it again: strip out all markup. If you need special formatting, abstract it using a different syntax, one where you control the markup that will be produced. After you strip (X)HTML, you can go on and have your application interpret a small subset of whatever formatting code you fancy. There are several available. UBB syntax is used on most forums, so you have a very good chance of your visitors being already familiar with it. You can also try one of the many flavors of wiki syntax. 3.2. SQL injectionAre you using GET, POST or cookie data directly in an SQL query? You’re vulnerable to SQL injection. You’re offering everybody full access to your database. SQL injection is one of the most well known forms of code injection, but at the same time it seems to be the one that trips most newbies. In particular, when we’re talking about PHP, it happens because people carelessly rely on the PHP interpretor having activated automatic SQL escaping for them. As you’ll see below, in some cases it’s useless even if it was activated. Basically, this kind of injection comes down to using unfiltered content that came from the wild in an SQL query. Without taking special precautions it’s quite trivial for someone with SQL knowledge to mangle your query into doing something else on the side. Consider the following query:
Now, imagine that john_doe came from an evil attacker. What’s to stop them from filling their username with this:
You can probably see where I’m going with this. Wanna see how your query looks after the attacker is done with it? Then take the second example and insert it in place of john_doe in the first:
It’s valid SQL that won’t throw an error and boom, no more USERS table. And this is only one of the stupidly simple examples. A truly evil attacker wouldn’t destroy your database, they’d explore and modify it to try and gain administrator priviledges for their own user, or collect as much information as they can about the other users. Many people assume that only strings are vulnerable to this kind of attack. They end up applying Therefore, in the following seemingly innocent query:
…”123″ gets replaced with this:
…and becomes this:
Again, say goodbye to your USERS table. One solution, in the case of numeric values, is to force-cast them to what they’re supposed to be, very early, before using them anywhere. Make sure integers are integers and floats are floats and nothing else. Another good practice, if the SQL engine allows it, is to write your query by enclosing all values, even those that are “supposed” to be numeric, in quotes. Some programmers employ automated escaping techniques, such as turning on “magic_quotes” or applying filters to all the incoming variables early in their scripts. As you’ve already seen, these measures may not catch all the cases, and leave your variables maimed, causing unpleasant output such as Therefore, the best solution (to any kind of SQL injection) is to use parameterized queries. Instead of composing SQL queries by concatenating strings, use prepared statements or stored procedures if your database engine provides them (and you’ll get a performance boost too). SQL injection is irrelevant in such contexts, because the SQL engine itself sanitizes the parameters according to what type they’re supposed to be. It will do a much better job at filtering bad values then anything you might come up with in your code. 3.3. PHP injectionDo you have
As a rule of thumb, try to avoid using
Exploiting Even more interesting, some code injection examples run back to the BBS era. Watch yourself. Say ‘no’ to In case you still need to ask what an attacker could do with this kind of power, the answer is “almost anything”. If they can write PHP code for you, they can do pretty much anything that PHP allows them to do: explore the filesystem and the server environment, read and write files, rewrite parts of your application, play with your database, set up their own little servers on the side for nefarious purposes. 3.4. HTTP injectionDo you perform HTTP redirects or otherwise make use of the Sometimes Web applications will need to issue HTTP headers themselves, for various purposes. The most common one is transparent redirection, such as sending the visitor to the proper page after they submitted a form. If by any chance foreign data finds its way into such a HTTP header, it will be output as-is and the visitor’s browser will have no choice but to interpret it, as long as it conforms to the HTTP rules of conduct. The main culprit in this case is the newline character. If not filtered out, the newline will basically split the HTTP header and allow the attacker to write several others, all of which will be sent to the visitor. There’s ample potential for misuse here. Here’s one often encountered scenario: the visitor wants to access a protected page without being authenticated, so they get redirected to a login form, with the address of the wanted page passed along in the form. After submit, the application acts upon that address. And if it doesn’t do some checking of that address, it may end up sending the visitor God knows where. One malicious use for this would be to send the user to a “delete” script. It gets very funny if that script doesn’t have built-in confirmation. And any script that can be controlled via GET parameteres is vulnerable. Another even more evil trick would be to redirect the visitor to the attacker’s personal site, where he would’ve set up a page looking just like the login form. The visitor will rarely check the address bar of his browser. Presented with a familiar sight and a familiar error message, he will input his username and password again, unaware that he just handed them to an evil third party. The attacker site can then simply redirect him back to the real login form and the user will be none the wiser. Think about it. Did you ever enter the wrong password three times in a row? I’m sure you have. How do you know one of those times you weren’t giving it to the bad guys? Avoiding HTTP injection depends on the circumstances. Avoiding the use of remote data in HTTP headers is obviously the best idea. If it cannot be avoided you can try several methods of prevention: filter out newlines; use POST whenever possible in your scripts instead of GET, because it’s harder to exploit (I said harder, not impossible); make sure those “back to the desired page” links are relative links, not absolute; don’t allow potentially destructive scripts to be accessed directly, without asking for confirmation. 3.5. Email injectionIf you use remote data in composing email you run the risk of having it malforming your message. SMTP injection is part of this problem, SMTP being the protocol used to send email. Just like with HTTP injection, overlooking newlines can lead to SMTP header mangling, which in turn can have unwanted consequences. It gets even worse if you consider that the headers in an email message control everything in that message. This kind of attack is especially effective when dealing with multipart email messages, such as the ones containing attachments or HTML. The evil headers can take over the message, redefine the markers that split the various parts of the email and then use the body to produce a malformed message. Even without SMTP being involved, there are still ways to abuse a script that sends email and doesn’t do enough checking of the data it uses. The solution is to filter everything you get from the remote party and make sure you use that data properly. 3.6. Other types of injectionWhenever you allow remote-provided data to pass freely into different environments than that of your application, you run the risk of it gaining special meaning. There are many types of injection out there. Most of the examples are not exactly obvious, not unless you develop an eye for it and know what to look for. Back in the early days of online forums it was possible for ill-mannered users to make a post containing a link to the logout script. They simply used the allowed BBCode or whatnot to link to This basically applies to any script that does something without asking for confirmation. When another user clicks the link, it will take action using his credentials. Nowadays, forums got wiser and use either a POST form and a logout button, which cannot be triggered by a BBCode link, or they don’t allow logout to occur unless the logout script also receives a special personalized key which the attacker had no way of knowing. Another form of injection is the one that stays at the base of most phishing attacks: crafting evil links and sending them to someone by email. If the text used to present the link is innocent, people will most likely click it. An attacker can use this for various purposes. For instance, he can guess that the target is at the time they read the mail logged in to a certain website and he can send them to addresses that perform administrative or destructive functions. Bottom line: always protect your scripts against automated activation. Assuming that they’ll always be used by the right humans is a big gotcha. Read this article by Elliotte Rusty Harold for more evil scenarios. 4. Final words of wisdomDo not rely on automated, generic catch-all mechanisms to protect your application from being used “the wrong way”. Do not rely on only blacklisting known attacks and similar half-measures. Do not expect other people to clean up after you by installing extra software or writing extra code. Take security seriously. Implement protection measures right and fully and stop any attempt of misuse dead in the tracks. Kill HTML outright and you won’t get JavaScript injection. Use procedural SQL and you won’t get SQL injection. Don’t use
| Important
Categories
Authoring
(1)Books (2)Cross platforms (2)DHTML (12)Graphical design (3)IT today (12)Morals&Politics (10)ODP (1)Random stuff (3)Romania (16)Security (7)SEO (2)Software (8)SQL (1)Standards (7)Technology (3)WordPress (4)[În română] (4)[This website] (2)Time-jump Syndication Need hosting?I've been a happy user of LunarPages since 2005. |
||
Copyright ©2005–2008 Zuavra | |||