Skip to content

Commit ed4d0a8

Browse files
committed
update node packages
- update aspnet-prerendering package from 1.0.x to latest 3.0.1 - fixed code that breaks after using aspnet-prerendering 3.0.1 - added a section about XSS - updated renderOnServer.js with XSS prevention code
1 parent 210d599 commit ed4d0a8

File tree

4 files changed

+75
-28
lines changed

4 files changed

+75
-28
lines changed

ClientApp/renderOnServer.js

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,22 @@ const path = require('path')
66
const filePath = path.join(__dirname, '../wwwroot/dist/main-server.js')
77
const code = fs.readFileSync(filePath, 'utf8')
88

9-
const bundleRenderer = require('vue-server-renderer').createBundleRenderer(code)
9+
var prerendering = require('aspnet-prerendering')
1010

11-
module.exports = function (params) {
12-
return new Promise(function (resolve, reject) {
13-
const context = {
14-
url: params.url
15-
}
11+
//prevent XSS attack when initialize state
12+
var serialize = require('serialize-javascript')
1613

17-
bundleRenderer.renderToString(context, (err, resultHtml) => {
18-
if (err) {
19-
reject(err.message)
14+
module.exports = prerendering.createServerRenderer(function (params) {
15+
return new Promise(
16+
function (resolve, reject) {
17+
const context = {
18+
url: params.url,
19+
xss: serialize("</script><script>alert('Possible XSS vulnerability from user input!')</script>")
2020
}
2121
resolve({
22-
html: resultHtml,
2322
globals: {
24-
__INITIAL_STATE__: context.state
23+
__INITIAL_STATE__: context
2524
}
2625
})
27-
})
2826
})
29-
}
27+
});

README.md

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ To simulate timely API call form remote server, we add the following line in Hom
9999
- webpack-merge
100100
- dependencies:
101101
- vue-server-renderer
102-
- aspnet-prerenderer *(Note that only version ^1.0.0 is supported, using latest ^3.0.0+ will break the code.)*
102+
- aspnet-prerenderer
103103

104104
2. Split the code into two part:
105105

@@ -130,4 +130,52 @@ Using Bootstrap in VueJS application is easy with BootstrapVue:
130130
- Import the css files: (tricky here, for this repo I need to add the imports at client.js instead of app.js)
131131
import 'bootstrap/dist/css/bootstrap.css'
132132
import 'boostrap-vue/dist/bootstrap-vue.css'
133-
- Add the Bootstrap components (e.g. I added a badge at Dashboard.vue template.)
133+
- Add the Bootstrap components (e.g. I added a badge at Dashboard.vue template.)
134+
135+
### Prevent XSS Attack:
136+
During the jounary in solveing the asp-prerendering v3.0.0+ dependency issue, I found an article talking about Cross-site scripting attack in JavaScript applications: *[The Most Common XSS Vulnerability in React.js Applications](https://medium.com/node-security/the-most-common-xss-vulnerability-in-react-js-applications-2bdffbcc1fa0)* And turns out rednerOnServer.js also has such vulnerability.
137+
138+
module.exports = prerendering.createServerRenderer(function (params) {
139+
return new Promise(
140+
function (resolve, reject) {
141+
const context = {
142+
url: params.url,
143+
xss:"</script><script>alert('Possible XSS vulnerability from user input!')</script>"
144+
}
145+
resolve({
146+
globals: {
147+
__INITIAL_STATE__: context
148+
}
149+
})
150+
})
151+
});
152+
153+
If we modify the renderOnServer.js as above, an alert will be shown when we load the page from browser. This will potentially enable attacker to execute arbitary code. To fix this vulnerability, we can make use of `serialize-javascript` package from Yahoo engineers and cleanse all initial state assignment from user input:
154+
155+
npm install --save serialize-javascript
156+
157+
and serialize the initial state like this:
158+
159+
//prevent XSS attack when initialize state
160+
var serialize = require('serialize-javascript')
161+
162+
module.exports = prerendering.createServerRenderer(function (params) {
163+
return new Promise(
164+
function (resolve, reject) {
165+
const context = {
166+
url: params.url,
167+
xss: serialize("</script><script>alert('Possible XSS vulnerability from user input!')</script>")
168+
}
169+
resolve({
170+
globals: {
171+
__INITIAL_STATE__: context
172+
}
173+
})
174+
})
175+
});
176+
177+
and when you inspect the HTML from browser you will see the tags are escaped:
178+
179+
window.__INITIAL_STATE__ = {"url":"/","xss":"\"\\u003C\\u002Fscript\\u003E\\u003Cscript\\u003Ealert('Possible XSS vulnerability from user input!')\\u003C\\u002Fscript\\u003E\""};
180+
181+
Cheers. :smirk:

Startup.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ public Startup(IConfiguration configuration)
2323
public void ConfigureServices(IServiceCollection services)
2424
{
2525
services.AddMvc();
26+
// services.AddNodeServices();
2627
}
2728

2829
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
2930
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory factory)
3031
{
31-
factory.AddConsole();
32+
// factory.AddConsole();
3233

3334
if (env.IsDevelopment())
3435
{

package.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,28 @@
1010
"license": "MIT",
1111
"private": true,
1212
"dependencies": {
13-
"aspnet-prerendering": "^1.0.1",
14-
"axios": "^0.17.1",
15-
"bootstrap": "^4.0.0-beta.2",
16-
"bootstrap-vue": "^1.3.0",
13+
"aspnet-prerendering": "3.0.1",
14+
"axios": "^0.18.0",
15+
"bootstrap-vue": "^2.0.0-rc.2",
1716
"lodash": "^4.17.4",
1817
"nprogress": "^0.2.0",
19-
"vue": "^2.5.9",
18+
"serialize-javascript": "^1.4.0",
19+
"vue": "^2.5.13",
2020
"vue-router": "^3.0.1",
21-
"vue-server-renderer": "^2.5.9",
21+
"vue-server-renderer": "^2.5.13",
2222
"vuex": "^3.0.1"
2323
},
2424
"devDependencies": {
25-
"aspnet-webpack": "^2.0.1",
25+
"aspnet-webpack": "^2.0.3",
2626
"babel-core": "^6.26.0",
27-
"babel-loader": "^7.1.2",
27+
"babel-loader": "^7.1.4",
2828
"babel-preset-es2015": "^6.24.1",
2929
"babel-preset-stage-2": "^6.24.1",
30-
"vue-loader": "^13.5.0",
31-
"vue-template-compiler": "^2.5.9",
32-
"css-loader": "^0.28.7",
30+
"vue-loader": "^14.2.1",
31+
"vue-template-compiler": "^2.5.13",
32+
"css-loader": "^0.28.10",
3333
"json-loader": "^0.5.7",
34-
"style-loader": "^0.19.0",
34+
"style-loader": "^0.20.2",
3535
"webpack": "^3.8.1",
3636
"webpack-hot-middleware": "^2.21.0",
3737
"webpack-merge": "^4.1.1"

0 commit comments

Comments
 (0)