Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Strong CSP Support #4943

Closed
wants to merge 85 commits into from
Closed
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
386245b
WIP Fix
dav-is Aug 10, 2018
1223ded
Merge branch 'canary' into canary
dav-is Aug 10, 2018
23012bc
Generate bootstrap.js
dav-is Aug 10, 2018
e5c1a51
Syntax
dav-is Aug 10, 2018
e18b1ad
Merge branch 'canary' of github.com:dav-is/next.js into canary
dav-is Aug 10, 2018
9531f55
Merge branch 'canary' into canary
dav-is Aug 27, 2018
b840984
Copy bootstrap.js instead of loading through webpack
dav-is Aug 28, 2018
9ec8c96
Cleanup
dav-is Aug 28, 2018
709fc5c
add a htmlescaped pathname
dav-is Aug 28, 2018
7e7092f
Fix Flow Error
dav-is Aug 28, 2018
986adfb
Remove hashes and nonces
dav-is Aug 28, 2018
9e7ee16
Minor fixes
dav-is Aug 28, 2018
f3eddab
Remove mentions of nonce/hash, add CSP to README.md
dav-is Aug 28, 2018
2c76ed9
Merge branch 'canary' into canary
dav-is Aug 28, 2018
178e4fe
Add Strict CSP Support//waiting for styled-jsx PR Merge
dav-is Aug 28, 2018
6e02af3
Merge branch 'canary' of github.com:dav-is/next.js into canary
dav-is Aug 28, 2018
27488ac
Merge branch 'canary' into canary
dav-is Aug 28, 2018
ea22175
Move setHeader logic to index.js, use nanoid
dav-is Aug 28, 2018
ae54cc6
Merge branch 'canary' of github.com:dav-is/next.js into canary
dav-is Aug 28, 2018
b1ba505
Fix eTags, if no policy dont set header, seamlessly insert nonce into…
dav-is Aug 28, 2018
b06f8ba
Fix CSP test
dav-is Aug 28, 2018
87d8b40
Whoops
dav-is Aug 28, 2018
ca2fff8
Merge branch 'canary' into canary
dav-is Aug 30, 2018
1865373
Merge branch 'canary' into canary
dav-is Aug 30, 2018
1066028
Merge branch 'canary' into canary
dav-is Aug 30, 2018
5ef8249
Add unsafeCSPMeta config option, move nonce code to this.render
dav-is Aug 30, 2018
3acf7a3
Merge branch 'canary' of github.com:dav-is/next.js into canary
dav-is Aug 30, 2018
de93117
Minor textual changes to README.md
dav-is Aug 30, 2018
f34704c
Merge branch 'canary' into canary
dav-is Aug 31, 2018
3aa6580
Fix HMR (WIP), check if static or not
dav-is Aug 31, 2018
d0d0288
Merge branch 'canary' into canary
dav-is Sep 4, 2018
d4ef249
Try fixing test
dav-is Sep 4, 2018
b728131
Merge branch 'canary' into canary
dav-is Sep 4, 2018
6ae263e
Run tests
dav-is Sep 4, 2018
f3cc533
Merge branch 'canary' of github.com:dav-is/next.js into canary
dav-is Sep 4, 2018
4b7688b
Fix tests?
dav-is Sep 4, 2018
6cf5d18
Merge branch 'canary' into canary
dav-is Sep 4, 2018
fb82831
Remove module={}
dav-is Sep 4, 2018
8f6a76f
Failing because styled-jsx PR isn't merged yet
dav-is Sep 4, 2018
a83d16c
Don't use inline styles for error pages, this change didn't work...
dav-is Sep 5, 2018
fe088b2
Merge branch 'canary' into canary
dav-is Sep 5, 2018
077d5a0
Merge branch 'canary' into canary
dav-is Sep 6, 2018
5d5643a
Fix tests, add note about error page
dav-is Sep 7, 2018
e09a1e7
Merge branch 'canary' of github.com:dav-is/next.js into canary
dav-is Sep 7, 2018
8343a93
Merge branch 'canary' into canary
dav-is Sep 7, 2018
96fc0cc
Minor fix, upgrade styled-jsx version - pending release
dav-is Sep 10, 2018
75227c3
Merge branch 'canary' of github.com:dav-is/next.js into canary
dav-is Sep 10, 2018
0c67bcd
Merge branch 'canary' into canary
dav-is Sep 24, 2018
cb76f38
Minify bootstrap.js
dav-is Sep 24, 2018
657d4e0
New dataloading technique, remove bootstrap.js
dav-is Sep 25, 2018
632d0e4
Merge branch 'canary' into canary
dav-is Sep 25, 2018
6167a49
Update package.json
dav-is Sep 26, 2018
c46ec20
Merge branch 'canary' into canary
dav-is Sep 26, 2018
1b50af9
Fixes
dav-is Sep 26, 2018
8898e59
Merge branch 'canary' of github.com:dav-is/next.js into canary
dav-is Sep 26, 2018
68741ef
Linter fixes
dav-is Sep 26, 2018
4f6c8dc
Use Proxy object instead of overriding prototype
dav-is Sep 26, 2018
6d5ab37
Get webpack page plugin to work
dav-is Sep 26, 2018
2c85d20
Sync with origin
dav-is Dec 4, 2018
c584de5
Reapply changes to updated branch
dav-is Dec 5, 2018
db4b51c
Merge branch 'canary' into canary
dav-is Dec 5, 2018
4ec0e01
Use classname for error-overlay
dav-is Dec 5, 2018
8a6de18
Merge branch 'canary' of github.com:dav-is/next.js into canary
dav-is Dec 5, 2018
96c2040
Define styles in js instead of jsx
dav-is Dec 5, 2018
cd718cc
Cleanup variables
dav-is Dec 5, 2018
56bd0e5
Remove AutoDll plugin to avoid unsafe-eval, fix typo in _doc
dav-is Dec 5, 2018
0bbdd3d
Fix tests
dav-is Dec 5, 2018
d8cd11c
Fix #5674
dav-is Dec 5, 2018
ba45a21
Fix tests because NEXT_DATA doesn't need crossOrigin and nonce attrib…
dav-is Dec 5, 2018
5d2c75b
Azure failed, is it because of a trailing slash?
dav-is Dec 6, 2018
d1017f8
Merge branch 'canary' into canary
dav-is Dec 6, 2018
fd2300a
Debug why Azure is failing tests
dav-is Dec 6, 2018
dfe452c
Merge branch 'canary' into canary
dav-is Dec 6, 2018
3c42323
No more default CSP, README is more clear, all integration tests use CSP
dav-is Dec 11, 2018
5697389
Merge branch 'canary' of github.com:dav-is/next.js into canary
dav-is Dec 11, 2018
9f9d2c4
Sync with upstream
dav-is Dec 11, 2018
98509ca
Merge branch 'canary' into canary
dav-is Dec 11, 2018
15cf4f4
Fix ETags and remove unused dep
dav-is Dec 11, 2018
bbd7306
Merge branch 'canary' of github.com:dav-is/next.js into canary
dav-is Dec 11, 2018
eaa0672
Merge branch 'canary' into canary
dav-is Dec 12, 2018
8fea414
Readme edits
dav-is Dec 12, 2018
3608c1a
Merge branch 'canary' of github.com:dav-is/next.js into canary
dav-is Dec 13, 2018
abfaa78
Remove crossOrigin PR
dav-is Dec 13, 2018
247aa1d
Merge remote-tracking branch 'upstream/canary' into canary
dav-is Dec 13, 2018
cf30cb6
Remove inline styles from _error.js and error-debug.js
dav-is Dec 13, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Next.js is a minimalistic framework for server-rendered React applications.
- [Reusing the built-in error page](#reusing-the-built-in-error-page)
- [Custom configuration](#custom-configuration)
- [Setting a custom build directory](#setting-a-custom-build-directory)
- [Content Security Policy](#content-security-policy)
- [Disabling etag generation](#disabling-etag-generation)
- [Configuring the onDemandEntries](#configuring-the-ondemandentries)
- [Configuring extensions looked for when resolving pages in `pages`](#configuring-extensions-looked-for-when-resolving-pages-in-pages)
Expand Down Expand Up @@ -1175,6 +1176,19 @@ module.exports = {
}
```

#### Content Security Policy

Next.js supports [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP). You can set your CSP Poliy in your Next.js configuration.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's no need to Policy after CSP.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You’re right. That’s left over from before when there were more variables set on the key “CSP” so there was CSP.policy, and CSP.nonce, etc

I need to go through and rewrite the README too I just haven’t had much time lately


```js
// next.config.js
module.exports = {
cspPolicy: "default-src 'self';"
}
```

Node: In order to support dynamic styles nodejs uses a `nonce` for `style-src`. This is done automatically. If you use a different CSS-in-JS library, you can use the `cspNonce` document parameter to get the nonce set in the header.

#### Disabling etag generation

You can disable etag generation for HTML pages depending on your cache strategy. If no configuration is specified then Next will generate etags for every page.
Expand Down
10 changes: 8 additions & 2 deletions build/webpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ import PagesManifestPlugin from './webpack/plugins/pages-manifest-plugin'
import BuildManifestPlugin from './webpack/plugins/build-manifest-plugin'
import ChunkNamesPlugin from './webpack/plugins/chunk-names-plugin'
import { ReactLoadablePlugin } from './webpack/plugins/react-loadable-plugin'
import {SERVER_DIRECTORY, NEXT_PROJECT_ROOT, NEXT_PROJECT_ROOT_NODE_MODULES, NEXT_PROJECT_ROOT_DIST, DEFAULT_PAGES_DIR, REACT_LOADABLE_MANIFEST, CLIENT_STATIC_FILES_RUNTIME_WEBPACK, CLIENT_STATIC_FILES_RUNTIME_MAIN} from '../lib/constants'
import {SERVER_DIRECTORY, NEXT_PROJECT_ROOT, NEXT_PROJECT_ROOT_NODE_MODULES, NEXT_PROJECT_ROOT_DIST, DEFAULT_PAGES_DIR, REACT_LOADABLE_MANIFEST, CLIENT_STATIC_FILES_RUNTIME_PATH, CLIENT_STATIC_FILES_RUNTIME_WEBPACK, CLIENT_STATIC_FILES_RUNTIME_MAIN} from '../lib/constants'
import AutoDllPlugin from 'autodll-webpack-plugin'
import CopyWebpackPlugin from 'copy-webpack-plugin'

// The externals config makes sure that
// on the server side when modules are
Expand Down Expand Up @@ -254,7 +255,12 @@ export default async function getBaseWebpackConfig (dir: string, {dev = false, i
!isServer && new BuildManifestPlugin(),
!isServer && new PagesPlugin(),
isServer && new NextJsSsrImportPlugin(),
isServer && new NextJsSSRModuleCachePlugin({outputPath})
isServer && new NextJsSSRModuleCachePlugin({outputPath}),
!isServer && new CopyWebpackPlugin([{
from: path.join(NEXT_PROJECT_ROOT_DIST, 'client', 'bootstrap.js'),
to: CLIENT_STATIC_FILES_RUNTIME_PATH,
cache: true
}])
].filter(Boolean)
}

Expand Down
17 changes: 17 additions & 0 deletions client/bootstrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
window.module = {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this is still needed with the latest webpack, it might not be needed anymore

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing it breaks everything.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed here: #5093

window.__NEXT_DATA__ = JSON.parse(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be done in client/index.js right 🤔

Copy link
Contributor Author

@dav-is dav-is Aug 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. There’s a function appended to the beginning of each page.js and they load async so they could be called at any moment. This means that these functions need to be defined before any other scripts are loaded, which is only possible by loading it first as the client/index.js could be loaded third and two pages have loaded first and there’s no function to register them.

Also, module={} has to be defined before any webpack files load as they begin with module.exports and will say module is undefined. I’m guessing these are all the hoops you had to jump through to get asynchronous loading working.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

window.__NEXT_DATA__ = JSON.parse(

I meant reading the __NEXT_DATA__, the rest still has to be defined beforehand like you said.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

document
.getElementById('server-app-state')
.textContent.replace(/%3C\/script%3E/g, '</script>')
)
window.__NEXT_LOADED_PAGES__ = []
window.__NEXT_REGISTER_PAGE = function (route, fn) {
window.__NEXT_LOADED_PAGES__.push({ route: route, fn: fn })
}
if (window.__NEXT_DATA__.page === '_error') {
window.__NEXT_REGISTER_PAGE(window.__NEXT_DATA__.cleanPathname, function () {
var error = new Error(`Page does not exist: ${window.__NEXT_DATA__.cleanPathname}`)
error.statusCode = 404
return { error: error }
})
}
48 changes: 0 additions & 48 deletions examples/with-strict-csp-hash/README.md

This file was deleted.

15 changes: 0 additions & 15 deletions examples/with-strict-csp-hash/package.json

This file was deleted.

26 changes: 0 additions & 26 deletions examples/with-strict-csp-hash/pages/_document.js

This file was deleted.

3 changes: 0 additions & 3 deletions examples/with-strict-csp-hash/pages/index.js

This file was deleted.

46 changes: 0 additions & 46 deletions examples/with-strict-csp/README.md

This file was deleted.

31 changes: 0 additions & 31 deletions examples/with-strict-csp/csp.js

This file was deleted.

17 changes: 0 additions & 17 deletions examples/with-strict-csp/package.json

This file was deleted.

28 changes: 0 additions & 28 deletions examples/with-strict-csp/pages/_document.js

This file was deleted.

3 changes: 0 additions & 3 deletions examples/with-strict-csp/pages/index.js

This file was deleted.

22 changes: 0 additions & 22 deletions examples/with-strict-csp/server.js

This file was deleted.

3 changes: 3 additions & 0 deletions flow-typed/npm/copy-webpack-plugin_vx.x.x.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module 'copy-webpack-plugin' {
declare module.exports: any;
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"babel-plugin-react-require": "3.0.0",
"babel-plugin-transform-react-remove-prop-types": "0.4.13",
"case-sensitive-paths-webpack-plugin": "2.1.2",
"copy-webpack-plugin": "4.5.2",
"cross-spawn": "5.1.0",
"del": "3.0.0",
"etag": "1.8.1",
Expand Down
2 changes: 2 additions & 0 deletions server/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export type NextConfig = {|
distDir: string,
assetPrefix: string,
configOrigin: string,
cspPolicy: null | string,
useFileSystemPublicRoutes: boolean,
generateBuildId: () => string,
generateEtags: boolean,
Expand All @@ -26,6 +27,7 @@ const defaultConfig: NextConfig = {
distDir: '.next',
assetPrefix: '',
configOrigin: 'default',
cspPolicy: null,
useFileSystemPublicRoutes: true,
generateBuildId: () => {
// nanoid is a small url-safe uuid generator
Expand Down
Loading