0

I've came across an interesting question today - how can a JavaScript detect that a DNS Spoofing attack has been made against the client its running upon?

Scenario:

Edit: wrong scenario was presented. Please refer @Polynomial's excellent explanation. I will update this question with a detailed, more challenging scenario soon.

Thanks!

1 Answer 1

1

DNS spoofing doesn't change which domain a victim reaches, but rather which IP it thinks the domain points to. As an example, if I try to fetch the DNS A record for http://example.com, and an attacker performs DNS spoofing, they can falsify the DNS A record contents in the response and point me to an attacker-controlled IP address. My browser still shows http://example.com in the URL, but it connects to the attacker's IP rather than the correct IP. This is a common man-in-the-middle trick.

The solution for this is SSL/TLS. Your browser goes to visit https://example.com and the attacker performs DNS spoofing, but since the attacker cannot own a valid CA-signed certificate for that domain the certificate will show up as invalid and the browser will not connect. This only work if your web page directly points to the HTTPS version of the site, though. If you point to HTTP and the server redirects you to HTTPS, an attacker can still man-in-the-middle the initial HTTP connection and proxy that rather than forwarding you to HTTPS.

By X-Allow-Origin I assume you mean Access-Control-Allow-Origin (ACAO), which is part of Cross-Origin Resource Sharing (CORS). CORS tells the browser which other domains can access data on your server from using Ajax, for example xyz.com can set an ACAO header that allows scripts on bbb.com to access data on its site. This does not prevent DNS spoofing attacks. As I described above, your browser still thinks you're visiting the original domain name, it's just that the IP address for that domain is illegitimate.

Frames are controlled by X-Frame-Options, which specifies a policy of which domains (if any) can load your webpage inside a frame. This is mostly a protection against clickjacking and UI redressing. The X-Frame-Options header is now deprecated in favour of the frame-ancestors Content Security Policy (CSP) directive, which has more granular control over frames than X-Frame-Options does. Again, this operates on domains not IPs, so it doesn't prevent DNS spoofing.

In both cases (frame options and CORS) they rely upon your browser being able to tell that it is visiting a legitimate server, hence the need for HTTPS.

Luckily, you've got some weapons in this fight. The first is HTTP Strict Transport Security (HSTS). By setting this header you can tell a browser that all subsequent visits to the site must be over HTTPS, and if it sees a HTTP URL it should automatically use a HTTPS one instead. This means that all visits except the first are protected against man-in-the-middle attacks. HSTS also (usually) prevents the browser from allowing the user to skip past the certificate error. Since you're using TLS, an attacker can't do a man-in-the-middle attack regardless of what type of spoofing they use (DNS, ARP, etc.)

The next trick is to explicitly use https:// for the third party domain in the ACAO header, i.e. https://bbb.com rather than http://bbb.com or bbb.com. This means that if a user visits the third party site over plain HTTP, their browser will refuse to communicate with your site because of a CORS policy violation. This protects you against cases where an attacker does a man-in-the-middle attack against the 3rd party rather than your site.

Thirdly you can use X-Frame-Options and CSP's frame-ancestors directive to restrict which other domains can load your page in an iframe. Again you can specify https://bbb.com explicitly to ensure that the 3rd party can only load your page in an iframe when the user has visited it over HTTPS.

If the request fails due to CSP, it may be possible to detect that directly in JavaScript, but this StackOverflow question suggests not - it just appears as an error state like any other. However, what you can do is configure CSP reporting, which causes the user's browser to send a report to a URL of your choice containing details about the event whenever something is blocked by CSP. You can implement CSP report logging on your own server, but if you're looking for a quick and easy (and potentially free!) solution I would suggest considering signing up to report-uri.com to handle this for you.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .