由 Google 和 Mozilla 领导的一个小组正在开发能够使用基于浏览器的 Web
应用轻松编辑文件的
API,这可以让用户不用每次编辑文件后下载新文件。但是开发团队认为这一功能会造成滥用,带来安全问题,所以其希望获得有关如何防范主要安全和隐私风险的建议。

时间: 2017-12-21阅读: 917标签: web

开发团队认为这样一个功能放在今天是很有必要的,用户只需要在 Web
应用上做好保存,而不需要每次编辑本地文件后都重新下载它们。

Web应用程序开发是一个很宽泛的话题。本文仅讨论Web应用开发者应当避免的安全错误。这些错误涉及到任何开发者都不应当忽视的基本安全原则。

渐进式 Web
应用是利用现代浏览器的特性,可以添加到主屏幕上,表现得像原生应用程序一样的
Web 应用程序。

谷歌开发者布道师 Pete LePage 指出:“今天,如果用户想要在 Web
应用中编辑本地文件,那么 Web
应用需要让用户打开该文件,在编辑文件后,保存更改的唯一方法是将文件下载下来。这种用户体验很糟糕,并且很去难构建访问用户文件的
Web 应用。”

澳门新葡萄京官网注册 1

什么是渐进式 Web 应用

为此,由 Chrome 开发人员和 Firefox 开发人员代表担任主席的 W3C Web
孵化社区组织(WICG)正致力于开发新的 Writable Files API,该 API
允许在浏览器中运行的 Web 应用打开文件、编辑,并将更改保存到同一文件。

开发者应当注意哪些基本的安全原则?应当避免哪些安全错误?为回答这些问题,下面的建议可以回答上述问题。

渐进式 Web 应用(PWA)本质上与普通的网站没有什么不同 – 它也是由
HTML、CSS 和 JavaScript 组成,并且存活于浏览器中。将 PWA
与普通网站区别开的是它需要满足的 10 个核心概念列表。下面就是直接从
Google 开发者网站上摘录的这个列表:

然而,该组织表示,最大的挑战将是防止恶意网站滥用持久访问用户系统上的文件。“到目前为止,这个
API 最难的部分当然是要使用的安全模型”,WICG 的 API
解释器页面警告到:“API 可能被滥用并带来许多可怕的攻击。”

澳门新葡萄京官网注册,自以为是:开发自己的安全方法

安全– 通过 HTTPS
来提供服务来防止网络窥探,保证内容不被篡改。渐进式
能够让每一位用户使用,无论用户使用什么浏览器,因为它是始终以渐进增强为原则响应式
适应任何环境:桌面电脑、智能手机、平板电脑,或者其他设备。不依赖网络连接
通过用 service workers
增强,可以在离线或者低质量网络下工作类原生应用
有像原生应用般的交互和导航给用户原生应用般的体验,因为它是建立在 app
shell model 上的。持续更新– 受益于 service worker
的更新进程,应用能够始终保持更新。可发现
可识别为“应用程序”,是得益于 W3C manifests 元数据和 service worker
的登记,让搜索引擎能够找到 web 应用。可再次访问
通过推送通知等特性让用户再次访问变得容易。可安装
允许用户保留对他们有用的应用在主屏幕上,不需要通过应用商店。可链接
通过 URL 可以轻松分享应用,不用复杂的安装即可运行。

(文/开源中国)    

有些开发者错误地认为自己的算法或认证方法更安全:毕竟黑客从未见识过这种方法,所以他们在破解时会更困难。果真如此吗?

遵循这些指南,会确保你的应用不仅在浏览器中查看时,还能在单独通过主屏幕快捷键启动时,都运行的不错。你可能会发现
Google
选用的措辞令人相当困惑,不过不要着急,我们会在本教程中一个一个解释这些规则。

答案是否定的。开发者自己开发认证或登录方法是一个错误,因为他会犯一个或一些黑客能够发现的错误。开发者应当依靠现有的经过完全测试的安全方法,原因在于它们已经被安全社团反复测试过了。因此,这些方法不太可能包含被开发者忽视的重大安全漏洞。有安全专家指出,任何人都可以发明一种他们自己无法破解的加密算法,但要开发一种别人无法破解的方法就困难多了。所以,开发者还是老老实实地用经认证或安全测试的方法吧。

渐进式 Web 应用不是什么

粗心大意:直接使用用户提供的信息访问数据库

PWA 的概念不应该与如下概念混淆:基于Cordova的混合 app,React
Native,NativeScript,Electron以及NW.js…

在开发应用程序特别是在开发Web应用程序时,许多开发者没有充分地验证从用户那儿接收到的输入数据。这种做法存在安全问题,因为它允许非法的数据进入客户的数据库,并且还有更大的安全隐患。不能对用户的输入进行验证(无论是来自Web还是来自API)会导致SQL注入、跨站脚本攻击、命令劫持、缓冲区溢出,以及被攻击者利用的其它Web应用程序漏洞。

所有前面提到的技术都是把 HTML
应用打包成可执行文件,比如.apk、.exe等等,然后必须从各自的应用商店下载下来,安装到用户的设备上。

这种错误在Web应用程序的开发中是最常见的。如果没有保护这些程序,用户就有可能利用输入字段将恶意脚本注入到应用程序或者访问数据库的私密数据。当然,多数用户不会有什么恶意企图,但开发者必须用防御的心态和方法来处理用户输入。

PWA 不需要安装,也依然不能用在 Google Play 或者 iTunes
应用商店中。要下载一个
PWA,只需要访问它的网站,然后将其作为快捷键保存到主屏幕上。对 iOS 和
Android 各自开发和维护一个版本不再是问题,但是需要考虑浏览器支持不支持。

开发者不应当轻易相信用户输入,而要在客户端和服务器端进行双重验证。否则,就有可能产生严重的漏洞,如:跨站脚本攻击和SQL注入等。

  1. 安全

忽视全局:关注组件而非整个系统

大多数渐进式 Web 应用要使用原生 API 和 service worker
这些处理敏感数据的技术,需要谨慎处理。这就是为什么每个 PWA 都要通过
HTTPS 连接访问的原因。

大型的开发项目往往是由多个开发者开发应用程序的不同部分,因而开发人员就容易关注个别组件。当然,如此开发的应用程序,其每个小部分可能很安全,但开发者是否考虑过整体的安全性?

如果你没有带有 SSL
证书的服务器,那么在安全环境下运行项目的最简单的方法是通过GitHub
Pages或者类似的服务。所有 Github 库都可以直接通过 HTTPS 存放,并且
GitHub 和 GitHub Pages 对公共仓库都是免费的。

许多安全问题并非产生于组件自身,而是在数据和过程从业务进程的一部分流动到另一部分时才会出问题。开发者一般都承担着一项业务进程的一部分,并且一般不理解业务过程的其它部分。这种认知缺乏会导致不安全的数据传递,从而将数据暴露给各种攻击和威胁,如中间人攻击、数据完整性问题、信息泄露等。

这是我们用来存放演示应用的地方:-photobooth/。

开发者对企业的业务服务有一个系统的观点是至关重要的,只有这样才能理解所有的组件如何协作,以及如何保证合并后的应用程序的安全。

如果只是在本地服务器上测试,还可以试试Ngrok。它是一个小工具,可以在任何当前运行的本地主机和一个公共
URL 之间建立一个安全通道。Ngrok是免费的,并且可用在 Windows、Mac 和
Linux 系统上。

后期修补:在开发后期增加安全功能

  1. 渐进式

有的网站或Web应用在构建时并没有内建安全性。记住:安全并不是以后增加的东西,它应当是整个应用架构的整体功能的一部分。架构是应用开发的最重要的方面,因为它会影响应用程序的所有其它方面,其中就包括安全性。

本质上,渐进式的意思是,PWA 应该使用被广泛支持的 Web
技术,并且可以同样运行在尽可能多的浏览器上。众所周知,在 Web
开发领域,这近乎是不可能的,但是我们依然可以做一些事情来覆盖更大的用户群。

这种错误的表现(如漏洞和错误配置)可以追溯到开发阶段:开发者最后将安全作为一种额外增加的特性或功能。如有的开发团队有这样的认识:不错,所有的功能都正常运行,现在开始解决安全性问题吧。这种思想会带来应用程序架构上的安全漏洞从而增加风险。在应用程序完全部署后,任何人都很难去解决跨站请求伪造(CSRF)及大量的SQL注入漏洞了。所以,开发者应当在开发和构建Web应用程序的整个生命周期中构建安全性。

例如,在 PhotoBooth 应用程序中,我们使用getUserMedia()API
来访问一个设备上的硬件相机。它在不同浏览器上的支持很不一致 – Safari
完全不支持,而支持它的浏览器需要前缀,并且用法各不相同。

放任用户:允许用户生成弱口令

为确保更多的人可以使用我们的应用程序,我们涵盖了所有前缀:

每当有攻击者破解网站或Web应用并暴露用户口令时,一个明确的事实都会随之浮出水面:用户们的安全习惯太差。例如,用户们的最常用的口令是“abcde”或“12345678”之类。Web应用的开发者不应当允许用户创建弱口令。开发者应当要求用户的口令达到足够的长度,确保其易于记忆但又难以猜测(例如,强口令至少应当包含字母、数字及特殊字符,长度达10个字符以上)。最好的口令未必是最复杂的。强迫用户使用过度复杂的口令往往导致用户一些不安全的做法,例如把口令写下来然后再贴到电脑的一个地方。

navigator.getMedia = ( navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);

忽视加密:以纯文本存储用户口令和数据

如果所有前缀都不行,就显示一个错误:

Web应用开发者最常犯的错误是没有保证用户认证凭据的安全。用户们想当然地认为网站或Web应用会做得很安全,但不幸的是,太多的网站或Web应用没有做好。从总体上说,
Web应用或网站在处理和保存口令方式上往往存在漏洞。

if (!navigator.getMedia) { displayErrorMessage("你的浏览器不支持 navigator.getUserMedia 接口。");}else { // 使用 Camera API}

问题是:怎样才能正确地保存口令?这里重点谈一个最常见却很不安全的做法:以明文保存口令。许多大公司也有可能犯这样的错误。对企业数据库的任何损害都不应当使用户数据遭受风险,尤其是用户们使用的口令。因而,企业的应用程序应当对用户的口令和其它细节进行加密,然后才将其保存在一个数据库中。

在可能的情况下,应该提供回退(Fallback)和填补(polyfill)。同样的原则也适用于
CSS 和 HTML 代码。

企业应用的开发者必须思考,在黑客取得企业数据库的访问权时,他们能怎样轻易地窃取数据?如果开发者加密数据,就会导致个人和企业信息的大量泄露。

  1. 响应式

仅仅因为数据库引擎要求用户名和口令并不意味着黑客无法窃取数据文件和获取其中的信息。数据的安全性依赖于数据库引擎的安全性,如果黑客利用了数据库引擎的漏洞,就可以轻松地访问数据库。这正是许多大型游戏和电子商务网站遭受破解的原因,也是包含信用卡数据在内的所有个人信息失窃的原因。

应用程序应该在所有设备上都看起来不错,不管屏幕大小是多少。我们应用的 UI
相当简单,所以只用了两个媒体查询来控制字体大小、padding、margin 等。

“明修栈道”:通过URL路径名传递变量

不要害怕使用 CSS
库和框架,比如Bootstrap。它们会让表单栅格、排版处理和普通的响应性变得很容易。

还有一种危险但常见的做法:许多开发者把变量放在URL中,这会为黑客打开利用其它应用或数据的大门。这种错误的风险非常巨大。

  1. 独立于网络连接

开发者绝对不能允许用户与之交互的变量成为文件路径的一部分。如果URL中包含下载文件的路径,攻击者就可以修改URL,使其引用另一个文件,从而可能下载包含用户口令的文件。由此,攻击者用一个链接(例如,该链接允许用户下载应用程序的免费版)就达到了利用漏洞的目的。

这是很重要的一点。使用service
worker可以让应用能在无互联网连接的情况下依然可以运行。

正所谓开发者“明修”了“栈道”,却被攻击者“暗渡”了“陈仓”。

有些应用可以只部分缓存:UI
被缓存,并且离线可用,动态内容依然需要访问服务器。

顾此失彼:仅在客户端执行授权

有些应用,比如我们的 PhotoBooth
演示应用,可以全部缓存。所有源代码和资源都将被保存在本地,应用程序在离线和在线情况以完全相同的方式运行。如下是让这种奇迹得以发生的代码:

如今,越来越多的开发者日渐重视客户端。这种趋势会使应用程序更快更强大,但如果开发者不能正确地解决程序的授权问题,就会带来安全隐患。

这是 Service Worker 的过分简化用法,在商业项目中要慎用。

很多Web应用的开发者依赖客户端的浏览器去完成以前在服务器完成的任务。从安全的观点看,这种做法缺少了许多控制,因为开发者并不了解客户端的种类。客户端甚至有可能并非浏览器。开发者不应当轻易地相信发生在客户端的操作,不应当仅依赖JavaScript或客户端代码来实现关键功能,对于涉及到付款信息和其它敏感信息的功能,尤其要注意。

首先需要创建一个 service worker JavaScript 文件,定义背后的逻辑。

盲目乐观:认为自己不可能出问题

sw.js

在开发Web应用程序时,开发人员容易犯的错误是:想当然地认为自己的应用程序不会遭到攻击,或者认为自己不会犯错误。这些想法都会导致安全问题。开发者应当总是设想自己的程序会遭受攻击,而且自己也会犯安全方面的错误。这种思想有助于开发者避免或减少安全风险,从而避免公司遭受损失。

// 安装 service worker.this.addEventListener('install', function(event) { event.waitUntil( caches.open('v1').then(function(cache) { // 如果这些资源中有任何资源不能保存,缓存就会失败 return cache.addAll([ // 路径是相对于缓存来源,而不是应用程序的目录。 '/pwa-photobooth/', '/pwa-photobooth/index.html', '/pwa-photobooth/assets/css/styles.css', '/pwa-photobooth/assets/fonts/MaterialIcons-Regular.woff2', '/pwa-photobooth/assets/js/script.js', '/pwa-photobooth/assets/icons/ic-face.png', '/pwa-photobooth/assets/icons/ic-face-large.png', '/pwa-photobooth/manifest.json' ]) .then(function() { console.log('成功! App 离线可用!'); }) }) );});// 定义一个资源被请求时候会发生什么// 对于我们的应用,我们以缓存优先的方式self.addEventListener('fetch', function(event) { event.respondWith( // 试着从缓存中获取. caches.match(event.request) .then(function(response) { // 如果资源没有存储在缓存中,就回退到网络 return response || fetch(event.request); }) );});

谁都会犯错。如果开发者在黑客找到漏洞之前自己先找到了问题,问题还不算大。在开发者和软件测试者测试和审计Web应用程序时,或在企业投入使用程序之前,开发者或测试者不妨使用著名的开源工具OWASP
ZAP来扫描企业的应用程序,查找一些常见的漏洞和错误。

然后,我们需要将该 service worker 链接到 HTML。

结束语

index.html

此文谈到了一些最基本的却是很重要的一些安全错误。希望开发者在此基础上能够进一步发现和总结在Web应用开发过程中的其它问题,构建更坚实的安全保障。

// 注册 Service Worker.if ('serviceWorker' in navigator) { // 路径是相对于缓存来源,而不是应用程序的目录. navigator.serviceWorker.register('/pwa-photobooth/sw.js') .then(function(reg) { console.log('Registration succeeded. Scope is ' + reg.scope); }) .catch(function(error) { console.error('Registration failed with ' + error); });}

【编辑推荐】

现在,项目中的所有文件都将被保存在用户浏览器中。所有 JavaScript
变量和对象也应该尽可能保存在localStorage或者IndexDB中。

现在 Service Worker 在 Chrome、Firefox 和 Opera 中是被支持的。Safari 和
Edge 也正努力采用它。希望将来所有浏览器都支持它。

  1. 类原生引用

在创建 PWA
时,推荐遵循一个称为应用外壳的架构的设计概念。它听起来很复杂,但是实际上可以总结为:应用被分为两个主要组件:外壳内容

外壳包含了所有静态 UI
元素,比如标题、菜单、抽屉等。在缓存应用程序时,外壳应该总是保存在设备上,因为我们想让它始终可用。这样,当无互联网连接的用户打开应用程序时,就不会看到空白屏幕或者一个奔跑的恐龙

  • 而是会看到缓存了的应用程序界面以及恰当的错误消息。

内容驻留在外壳内。它也可以被缓存,但是没有必要这样做,因为内容通常是动态的,会频繁发生改变,并且每个页面加载时都可能是不同的。

  1. 持续更新

一旦被缓存了,PWA 会总是从本地存储加载。不过,如果以任何方式修改了
service workersw.js,那么在下一个页面加载时,新版本就会被下载和安装。

this.addEventListener('install', function(event) { event.waitUntil( caches.open('v1.0.1').then(function(cache) { // ... }) );});

通过使用 service worker
更新,我们可以重新下载资源,删除旧缓存,或者彻底修改 service worker
逻辑。你可以从这篇 Google 开发者文章中,学到更多有关 SW 更新过程的知识。

  1. 可发现

通过给应用程序添加一个Web
Manifest,可以提供有关应用程序的各种信息,并且可以修改应用程序在用户设备上的显示方式。它允许应用程序被带自定义图标的方式保存到主屏幕上,在一个单独的浏览器窗口中启动,以及很多其它很酷的东西。

Web Manifest 是以一个简单 JSON 文件的形式出现:

manifest.json

{ "name": "Progressive Web App: PhotoBooth", "short_name": "PhotoBooth", "description": "Simple Progressive Web App for taking selfies.", "icons": [{ "src": "assets/icons/ic-face.png", "type": "image/png", "sizes": "72x72" }, { "src": "assets/icons/ic-face-large.png", "type": "image/png", "sizes": "144x144 256x256" }], "start_url": "index.html", "display": "standalone", "background_color": "#fff", "theme_color": "#fff", "orientation": "portrait"}

大多数属性是自解释的,所以我们只讲讲较为重要的一些属性。要查看完整的 Web
manifest 格式,以及所有可用的字段,请到这里。

Shortname – 这是应用保存到主屏幕上时的名称。Icons –
不同分辨率的图标数组。Display –
定义应用打开的方式。我们选择的是独立(standalone),所以启动 PhoneBooth
时,会以全屏窗口出现,没有浏览器导航栏或者菜单。它还会被看作为多任务中的一个单独的应用。

要注册 Manifest 文件,必须把它链接到 HTML 中:

lt;link rel="manifest" href="manifest.json"gt;

Safari 还不支持 Web Manifest 标准,但是我们可以用如下的苹果特定的 meta
标记,定义类原生应用的行为:

lt;meta name=”apple-mobile-web-app-capable” content=”yes”gt;
  1. 可再次访问

通知推送不再只限于原生应用。多亏了 service worker 和Push API,Web
应用程序也可以发送消息给 Android
通知栏。并不是所有应用都可以从这个功能受益,但是当正确使用此功能时,通知确实可以帮助吸引用户。

这个主题已经超出了本教程的范围,因为推送很复杂,值得用一个完整的课程讲解。如果你依然想在你的
Web 应用中实现通知推送,这里有一些最好的学习资源:

Google 开发者网站上的《推送通知:及时、相关和准确》 –这里.Google
开发者网站上的《开放 Web 上的推送通知 –这里.MDN 上的《使用 Push API》
–这里.Push.js 库,提供处理推送通知的更清洁的 API –这里.9. 可安装

默认情况下,任何网站都可以用 Chrome 浏览器菜单的 “添加到主屏幕”
按钮,保存到主屏幕上。不过,让用户以这种方式 “安装”
应用程序可能有点难,因为大多数人完全不知道这个功能。

值得庆幸的是,还是有一种方式让应用程序提示用户保存它,即采用一个简单安装弹出窗口来提示。为防止开发者滥用这些弹出窗口,不允许以编程的方式显示它们。而是在应用程序满足如下几个条件时,才会让这些窗口自己出现:

有一个有效的 Web Manifest。安装有有效的 Service Worker。通过 HTTPS
访问应用程序。

我们满足上面涉及的所有条件,所以当用户访问网站几次后,会得到这个提示:

整个应用程序的安装过程就在这个简单的提示中。安装立即发生,并且一旦保存了,PhotoBooth
就可以从主屏幕图标启动,表现得与原生应用一模一样。

  1. 可链接

任何人只有要浏览器,就可以访问 PWA 应用,这样应用仅通过其 URL
就可以被共享。发现或者安装这些应用不需要第三方工具。

如果应用程序以独立模式运行,因为浏览器地址栏和菜单都是不可见的,所以在应用内添加一个共享按钮也是明智的。

总结

现在我们的 PWA 完成了。我们可以用 Google
的官方工具Lighthouse来测试一下它对 PWA 规则遵循的咋样。Lighthouse
会重建可能的场景,并且完整测试应用。如下是它告诉我们关于 PhotoBooth
的东西:

我们通过了!

如果你想找到更多的 PWA
玩玩,请到pwa.rocks。这个网站上有一些不错的游戏和工具,展示了渐进式 Web
应用的威力。原文链接