[英]How to secure REST API for SPA and Mobile App using Cordova
I've done a lot of research on "best practices" surrounding this and have read blog post after blog post, SO question after SO question, and OWASP article after OWASP article. 我已经对围绕这个的“最佳实践”进行了大量的研究,并在博客文章之后阅读了博客文章,在SO问题之后阅读了SO问题,在OWASP文章之后阅读了OWASP文章。 I've arrived at a few clear answers but some unknowns. 我已经得到了一些明确的答案,但有些未知数。
First, the "Do's": 首先,“做”:
Now I started with the assumption that having a SPA (built with Angular) and using HTML5 sessionStorage would be secure enough for short-lived tokens, but there is a point to be made that XSS attacks can happen from a "bad actor" originating in the one of many libraries loaded in from a CDN. 现在我开始假设拥有一个SPA(使用Angular构建)并使用HTML5 sessionStorage对于短期令牌来说足够安全,但有一点可以说XSS攻击可能来自一个源自“坏角色”的“坏角色”从CDN加载的许多库之一。
For my specific use case, I do not plan on having long-lived tokens - expiration after 10 minutes of non-use but I'm still figuring out if I want to track expiration by session or use refresh tokens - StormPath recommends the former (no longer stateless?) but I believe big players using JWTs use refresh tokens (Google uses them but states you need to store them in secure, long-term storage which means HTML5 localStorage is again, out of the question). 对于我的特定用例,我不计划使用长期令牌 - 在不使用10分钟后过期但我仍然想知道我是否要通过会话跟踪到期或使用刷新令牌 - StormPath推荐前者(不再是无国籍?)但我相信使用JWT的大玩家使用刷新令牌(谷歌使用它们但声明你需要将它们存储在安全的长期存储中,这意味着HTML5 localStorage再次出现问题)。
I would like to make it so my users don't have to log back in if they refresh the page (hence the need to store the token on the client side). 我想这样做,这样我的用户如果刷新页面就不必重新登录(因此需要在客户端存储令牌)。 I would also like to use my SPA as a "mobile app" with the help of Cordova. 我还希望在Cordova的帮助下将我的SPA用作“移动应用程序”。 The obvious pitfall here is that if I use cookies, there is no baked-in cookie support/storage with Cordova and I'm urged to switch to HTML5 local storage instead. 这里显而易见的缺陷是,如果我使用cookie,Cordova没有带烘焙的cookie支持/存储,我应该转而使用HTML5本地存储。 Since on mobile I don't really need to worry about refreshing pages, I can just let my token live in memory and expire with the strategy I settle on. 因为在移动设备上我并不需要担心刷新页面,所以我可以让我的令牌存在于内存中并使用我所确定的策略到期。
If I take this approach, cookie-based JWT on Desktop, "Bearer" headers on mobile, I now need an authentication end-point that will give tokens two different ways, and when I authorize on the REST API side, I need to support both cookie-based JWTs (with CSRF) and header based JWT verification. 如果我采用这种方法,桌面上基于cookie的JWT,移动设备上的“Bearer”标头,我现在需要一个认证端点,它将以两种不同的方式给予令牌,当我在REST API端授权时,我需要支持基于cookie的JWT(带有CSRF)和基于头的JWT验证。 This complication has me worried as I don't know if I can accurately foresee security implications here. 这种复杂情况令我担心,因为我不知道我是否能准确预见到这里的安全隐患。
To summarize the barrage of thoughts above: 总结一下上面的一系列想法:
Is there any reason why I wouldn't want to take this approach? 我有什么理由不想采取这种方法吗? I assume if I take XSS on my SPA as a serious risk, then I need a classic login-page for authentication to set the proper cookies because if I do authentication via the SPA, then any XSS attack could potentially intercept that as well (both on mobile and Desktop)! 我假设如果我在我的SPA上使用XSS是一个严重的风险,那么我需要一个经典的登录页面进行身份验证以设置正确的cookie,因为如果我通过SPA进行身份验证,那么任何XSS攻击都可能会拦截它(两者都有)在手机和桌面上)! However, on mobile, I'd need to inject the JWT into SPA, maybe through some custom DOM element (meta tag?), but at that point I can just let the SPA perform the login and not consider XSS a threat on mobile devices. 但是,在移动设备上,我需要将JWT注入到SPA中,可能通过一些自定义DOM元素(元标记?),但此时我可以让SPA执行登录,而不是将XSS视为移动设备上的威胁。 Cordova packages all assets into the install package so that's somewhat better but then why not take the same approach on the Desktop version? Cordova将所有资产打包到安装包中,这样有点好,但为什么不在桌面版上采用相同的方法呢?
My application takes very little user input, it is primarily a dashboard/reporting tool. 我的应用程序只需很少的用户输入,它主要是一个仪表板/报告工具。 There will be a "message center" but it's content should always be user-created (by only that user) and sanitized. 将有一个“消息中心”,但它的内容应始终由用户创建(仅由该用户创建)并进行消毒。 In my use-case then, would it be ok to deviate from "best practices" and rely on localStorage not counting XSS as a serious risk for my SPA? 在我的用例中,是否可以偏离“最佳实践”并依赖localStorage不计算XSS作为我的SPA的严重风险? This would simplify this entire thing (use HTML5 sessionStorage as originally planned) and reduce complexity, which would reduce attack surface for potential security blunders. 这将简化整个过程(按原计划使用HTML5 sessionStorage)并降低复杂性,这将减少潜在安全性失误的攻击面。 I just want to make sure I understand the risks before moving forward. 我只想确保在继续前进之前了解风险。
Is there no secure way to make this secure other than by building a native app for mobile and not using Cordova to convert my SPA to a mobile app? 除了通过构建移动本机应用程序而不是使用Cordova将我的SPA转换为移动应用程序之外,还有其他方法可以确保安全吗? I'd hate for this to be the case, but it might very well be. 我讨厌这种情况,但它可能很好。
I'd appreciate all thoughts on the matter! 我很感激所有关于此事的想法!
When thinking of designing javascript based cross-platform applications to run a mobile device, many of the caveats with designing regular web browser based applications do not necessarily apply. 在考虑设计基于javascript的跨平台应用程序来运行移动设备时,许多关于设计基于Web浏览器的常规应用程序的注意事项并不一定适用。
As far as security is concerned, whether you decide to use JWT or simple OAuth tokens, ensure that all your communications are via https. 就安全性而言,无论您决定使用JWT还是简单的OAuth令牌,都要确保所有通信都通过https进行。
Please use localStorage as much as you want. 请尽可能多地使用localStorage。 If you consider the anatomy of a http request, all it really is sending some text based message divided into multiple sections to a server. 如果你考虑一个http请求的解剖,它真的是发送一些基于文本的消息分成多个部分到服务器。 The header of the request is no more secure than any other part of it including the cookies. 请求的标头不比包括cookie在内的任何其他部分更安全。 So the points of interest from a security perspective are generation/validation/invalidation of the token, storage of the token on the device and the transport mechanism of the requests. 因此,从安全角度来看,兴趣点是令牌的生成/验证/无效,令牌在设备上的存储以及请求的传输机制。
How you store the token on the device is constrained to what the device OS make makes available to you. 如何将令牌存储在设备上受限于设备操作系统为您提供的功能。 Regarding whether using a native app is better than cross-platform, I think creating a native-cordova plugin to store your token using any specific native strategy if one is unsatisfied with the "out of the box" ones (such as local storage) is possible, although in my experience this is usually overkill. 关于使用本机应用程序是否优于跨平台应用程序,我认为创建一个native-cordova插件来使用任何特定的本机策略来存储您的令牌,如果对“开箱即用”(例如本地存储)不满意的话可能,虽然根据我的经验,这通常是矫枉过正。 Happy to be corrected on this one if anyone has a different experience. 如果有人有不同的经历,很高兴在这一个纠正。
Please use HTTPS ALWAYS without exception for ALL Webservice end point communications. 对于所有Web服务端点通信,请毫无例外地使用HTTPS ALWAYS。 Is HTTPS foolproof, NO, but you wouldn't build a house without a front door simply because dedicated burglars could learn to pick locks. HTTPS是万无一失的,不,但是你不会因为专门的窃贼可以学会选择锁来建造一个没有前门的房子。 This secures the transport mechanism considerably. 这大大保证了运输机制。
Usually, this is all native apps have to work with too anyway. 通常,无论如何,这都是本机应用程序必须使用的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.