DNS pinning does not protect against sophisticated DNS rebinding attacks.
Consider a scenario where an attacker sets up a firewall in front of their web server. You request their website, attacker.com, which results in a DNS query returning their IP address. The DNS result has a TTL (time to live) of 1 second. Normally, this means the browser should make another DNS request after 1 second has passed, however, DNS pinning instructs the browser to ignore the TTL and add some unit of time (say one hour) to it. So now, your browser won't make another DNS query for that hostname for 1 hour, 1 second. After the DNS query completes, your HTTP request is sent and the attacker sends back the website you requested with javascript code which will launch the attack.
Now, the attacker's Javascript has set up an AJAX request which waits two seconds before firing. Then it automatically requests some resource on the attacker's website again. However, the request fails. This is because the attacker has already set up a firewall rule blocking your browser's request. Now we are in the following state:
- The TTL has expired on your first DNS request, but DNS pinning is still in effect
- You made a request back to the attacker's website via their JS AJAX call
- The request was dropped by the attacker's firewall
These three things will cause your web browser to send another DNS query despite the fact that you are using DNS pinning. In effect, the attacker has easily defeated your DNS pinning strategy by using a firewall and sending a second request outside of the TTL. DNS pinning isn't an effective strategy because there are plenty of legitimate reasons why someone's server might be down; your browser is forced to make a second DNS query in case there is another DNS record that will resolve to the correct machine (e.g. in case of a server migration, downtime, whatever). Basically, your browser has no way of knowing whether or not it's actually being attacked here; for all it knows, the server is legitimately down and so, it MUST make another DNS request.
So... why does it matter that there's a second DNS request?
The second DNS request is usually used by the attacker to return an incorrect IP address for the DNS record. Browsers have what is called a "same origin" policy which prevents webpages from making requests of resources that they do not own. Basically the way same origin works is that it says http://hostname.com can only request http://hostname.com. But it actually works using the IP address for hostname.com, not the human readable hostname itself. So in a DNS rebinding attack, when your browser makes the second DNS query that I described earlier, the attacker will return a "fake" IP address in the DNS query result. Then your browser will think, for example, that the IP address 1.1.1.1 belongs to attacker.com even though it really belongs to google.com. This allows the attacker to exploit the same origin policy of the browser; now the attacker's javascript can request stuff from google.com via AJAX. Also, they can read and set cookies and other malicious stuff. This exploits same origin policy by tricking the browser into trusting the second DNS record that was returned. Now the browser thinks hostname.com is associated with the IP address 1.1.1.1 even though it really isn't. What's a browser to do? DNS doesn't have that kind of authentication built in. :(
Preventing the DNS rebinding attack
There are a bunch of ways to prevent it, and I'm pretty sure modern browsers already have implemented protection against these attacks. One easy way to prevent it (as a web owner) is to check the HTTP host header of a request. For example if you are google.com then you would receive a request but the host header would still say attacker.com. Obviously that isn't part of your domain, so you can prevent the attack simply by dropping the request. Why would someone want to do this to begin with? Well, click fraud in advertising. Scraping search engines from many machines at once. Stealing valuable data from web sites on your internal company network. Etc.