@@ -22,15 +22,27 @@ predicate isLocalhostPrefix(string host) {
2222 ] )
2323}
2424
25- bindingset [ path]
26- predicate isUntrustedSourcePath ( string path ) {
27- path .substring ( 0 , 2 ) = "//"
25+ /** A path that is vulnerable to a MITM attack. */
26+ bindingset [ url]
27+ predicate isUntrustedSourceUrl ( string url ) {
28+ url .substring ( 0 , 2 ) = "//"
2829 or
29- exists ( string hostPath | hostPath = path .regexpCapture ( "http://(.*)" , 1 ) |
30+ exists ( string hostPath | hostPath = url .regexpCapture ( "http://(.*)" , 1 ) |
3031 not isLocalhostPrefix ( hostPath )
3132 )
3233}
3334
35+ /** A path that needs an integrity check — even with https. */
36+ bindingset [ url]
37+ predicate isCdnUrlWithCheckingRequired ( string url ) {
38+ // Some CDN URLs are required to have an integrity attribute. We only add CDNs to that list
39+ // that recommend integrity-checking.
40+ url .regexpMatch ( [
41+ "^https?://code\\.jquery\\.com/.*\\.js$" , "^https?://cdnjs\\.cloudflare\\.com/.*\\.js$" ,
42+ "^https?://cdnjs\\.com/.*\\.js$"
43+ ] )
44+ }
45+
3446abstract class IncludesUntrustedContent extends HTML:: Element {
3547 /** Gets an explanation why this source is untrusted. */
3648 abstract string getProblem ( ) ;
@@ -39,8 +51,12 @@ abstract class IncludesUntrustedContent extends HTML::Element {
3951/** A script element that refers to untrusted content. */
4052class ScriptElementWithUntrustedContent extends IncludesUntrustedContent , HTML:: ScriptElement {
4153 ScriptElementWithUntrustedContent ( ) {
42- isUntrustedSourcePath ( this .getSourcePath ( ) ) and
43- not exists ( string digest | not digest = "" | this .getIntegrityDigest ( ) = digest )
54+ not exists ( string digest | not digest = "" | this .getIntegrityDigest ( ) = digest ) and
55+ (
56+ isUntrustedSourceUrl ( this .getSourcePath ( ) )
57+ or
58+ isCdnUrlWithCheckingRequired ( this .getSourcePath ( ) )
59+ )
4460 }
4561
4662 override string getProblem ( ) {
@@ -50,7 +66,7 @@ class ScriptElementWithUntrustedContent extends IncludesUntrustedContent, HTML::
5066
5167/** An iframe element that includes untrusted content. */
5268class IframeElementWithUntrustedContent extends HTML:: IframeElement , IncludesUntrustedContent {
53- IframeElementWithUntrustedContent ( ) { isUntrustedSourcePath ( this .getSourcePath ( ) ) }
69+ IframeElementWithUntrustedContent ( ) { isUntrustedSourceUrl ( this .getSourcePath ( ) ) }
5470
5571 override string getProblem ( ) { result = "iframe elements should use an HTTPS url" }
5672}
0 commit comments