From 4893fe048c556a196c146b074fc2fb45b55734df Mon Sep 17 00:00:00 2001 From: Emily Stark Date: Tue, 13 Aug 2013 21:50:45 -0700 Subject: [PATCH 1/4] Package for security-related http headers. --- docs/client/docs.js | 4 +- docs/client/packages.html | 2 + docs/client/packages/browser-policy.html | 126 +++++++++++ .../packages/starter-browser-policy.html | 25 +++ packages/browser-policy/.gitignore | 1 + packages/browser-policy/browser-policy.js | 200 ++++++++++++++++++ packages/browser-policy/package.js | 9 + packages/starter-browser-policy/.gitignore | 1 + packages/starter-browser-policy/package.js | 8 + .../starter-browser-policy.js | 13 ++ packages/webapp/webapp_server.js | 40 +++- tools/app.html.in | 4 +- 12 files changed, 419 insertions(+), 14 deletions(-) create mode 100644 docs/client/packages/browser-policy.html create mode 100644 docs/client/packages/starter-browser-policy.html create mode 100644 packages/browser-policy/.gitignore create mode 100644 packages/browser-policy/browser-policy.js create mode 100644 packages/browser-policy/package.js create mode 100644 packages/starter-browser-policy/.gitignore create mode 100644 packages/starter-browser-policy/package.js create mode 100644 packages/starter-browser-policy/starter-browser-policy.js diff --git a/docs/client/docs.js b/docs/client/docs.js index c057ef71bd..036ed23c89 100644 --- a/docs/client/docs.js +++ b/docs/client/docs.js @@ -344,7 +344,9 @@ var toc = [ "spiderable", "stylus", "showdown", - "underscore" + "underscore", + "browser-policy", + "starter-browser-policy" ] ], "Command line", [ [ diff --git a/docs/client/packages.html b/docs/client/packages.html index 0ee701bbe8..ac344171cd 100644 --- a/docs/client/packages.html +++ b/docs/client/packages.html @@ -32,6 +32,8 @@ and removed with: {{> pkg_stylus}} {{> pkg_showdown}} {{> pkg_underscore}} +{{> pkg_browser_policy}} +{{> pkg_starter_browser_policy}} {{/better_markdown}} diff --git a/docs/client/packages/browser-policy.html b/docs/client/packages/browser-policy.html new file mode 100644 index 0000000000..b2da7d5117 --- /dev/null +++ b/docs/client/packages/browser-policy.html @@ -0,0 +1,126 @@ + diff --git a/docs/client/packages/browser-policy.html b/docs/client/packages/browser-policy.html index b2da7d5117..efc4c2c275 100644 --- a/docs/client/packages/browser-policy.html +++ b/docs/client/packages/browser-policy.html @@ -16,12 +16,13 @@ attacks. tells the browser where your app can load content from, which encourages safe practices and mitigates the damage of a cross-site-scripting attack. -For most apps, we recommend that you use the `starter-browser-policy` package to -enable reasonable policies, and then use the functions below to tighten or relax -the policies as necessary. For example, an app that only loads content from its -own origin and that doesn't use inline Javascript should use -`starter-browser-policy` and then call `BrowserPolicy.disallowInlineScripts()` -to gain additional security against cross-site scripting attacks. +For most apps, we recommend that you use the +[`starter-browser-policy`](#starterbrowserpolicy) package to enable reasonable +policies, and then use the functions below to tighten or relax the policies as +necessary. For example, an app that only loads content from its own origin and +that doesn't use inline Javascript should use `starter-browser-policy` and then +call `BrowserPolicy.disallowInlineScripts()` to gain additional security against +cross-site scripting attacks. You can use the following functions to specify which websites are allowed to frame your app: @@ -31,10 +32,11 @@ Your app will never render inside a frame or iframe. {{/dtdd}} {{#dtdd "BrowserPolicy.allowFramingByOrigin(origin)"}} -Your app will only render inside frames loaded by `origin` (such as -http://meteor.com). You can only call this function once with a single origin, -and cannot specify multiple origins that are allowed to frame your app. (This is -a limitation of the X-Frame-Options header.) +Your app will only render inside frames loaded by `origin`. You can only call +this function once with a single origin, and cannot use wildcards or specify +multiple origins that are allowed to frame your app. (This is a limitation of +the X-Frame-Options header.) Example values of `origin` include +"http://example.com" and "https://foo.example.com". {{/dtdd}} {{#dtdd "BrowserPolicy.allowFramingBySameOrigin()"}} @@ -79,17 +81,7 @@ Disallows inline CSS. Finally, you can configure a whitelist of allowed requests that various types of -content can make. Examples: - -* `BrowserPolicy.disallowObject()` causes the browser to disallow all -`` tags. -* `BrowserPolicy.allowImageOrigin("https://example.com")` -allows images to have their `src` attributes point to images served from -`https://example.com`. -* `BrowserPolicy.allowConnectOrigin("https://example.com")` allows XMLHttpRequest -and WebSocket connections to `https://example.com`. - -The following functions are defined for the content types +content can make. The following functions are defined for the content types script, object, image, media, font, and connect.
@@ -122,5 +114,16 @@ app's origin but you want to disable `` tags, you can simply call `BrowserPolicy.allowAllContentSameOrigin()` followed by `BrowserPolicy.disallowObject()`. +Other examples of using the `BrowserPolicy` API: + +* `BrowserPolicy.disallowObject()` causes the browser to disallow all +`` tags. +* `BrowserPolicy.allowImageOrigin("https://example.com")` +allows images to have their `src` attributes point to images served from +`https://example.com`. +* `BrowserPolicy.allowConnectOrigin("https://example.com")` allows XMLHttpRequest +and WebSocket connections to `https://example.com`. + + {{/better_markdown}} diff --git a/docs/client/packages/starter-browser-policy.html b/docs/client/packages/starter-browser-policy.html index bb1118fc0d..71ff88911a 100644 --- a/docs/client/packages/starter-browser-policy.html +++ b/docs/client/packages/starter-browser-policy.html @@ -2,10 +2,10 @@ {{#better_markdown}} ## `starter-browser-policy` -The `starter-browser-policy` package provides a recommended configuration for the -`browser-policy` package. When you add `starter-browser-policy` to your app, the -following policies will be enforced by browsers that support the X-Frame-Options -and Content-Security-Policy headers: +The `starter-browser-policy` package provides a recommended configuration for +the [`browser-policy`](#browserpolicy) package. When you add +`starter-browser-policy` to your app, the following policies will be enforced by +browsers that support the X-Frame-Options and Content-Security-Policy headers: * Only webpages on the same origin as your app can frame your app. * Your app can only load content (images, scripts, fonts, etc.) from its own diff --git a/packages/browser-policy/browser-policy.js b/packages/browser-policy/browser-policy.js index 3d9d8e330c..5f54c8d6d3 100644 --- a/packages/browser-policy/browser-policy.js +++ b/packages/browser-policy/browser-policy.js @@ -81,6 +81,7 @@ var removeCspSrc = function (directive, src) { }; var ensureDirective = function (directive) { + cspSrcs = cspSrcs || {}; if (! _.has(cspSrcs, directive)) cspSrcs[directive] = []; }; diff --git a/packages/webapp/package.js b/packages/webapp/package.js index 0f89553822..c451f2086a 100644 --- a/packages/webapp/package.js +++ b/packages/webapp/package.js @@ -12,6 +12,9 @@ Package.on_use(function (api) { api.use(['application-configuration'], { unordered: true }); + api.use(['browser-policy'], { + unordered: true + }); api.export(['WebApp', 'main', 'WebAppInternals'], 'server'); api.add_files('webapp_server.js', 'server'); }); From a102872a963e367962f91291a37b0fff7df1e38e Mon Sep 17 00:00:00 2001 From: Emily Stark Date: Tue, 10 Sep 2013 17:08:42 -0700 Subject: [PATCH 3/4] Rework browser-policy to make API more intuitive. - Remove starter-browser-policy and replace it with BrowserPolicy.enableContentSecurityPolicy(), which gives you the starter policy and allows you to use the other BrowserPolicy functions to configure it. This is motivated by the fact that the API isn't very intuitive without a well-defined starting policy. ex: if the package starts off without a policy, and then the user calls allowAllContentSameOrigin(), that will result in turning off inline scripts, which is probably not what they wanted. - AllContent functions do more of what you'd expect now; i.e. BrowserPolicy.disallowAllContent() actually disallows all content, instead of setting default-src to 'none', which will allow other types of content that have previously had srcs set for them. - Add some tests --- docs/client/docs.js | 1 - docs/client/packages.html | 1 - docs/client/packages/browser-policy.html | 53 +++++-- .../packages/starter-browser-policy.html | 25 --- .../browser-policy/browser-policy-test.js | 123 +++++++++++++++ packages/browser-policy/browser-policy.js | 148 +++++++++++++----- packages/browser-policy/package.js | 5 + packages/starter-browser-policy/.gitignore | 1 - packages/starter-browser-policy/package.js | 8 - .../starter-browser-policy.js | 13 -- 10 files changed, 277 insertions(+), 101 deletions(-) delete mode 100644 docs/client/packages/starter-browser-policy.html create mode 100644 packages/browser-policy/browser-policy-test.js delete mode 100644 packages/starter-browser-policy/.gitignore delete mode 100644 packages/starter-browser-policy/package.js delete mode 100644 packages/starter-browser-policy/starter-browser-policy.js diff --git a/docs/client/docs.js b/docs/client/docs.js index dc489c7cb5..3ac001e554 100644 --- a/docs/client/docs.js +++ b/docs/client/docs.js @@ -345,7 +345,6 @@ var toc = [ "spiderable", "stylus", "showdown", - "starter-browser-policy", "underscore" ] ], diff --git a/docs/client/packages.html b/docs/client/packages.html index c891bbc5cd..077e4f1cd1 100644 --- a/docs/client/packages.html +++ b/docs/client/packages.html @@ -32,7 +32,6 @@ and removed with: {{> pkg_spiderable}} {{> pkg_stylus}} {{> pkg_showdown}} -{{> pkg_starter_browser_policy}} {{> pkg_underscore}} {{/better_markdown}} diff --git a/docs/client/packages/browser-policy.html b/docs/client/packages/browser-policy.html index efc4c2c275..5b8e31354e 100644 --- a/docs/client/packages/browser-policy.html +++ b/docs/client/packages/browser-policy.html @@ -16,13 +16,26 @@ attacks. tells the browser where your app can load content from, which encourages safe practices and mitigates the damage of a cross-site-scripting attack. -For most apps, we recommend that you use the -[`starter-browser-policy`](#starterbrowserpolicy) package to enable reasonable -policies, and then use the functions below to tighten or relax the policies as -necessary. For example, an app that only loads content from its own origin and -that doesn't use inline Javascript should use `starter-browser-policy` and then -call `BrowserPolicy.disallowInlineScripts()` to gain additional security against -cross-site scripting attacks. +For most apps, we recommend that you take the following steps when using +`browser-policy`: + +* Call `BrowserPolicy.enableContentSecurityPolicy()` to enable a starter policy +for your app. With this starter policy, your app's client code will be able to +load content (images, scripts, fonts, etc.) only from its own origin, except +that XMLHttpRequests and WebSocket connections can go to any origin. Further, +your app's client code will not be able to use functions such as `eval()` that +convert strings to code. +* You can use the functions described below to customize the content +security policy. If your app does not need any inline Javascript such as inline +`