@ThiefMaster's answer does a great job of enumerating the risks of using an externally controlled Content-- which basically fall under the category of executing or displaying arbitrary code and content on a user's browser.
I will mainly focus on your last question: How are those risk mitigated?
which was unaddressed-- a lot has since changed (in 4 years).
The primary defense when including external resources from a CDN is to use Subresource Integrity (SRI). SRI extends two HTML elements with an integrity attribute that contains a cryptographic hash of the representation of the resource the author expects to load. Specifically, these are the <script>
and <link>
elements, commonly used to include third-party Javascript and CSS respectively.
Examples:
CSS:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css" integrity="sha384-y3tfxAZXuh4HwSYylfB+J125MxIs6mR5FOHamPBG064zB+AFeWH94NdvaCBm8qnd" crossorigin="anonymous">
JS:
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/js/bootstrap.min.js" integrity="sha384-vZ2WRJMwsjRMW/8U7i6PWi6AlO1L79snBrmgiDpgIWJ82z8eA5lenwvxbMV1PAh7" crossorigin="anonymous">
One or multiple hashes can be used, generally generated with openssl with base64 encoding. A browser uses the "strongest" one that it supports.
This is now supported by Chrome and by Firefox.
When these browsers encounter an SRI-protected element, they compute the digest and return a network error if it does not match the expected result. To protect against an update on a CDN, failovers can be setup, either to other CDNs or to your own server.
Another defense you can note above is the use of the crossorigin="anonymous"
attribute. This prevents your browser from sending cookies to the CDN, thus avoiding CORS leaks with a side effect of reducing the request size.
Finally, a very slight benefit could be found by setting a restrictive Content-Security-Policy
that limits the attack surface only to the CDN, such that even if a vulnerable CDN was infected by a different JS file, it will not directly be able to access the data (though it could through the CDN).
Apart from the various links above, another useful reference is this Mozilla Hacks article.