Yes and no.
Generally, there are three distinct security properties required of a cryptographic hash function:
- First preimage resistance: Given a random hash value, it should not be feasible to find an input hashing to it.
- Second preimage resistance: Given an input string, it should not be feasible to find another input hashing to the same value.
- Collision resistance: It should not be feasible to find any two inputs hashing to the same value.
Generally, each of the properties listed above implies the preceding ones in the list: if a hash function is collision resistant, then it's also preimage resistant, and if it's second preimage resistant, then it's also first preimage resistance. (There are some weird edge cases, e.g. involving restricted input domains, where this might not quite hold, but for normal cryptographic hashes it does.)
For example, practical collision attacks are known against the MD5 hash function, capable of finding collisions within a few seconds on a modern CPU. However, while there are known theoretical attacks that can find MD5 preimages about 20 to 30 times faster than by brute force, none of those attacks are anywhere near fast enough to carry out in practice. For the SHA-256 hash function, no practical attacks against any of these properties are currently known.
Another difference between hashes that affects their security is their output length. For a hash with n-bit output, no matter how strong, a simple brute force attack can find a first or second preimage using on average 2n hash evaluations, and, due to the birthday paradox, a collision after only about 2n / 2 evaluations. For example, even if MD5 wasn't broken, its 128-bit output length means that finding a collision by brute force would be possible using only about 264 hash operations. That's a lot of work, but it's just about technically feasible for an attacker using a large distributed computing network and/or lots of expensive custom hardware. SHA-256 generates, as the name indicates, 256-bit hashes, meaning that running the same attack on it would require over 2128 hash operations, way beyond anything even conceivable using known physics.
Anyway, let's see how nesting a weak and a strong hash function (say, MD5 and SHA-256) would affect the different security properties:
First preimage resistance
If we find a first preimage P for a given hash value H, such that SHA256(MD5(P)) = H, then we've also found a preimage PSHA = MD5(P) such that SHA256(PSHA) = H. Conversely, if we can efficiently find such preimages for the nested hash, we can also find a preimage PMD5 such that MD5(PMD5) = H' for any MD5 hash H' just by solving SHA256(H') = SHA256(MD5(PMD5).
Thus, a nested hash is at least as strong against first preimage attacks as the strongest of the hashes.
This may seem like good news for applications like password hashing, whose security depends on first preimage resistance (and generally, it is). However, there's a technical catch related to the output lengths of the hashes that we should be aware of.
To see what the problem is, consider what would happen if we replaced MD5 in the nested hash with a trivial hash that produced only a one-bit output. Now our nested hash, despite nominally producing 256 bits of output, would only have two possible output values. If the hash value we were attacking was one of those two values (as it would have to be, if we knew that some preimage existed), then finding a first preimage would be trivial. Conversely, if we tried to find a preimage for any other 256-bit hash value, it would be impossible (which is why this result doesn't contradict the earlier proof above).
In the case of SHA256(MD5(·)), we similarly have only 2128 possible outputs, even though they're nominally 256 bits long. Thus, a generic brute-force preimage attack on the nested hash takes only 2128 operations on average, not 2256 as it would for a "real" 256-bit hash. Effectively, our nested hash looks like a 256-bit hash, but only has 128 bits of strength against brute force attacks.
Still, as long as attacks requiring 2128 operations are infeasible (and they are, for any foreseeable length of time), we don't need to worry about this, and we can safely use SHA256(MD5(·)) for password hashing (with appropriate salting and key stretching, of course).
Second preimage resistance
As Gordon Davisson shows in his answer, SHA256(MD5(·)) is only as strong as MD5 against second preimage attacks: if, for a given message M, we can find another message M' ≠ M such that MD5(M') = MD5(M), then it's also true that SHA256(MD5(M')) = SHA256(MD5(M)).
Thus, nested hashing is no stronger against second preimage attacks than the innermost hash. This is bad news for applications like digital signatures, where a second preimage attack on the hash generally translates to a forgery attack on the signature.
We could do better by using MD5(SHA256(·)) instead, since that would put the stronger hash on the inside. However, the resulting hash would still be no stronger against second preimage attacks than just SHA-256 alone. In fact, due to the shorter output length of MD5, it would be weaker than SHA-256 alone against generic brute force attacks.
The situation with collision attacks is pretty much the same as for second preimage attacks: if we can find a collision for MD5 (and we can!), then we also have a collision for SHA256(MD5(·)). Thus, SHA256(MD5(·)) is utterly broken against collision attacks.
Again, this is bad news for things like digital signatures, where a hash collision could allow a malicious user to pull off a "bait and switch" attack on a third party, where they persuade the third party to sign an innocent-looking message (e.g. an SSL certificate) and then replace it with a different message having the same hash.
Reversing the nesting order again makes things somewhat better: just being able to generate MD5 collisions doesn't help us much against MD5(SHA256(·)), since, even if the colliding MD5 inputs were both valid SHA-256 outputs, we'd still have to find preimages for them. But even so, this nested hash still wouldn't be any stronger against collision attacks than SHA-256 alone.
Against (non-brute-force) first preimage attacks, a nested hash is at least as strong as the strongest of its component hashes. Against other kinds of attacks, however, a nested hash is no stronger than the innermost hash.
Thus, for most purposes, simply nesting hash functions is not a good idea. A much better alternative is to use the method suggested by tylerl, where the inner hash output is concatenated with the original input before applying the outer hash, e.g. H = SHA256(M + MD5(M)), where + denotes concatenation. This construction can be easily shown to be at least as strong as the outer hash against any kind of attacks.
However, there's one situation where using H = SHA256(MD5(M)) can be legitimately useful, and that's upgrading an old password database using MD5 hashes to use a more secure hashing mechanism. Provided that the old hashes are long enough to resist brute force preimage attacks, and that the old hashing method doesn't do anything stupid that could create a non-negligible probability of collision between normal inputs (like throwing away all but the first 8 bytes of the input), simply re-hashing the existing password hashes using a stronger hash function can provide an immediate security improvement without requiring user interaction (e.g. logging in).
Of course, if you're upgrading an old password database to meet modern standards, you really should be using something like PBKDF2-HMAC-SHA256 instead of plain SHA-256 as the outer hash, with a proper salt and a sufficiently large iteration count to make brute-force attacks difficult. If your old password hashing scheme also used a salt, your new password hashes might end up looking something like this:
where type is a scheme identifier (so you can easily change the hashing scheme again later), new-salt and old-salt are the salts for the new and old hashes, count is the iteration count for PBKDF2 (again included so that you easily change it later) and hash = PBKDF2-HMAC-SHA256(old-hash(password, old-salt), new-salt, count).
Of course, this kind of nested password hashing scheme is most useful as just a transitional solution. As your users log in or change their password, you can gradually replace these transitional password hashes with a simpler hashing scheme (with a different type identifier) that doesn't use the old hashing scheme at all. That way, once all your user accounts are migrated to use the new, simpler scheme (which could take a while), you can later retire the old password hashing code entirely.