dw制作个人网站的具体步骤,做网站设计参考文献,网站游戏入口,织梦 大型综合旅游网站 源码在JavaScript文件中存储敏感数据#xff0c;不仅是一种错误的实践方式#xff0c;而且还是一种非常危险的行为#xff0c;长期以来大家都知道这一点。 而原因也非常简单#xff0c;我们可以假设你为你的用户动态生成了一个包含API密钥的JavaScript文件#xff1a; apiCall…在JavaScript文件中存储敏感数据不仅是一种错误的实践方式而且还是一种非常危险的行为长期以来大家都知道这一点。 而原因也非常简单我们可以假设你为你的用户动态生成了一个包含API密钥的JavaScript文件 apiCall function(type, api_key, data) { ... } var api_key 1391f6bd2f6fe8dcafb847e0615e5b29 var profileInfo apiCall(getProfile, api_key, all) 跟上述例子一样每当你在全局范围创建一个变量意味着网站中任何一部分代码都可以访问到这个变量包括你托管的其他脚本在内。 为什么这样做很明显是不安全的 为什么开发人员不应该在JavaScript文件中嵌入敏感信息呢原因有很多对于经验不丰富的开发人员来说通过JavaScript文件来传递数据是一种非常简单的方法因为你可以将数据在服务器端生成和存储然后将它们传递给客户端代码而且这样还可以节省一部分发送给服务器端的请求。但是这种时候我们通常会忽略的一个因素就是浏览器的扩展插件有的时候为了使用相同的窗口对象它们有的时候需要直接在DOM中注入script标签因为仅仅依靠内容脚本可能无法实现预期的功能。 有没有办法保护变量的安全 我们之前已经讨论了全局范围了对于浏览器中的JavaScript来说一个全局变量对于窗口对象来说是非常有用的。但是在ECMA Script5中还有一种额外的范围也就是函数范围。这也就意味着如果我们使用var关键字在一个函数内部声明了一个变量它就不是全局变量了。而在ECMA Script 6中又引入了另一种范围即块范围这个范围内的变量使用const和let关键字来声明。 这两种关键字可以用来声明块范围中的变量但是我们无法修改const变量的值、如果我们没有用这些关键词来声明变量或者说我们在函数外部使用了var变量我们就相当于创建了一个全局变量而这种情况并不是我们经常想要出现的。 “use strict” 为了防止你不小心创建了全局变量其中一种有效方法就是激活限制模式大家可以在一个文件或函数的起始位置添加字符串“use strict”来实现这个功能。接下来如果你之前没有声明这个变量的话你将无法使用这个变量。 use strict; var test1 arka // 有效 test2 kapı // 引用错误 我们可以在IIFE立即调用的函数表达式中使用这种技术IIFE可以用来创建一个函数范围但是它们会立即执行函数主体比如说 (function(){ use strict; //在函数范围内声明变量 var privateVar Secret value; })() console.log(privateVar) // 引用错误 可能乍看过去这会是一种创建变量的有效方式其内容无法在范围外读取但其实不然。虽然IIFE是一种防止全局命名空间被干扰的有效方式但是它们并不能真正保护你的数据内容。 从私有变量中读取敏感数据 实际上我们几乎无法保证私有变量中的内容真正的是“私有”的。原因有非常多我们接下来会对其中的部分进行测试虽然不够完整但也足够证明给大家看为什么我们不能在JavaScript文件中存储敏感数据。 重写原生函数 在下面的例子中我们将使用一个api密钥来向服务器端发送请求。因此我们需要通过网络并以明文数据的形式发送这个密钥而且现在在JavaScript中也没有多少其他可选择的方法。假设我们的代码使用了fetch()函数 window.fetch (url, options) { console.log(URL: ${url}, data:${options.body}); }; //EXTERNAL SCRIPT START (function(){ use strict; var api_key 1391f6bd2f6fe8dcafb847e0615e5b29 fetch(/api/v1/getusers, { method: POST, body: api_key api_key }); })() //EXTERNAL SCRIPT END 你可以看到我们可以直接重写fetch()函数然后窃取API密钥。唯一的前提就是我们需要在我们的脚本块后include一个外部脚本。在这个例子中我们只是在控制台console.log出来了这个API密钥但实际操作中我们还需要将其发送到我们的服务器中。 定义Setter和Getter 私有变量中可能不仅包含字符串还有可能包含对象或数组。对象可以有不同的属性在多数情况下你可以直接设置和读取它们的值但是JavaScript还支持很多其他有意思的功能。比如说你可以在一个对象的属性被设置或被访问的时候执行另一个函数这里可以使用__defineSetter__和__defineGetter__函数来实现。如果我们在对象构造函数的原型中使用__defineSetter__函数我们就可以输出分配给目标对象属性的所有值。 Object.prototype.__defineSetter__(api_key,function(value){ console.log(value); return this._api_key value; }); Object.prototype.__defineGetter__(api_key,function(){ return this._api_key; }); //EXTERNAL SCRIPT START (function(){ use strict let options {} options.api_key 1391f6bd2f6fe8dcafb847e0615e5b29 options.name Alice options.endpoint get_user_data anotherAPICall(options); })() //EXTERNAL SCRIPT END 如果分配给对象属性的是一个API密钥那我们就可以直接在setter中访问它了。另一方面getter也可以确保我们的后续代码能够正确执行。 自定义枚举器 数组肯定是不能忽略的一个因素如果代码中使用了for循环来遍历数组值我们就可以在数组构造器原型中定义一个自定义的枚举器这样不仅可以允许我们访问数组中的内容而且也不会影响原生函数的功能。 Array.prototype[Symbol.iterator] function() { let arr this; let index 0; console.log(arr) return { next: function() { return { value: arr[index], done: index arr.length } } } }; //EXTERNAL SCRIPT START (function(){ let secretArray [this,contains, an, API, key]; for (let element of secretArray) { doSomething(element); } })() //EXTERNAL SCRIPT END 后话 除了本文所介绍的方法之外攻击者还有很多从JavaScript文件中窃取敏感信息的方法。有的情况下使用IIFE、限制模式和在函数/块范围声明变量都不一定能保证你的安全。因此我建议大家可以从服务器端动态获取敏感数据而不是直接在JavaScript文件中存储敏感数据。这样不仅更加安全而且还易于维护何乐而不为转载于:https://www.cnblogs.com/h2zZhou/p/9770439.html