时间过得真快。距离上一篇文章:手写一个简单的编译器:在JavaScript中使用Swift的尾部闭包语法已经快半年了。想了半年按时更新文章;但因为工作和生活的琐事,我一直没能坚持下来。我有些惭愧,觉得自己年初定下的计划很快就不可能实现了。希望在接下来的一段时间里继续更新文章。这次要跟大家分享的是SubresourceIntegrity。如果你不太关注Web安全,你可能没有听说过这个名词。不知道也没关系。接下来,我将和大家一起研究和讨论这个内容。相信看完这篇文章后,你可以深刻理解什么是SRI,为什么要使用SRI,以及什么时候需要在项目中如何实践使用SRI。什么是SRI,解决什么问题SRI是SubresourceIntegrity的缩写,意思是子资源的完整性。比如我们在页面中通过link和script标签导入的样式文件或者导入使用的第三方库都是页面的子资源。例如,像下面这样:="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"crossorigin="anonymous">一般来说,为了提高网页的响应速度和性能,我们通常把这些子资源放在CDN上。对于大型互联网公司来说,一般都有自己的云服务,基本都有自己的CDN服务。但是对于小公司来说,一般都是使用云服务厂商提供的CDN功能。这里会有问题。如果我们托管在云服务商的CDN上的资源被篡改,会对我们的业务造成一定的影响。虽然一般情况下不会发生这种事情,但是如果我们的业务对安全性要求比较高,对于这种情况还是要有所防范的。SRI是解决这个问题的方法。那么具体的解决方法是什么呢?首先,对于一个文件,我们如何知道这个文件的内容是否被篡改过呢?我们可以对这个文件进行哈希计算,通过base64编码生成一个与文件内容相关联的唯一字符串。如果文件内容发生了变化,同样的方法生成的字符串与原文件生成的字符串不同。这样我们就知道该文件已被篡改。如果对区块链有所了解,应该更容易理解这一点。对于每一个导入的第三方资源,我们只需要在相应的标签中添加完整性属性即可。integrity属性的值为字符串,形式如下:匿名“>其中SHA384-OQVUAFXRKAP7FDGCCY5UYKM6+R9GQQ8K/UXY9RX7HONQL1KPZQHO1KPZQHO1WX4JWY8WY8WC后面是一个短横线-,用来分隔算法名和后面这个算法生成的base64编码值;最后的oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC表示对应文件计算后生成的字符串。当浏览器下载一个具有完整性属性的子资源时,不会立即执行其中的代码;或在其中应用样式。浏览器会先根据完整性属性值中指定的对应算法和下载文件的内容计算文件的哈希值是否与标签中的值相同。只有两者相同,才会相应的样式或者执行相应的代码。如果两者不同,浏览器将拒绝执行相应的代码,拒绝应用相应的样式。控制台也会报错,提醒我们当前下载的子资源有问题。这样,我们使用SRI来保证我们的页面不会使用从CDN下载的被篡改的内容资源。我们页面的安全性得到保证。如何使用SRI上面简单介绍了SRI的功能,那么如何实践呢?让我们一起练习如何使用SRI。首先我们随便建立一个index.html,然后在里面添加如下内容:>然后创建一个包含以下内容的test.js文件:document.write("HelloWorld!");然后在本地使用Node.jsexpressframework或者其他工具,让test.js在本地可以通过http://localhost:3000/test.js访问。对于上面script标签的完整性属性,我们可以使用如下命令通过openssl工具获取对应sha384算法生成的字符串:cattest.js|openssldgst-sha384-二进制|opensslbase64-A如果是windows环境,需要用另外一种方式获取对应的字符串。然后在浏览器中打开index.html,你会看到页面显示:HelloWorld!。如果我们此时更改test.js的内容,在原来的基础上,去掉HelloWorld!后面的感叹号,如下图:document.write("HelloWorld");那么此时页面是空白的,不再显示HelloWorld。对应的控制台也会报错,但是不同浏览器报错信息不同:Chrome报如下错误:Firefox报如下错误:Safari报如下错误:总之就是会提示你的hash字符串当前下载的子资源被计算出来,后面标签上出现Inconsistency,浏览器拒绝执行相应的代码。这里还有一些需要注意的地方。如果我们的test.js资源和我们的index.html是不同的来源,那么我们需要在标签中加上crossorigin="anonymous",表示请求这个资源需要共享一个跨域资源。否则浏览器会报错如下:对跨域资源共享不了解的同学可以参考跨域资源共享。当然对应的服务器也需要设置相应的响应头:Access-Control-Allow-Origin:*,如果使用express,可以使用cors简单设置即可。具体如下://...app.use(cors({origin:"*",}));//...如何在框架中使用SRI对于Vue项目,我们可以使用VueCLI就可以了使用此功能非常简单。通过在vue.config.js中添加一个配置:integrity:true,我们构建后可以看到打包后的index.html中引入的资源都有integrity属性,如下图:linkhref="/css/app.fb0c6e1c.css"rel="stylesheet"integrity="sha384-1Ekc46o2fTK9DVGas4xXelFNSBIzgXeLlQlipQEqYUDHkR32K9dbpIkPwq+JK6cl">scriptsrc="/js/chunk-vendors.0691b6c2.js"integrity="sha384-j7EDAmdSMZbkzJnbdSJdteOHi77fyFw7j6JeGYAf4O20/zAyQq1nJ91iweLs6NDd">对于其他框架,如果打包工具使用了Webpack,可以直接使用对应的插件webpack-subresource-integrity,相关的安装和使用说明可以参考这里。Integrity在实际使用过程中还有很多细节需要注意。下面就让小编为大家深入介绍一下吧。目前用于计算资源文件哈希值的算法有sha256、sha384、sha512,都是属于SHA-2的安全哈希算法。使用MD5和SHA-1计算哈希值的算法目前已弃用。首先,Integrity值可以有多个,每个值之间用空格隔开。如果多个值使用不同的安全哈希算法,例如如下图:/MMFJEMBGUDBXJPVXFGSHA512-2QG2XR+0xGPSOWJP3VCQQQQQQWFGQLGQALU9XPBQNTV0FDM9SV9LTHSSACHNI2OO2OO6AAAJO6AAAJOMOSACACHSACHNI2OO60KVFU8S1RDDWB8S1RDWB8S1RDWB8OSTITISTINGITIST答案是:浏览器会优先选择安全性最高的计算方式。如果是上面的例子,浏览器会选择sha512等计算hash值的算法。因为sha512的安全性大于sha384,而sha384的安全性又大于sha256,那么剩下的其他方法计算出来的哈希值都会被忽略。这时需要注意的是,如果浏览器基于sha512计算出的hash字符串与提供的不同,则无论sha384或sha256提供的hash值是否正确,浏览器都会考虑该资源计算出的hash.该值与提供的哈希不同。所以相应的代码不会被执行。Ifmultiplevalues??usethesamesecurehashalgorithm,forexample,asfollows:那么这个时候只要有一个值跟浏览器计算的结果是一样的,那么这个资源就可以被认为是没有被篡改的;Thecontentoftheresourceisexecutable.TheIntegrityattributeonlysupportslinkandscripttagstemporarily,andwillsupportmoretagsaboutsub-resourcesinthefuture,suchas:audio,embed,iframe,img,etc.SummaryThesharingabouttheintegrityverificationofwebpagesub-resourcesisoverhere.Ibelievethatifyoureaditcarefully,youshouldhavesomegains.Ifyouhaveanysuggestionsandfeedbackafterreading,youcanleaveamessagehere,orleaveamessageatthebottomofthearticle.Ifyouwanttopracticeityourselfquickly,youcanrefertothesri-demoproject.Someexamplesinthearticlecanbepracticedinthisproject.Ofcourse,youcanalsowritesomeexamplesyourselftopractice.Afterall,ifyoupracticeityourself,youwillrememberthecorrespondingknowledgemorefirmly.Youarealsowelcometopayattentiontomy公众号Guanshanisnotdifficulttocross.Ifyouthinkthisarticleiswellwrittenorhelpfultoyou,pleaselikeandshareit~RecruitmentDasouche,establishedin2012,isprovidingdataanalysis,marketingmanagement,financialandtransactionservicesforthedailyoperationsofcardealers.AsanadvancednewretailplatformforautomobilesinChina,wehavebeenlookingforwardtoredefiningtheindustrywithInternet+intelligentthinkingsinceitsinception.Bylinking,empoweringandleadingtheupstreamanddownstreamoftheindustrialchain,wewillcreateafullcirculationecologyofautomobilesandpromotetheInternetdevelopmentoftheautomobileindustry.WebelongtothefinancialservicesdepartmentofSouche.Duetotherapiddevelopmentofthedepartment'sbusiness,weneedexcellentfront-endengineerstojoinus.Welookforwardtoyoubeingabletodosomethingmeaningfulwithustopromotethedevelopmentoftheautomotiveindustry.让我们互相成就,共同努力,共创美好明天。有关公司的更多信息,您可以浏览大搜车。关于职位薪资和福利的信息,您可以参考职位信息。有兴趣的可以发简历到dreamapplehappy@gmail.com,或者加我微信,备注搜车求内推。如果你的简历可以接受,我会帮你直接推荐给相关负责人。并且可以帮助您及时了解内部晋升的进展情况。参考:SubresourceIntegrityACDNthatcannotXSSyou:UsingSubresourceIntegritySubresourceIntegrityWhatisthebestSRIhashsize?
