Browse Source

Fix XSS.

master
Tian Yunhao 6 years ago
parent
commit
870d8c3af5
  1. 2
      app.js
  2. 5
      package.json
  3. 2
      views/admin_links.ejs
  4. 2
      views/admin_raw.ejs
  5. 2
      views/forget_confirm.ejs
  6. 2
      views/index.ejs
  7. 2
      views/login.ejs
  8. 4
      views/problem.ejs
  9. 2
      views/problem_data.ejs
  10. 2
      views/ranklist.ejs
  11. 4
      views/sign_up.ejs
  12. 6
      views/statistics.ejs
  13. 18
      views/submission.ejs
  14. 6
      views/submissions.ejs
  15. 6
      views/submissions_item.ejs

2
app.js

@ -1,5 +1,6 @@
let fs = require('fs'), let fs = require('fs'),
path = require('path'); path = require('path');
const serializejs = require('serialize-javascript');
const commandLineArgs = require('command-line-args'); const commandLineArgs = require('command-line-args');
const optionDefinitions = [ const optionDefinitions = [
@ -52,6 +53,7 @@ global.syzoj = {
// Use cookie parser // Use cookie parser
app.use(require('cookie-parser')()); app.use(require('cookie-parser')());
app.locals.serializejs = serializejs;
let multer = require('multer'); let multer = require('multer');
app.multer = multer({ dest: syzoj.utils.resolvePath(syzoj.config.upload_dir, 'tmp') }); app.multer = multer({ dest: syzoj.utils.resolvePath(syzoj.config.upload_dir, 'tmp') });

5
package.json

@ -43,12 +43,12 @@
"jsondiffpatch": "0.2.5", "jsondiffpatch": "0.2.5",
"jsonwebtoken": "^8.4.0", "jsonwebtoken": "^8.4.0",
"katex": "^0.10.0", "katex": "^0.10.0",
"mariadb": "^2.0.2-rc",
"mathjax-node": "^2.1.1", "mathjax-node": "^2.1.1",
"moemark": "^0.3.10", "moemark": "^0.3.10",
"moment": "^2.23.0", "moment": "^2.24.0",
"msgpack-lite": "^0.1.26", "msgpack-lite": "^0.1.26",
"multer": "^1.2.0", "multer": "^1.2.0",
"mariadb": "^2.0.2-rc",
"node-7z": "^0.4.0", "node-7z": "^0.4.0",
"nodemailer": "^4.7.0", "nodemailer": "^4.7.0",
"object-assign-deep": "^0.4.0", "object-assign-deep": "^0.4.0",
@ -58,6 +58,7 @@
"request-promise": "^4.1.1", "request-promise": "^4.1.1",
"sendmail": "^1.1.1", "sendmail": "^1.1.1",
"sequelize": "^5.0.0-beta.15", "sequelize": "^5.0.0-beta.15",
"serialize-javascript": "^1.6.1",
"session-file-store": "^1.0.0", "session-file-store": "^1.0.0",
"socket.io": "^2.2.0", "socket.io": "^2.2.0",
"stream-to-string": "^1.1.0", "stream-to-string": "^1.1.0",

2
views/admin_links.ejs

@ -62,7 +62,7 @@ this.adminPage = 'links';
</form> </form>
<script> <script>
var links = <%- JSON.stringify(links) %>; var links = <%- serializejs(links) %>;
$('.remove_link').click(function () { $('.remove_link').click(function () {
links.splice($(this).data('id'), 1); links.splice($(this).data('id'), 1);
$('#submit_data').val(JSON.stringify(links)); $('#submit_data').val(JSON.stringify(links));

2
views/admin_raw.ejs

@ -3,7 +3,7 @@
<form method="post" class="ui form"> <form method="post" class="ui form">
<div id="editor" style="border: 1px solid #D4D4D5; height: 500px; margin-bottom: 20px; "></div> <div id="editor" style="border: 1px solid #D4D4D5; height: 500px; margin-bottom: 20px; "></div>
<script>$('#editor').text(<%- JSON.stringify(data) %>)</script> <script>$('#editor').text(<%- serializejs(data) %>)</script>
<input type="hidden" name="data"> <input type="hidden" name="data">
<script src="<%- lib('ace/1.4.2/ace.js') %>"></script> <script src="<%- lib('ace/1.4.2/ace.js') %>"></script>

2
views/forget_confirm.ejs

@ -50,7 +50,7 @@ function submitForm() {
url: "/api/reset_password", url: "/api/reset_password",
type: 'POST', type: 'POST',
data: { data: {
"token": <%- JSON.stringify(token) %>, "token": <%- serializejs(token) %>,
"password": password "password": password
}, },
async: true, async: true,

2
views/index.ejs

@ -56,7 +56,7 @@
<td style="font-content"> <td style="font-content">
<script id="user-infomation-script-<%= i %>"> <script id="user-infomation-script-<%= i %>">
(function () { (function () {
var html = <%- JSON.stringify(user.information) %>; var html = <%- serializejs(user.information) %>;
var elem = document.createElement('div'); var elem = document.createElement('div');
elem.style = 'overflow: hidden; width: 100%; position: relative; '; elem.style = 'overflow: hidden; width: 100%; position: relative; ';
elem.style.maxHeight = lineHeight + 'px'; elem.style.maxHeight = lineHeight + 'px';

2
views/login.ejs

@ -50,7 +50,7 @@ function show_error(error) {
$("#error").show(); $("#error").show();
} }
function success(session_id) { function success(session_id) {
window.location.href = location.protocol + '//' + location.host + <%- JSON.stringify(req.query.url || '/') %>; window.location.href = location.protocol + '//' + location.host + <%- serializejs(req.query.url || '/') %>;
} }
function login() { function login() {
password = md5($("#password").val() + "syzoj2_xxx"); password = md5($("#password").val() + "syzoj2_xxx");

4
views/problem.ejs

@ -237,7 +237,7 @@ div[class*=ace_br] {
} }
%> %>
<script> <script>
var cases = <%- JSON.stringify(cases) %>, currCase = 0; var cases = <%- serializejs(cases) %>, currCase = 0;
</script> </script>
<div class="ui grid"> <div class="ui grid">
<% if (testcases) { %> <% if (testcases) { %>
@ -325,7 +325,7 @@ div[class*=ace_br] {
</div> </div>
<div class="twelve wide stretched column" style="padding-left: 0; margin-left: calc(-1rem - 1px); width: calc(75% + 1rem + 1px + 25px) !important; "> <div class="twelve wide stretched column" style="padding-left: 0; margin-left: calc(-1rem - 1px); width: calc(75% + 1rem + 1px + 25px) !important; ">
<div id="editor" style="border: 1px solid #D4D4D5; "></div> <div id="editor" style="border: 1px solid #D4D4D5; "></div>
<% if (state) { %><script>$('#editor').text(<%- JSON.stringify(state.code) %>)</script><% } %> <% if (state) { %><script>$('#editor').text(<%- serializejs(state.code) %>)</script><% } %>
</div> </div>
<div class="inline fields" style="width: 100%; "> <div class="inline fields" style="width: 100%; ">
<div class="field" style="margin: 0 auto; "> <div class="field" style="margin: 0 auto; ">

2
views/problem_data.ejs

@ -145,7 +145,7 @@ function getIcon(filename) {
</div> </div>
<script> <script>
function check_replace() { function check_replace() {
var old_files = <%- JSON.stringify((testdata && testdata.files ? testdata.files : []).map(function(x) { return x.filename; })) %>; var old_files = <%- serializejs((testdata && testdata.files ? testdata.files : []).map(function(x) { return x.filename; })) %>;
var replaced_files = Array.prototype.slice.call($('#upload_file')[0].files).map(function (x) { return x.name; }).filter(function (x) { return old_files.includes(x); }); var replaced_files = Array.prototype.slice.call($('#upload_file')[0].files).map(function (x) { return x.name; }).filter(function (x) { return old_files.includes(x); });
var s = ''; var s = '';
for (let file of replaced_files) s += '<samp>' + file + '</samp><br>'; for (let file of replaced_files) s += '<samp>' + file + '</samp><br>';

2
views/ranklist.ejs

@ -42,7 +42,7 @@
<td class="font-content"> <td class="font-content">
<script id="user-infomation-script-<%= i %>"> <script id="user-infomation-script-<%= i %>">
(function () { (function () {
var html = <%- JSON.stringify(user.information) %>; var html = <%- serializejs(user.information) %>;
var elem = document.createElement('div'); var elem = document.createElement('div');
elem.style = 'overflow: hidden; width: 100%; position: relative; '; elem.style = 'overflow: hidden; width: 100%; position: relative; ';
elem.style.maxHeight = lineHeight + 'px'; elem.style.maxHeight = lineHeight + 'px';

4
views/sign_up.ejs

@ -37,7 +37,7 @@ function show_error(error) {
function success() { function success() {
alert("注册成功!"); alert("注册成功!");
window.location.href = location.protocol + '//' + location.host + <%- JSON.stringify(req.query.url || '/') %>; window.location.href = location.protocol + '//' + location.host + <%- serializejs(req.query.url || '/') %>;
} }
function mail_required() { function mail_required() {
@ -63,7 +63,7 @@ function submit() {
username: $("#username").val(), username: $("#username").val(),
password: password, password: password,
email: $("#email").val(), email: $("#email").val(),
prevUrl: <%- JSON.stringify(req.query.url || '/') %> prevUrl: <%- serializejs(req.query.url || '/') %>
}, },
success: function(data) { success: function(data) {
error_code = data.error_code; error_code = data.error_code;

6
views/statistics.ejs

@ -103,7 +103,7 @@ function getColorOfScore(score) {
<script type="text/javascript"> <script type="text/javascript">
new Morris.Bar({ new Morris.Bar({
element: 'score-distribution-chart', element: 'score-distribution-chart',
data: <%- JSON.stringify(statistics.scoreDistribution) %>, data: <%- serializejs(statistics.scoreDistribution) %>,
barColors: function(r, s, type) { barColors: function(r, s, type) {
return getColorOfScore(r.label); return getColorOfScore(r.label);
}, },
@ -129,7 +129,7 @@ function getColorOfScore(score) {
%> %>
new Morris.Line({ new Morris.Line({
element: 'score-distribution-chart-pre', element: 'score-distribution-chart-pre',
data: <%- JSON.stringify(statistics.prefixSum) %>, data: <%- serializejs(statistics.prefixSum) %>,
xkey: 'score', xkey: 'score',
ykeys: ['count'], ykeys: ['count'],
labels: ['number'], labels: ['number'],
@ -161,7 +161,7 @@ function getColorOfScore(score) {
%> %>
new Morris.Line({ new Morris.Line({
element: 'score-distribution-chart-suf', element: 'score-distribution-chart-suf',
data: <%- JSON.stringify(statistics.suffixSum) %>, data: <%- serializejs(statistics.suffixSum) %>,
xkey: 'score', xkey: 'score',
ykeys: ['count'], ykeys: ['count'],
labels: ['number'], labels: ['number'],

18
views/submission.ejs

@ -149,8 +149,8 @@ Vue.component("code-box", {
props: ['title', 'content', 'escape'] props: ['title', 'content', 'escape']
}); });
const socketUrl = "/detail"; const socketUrl = "/detail";
const displayConfig = <%- JSON.stringify(displayConfig) %>; const displayConfig = <%- serializejs(displayConfig) %>;
const token = <%- JSON.stringify(socketToken) %>; const token = <%- serializejs(socketToken) %>;
const TestcaseResultType = {}; const TestcaseResultType = {};
(function (TestcaseResultType) { (function (TestcaseResultType) {
@ -187,8 +187,8 @@ const TaskStatus = {};
TaskStatus[TaskStatus["Skipped"] = 4] = "Skipped"; TaskStatus[TaskStatus["Skipped"] = 4] = "Skipped";
})(TaskStatus); })(TaskStatus);
const unformattedCode = <%- JSON.stringify(code) %>; const unformattedCode = <%- serializejs(code) %>;
const formattedCode = <%- JSON.stringify(formattedCode) %>; const formattedCode = <%- serializejs(formattedCode) %>;
function toggleFormattedCode() { function toggleFormattedCode() {
if (vueApp.currentFormatted) { if (vueApp.currentFormatted) {
@ -204,14 +204,14 @@ const vueApp = new Vue({
el: '#vueAppFuckSafari', el: '#vueAppFuckSafari',
data: { data: {
roughData: { roughData: {
info: <%- JSON.stringify(info) %>, info: <%- serializejs(info) %>,
result: <%- JSON.stringify(roughResult) %>, result: <%- serializejs(roughResult) %>,
running: false, running: false,
displayConfig: displayConfig displayConfig: displayConfig
}, },
code: <%- JSON.stringify(preferFormattedCode && formattedCode !== null) -%> ? formattedCode : unformattedCode, code: <%- serializejs(preferFormattedCode && formattedCode !== null) -%> ? formattedCode : unformattedCode,
currentFormatted: <%- JSON.stringify(preferFormattedCode && formattedCode !== null) -%>, currentFormatted: <%- serializejs(preferFormattedCode && formattedCode !== null) -%>,
detailResult: <%- JSON.stringify(detailResult) %>, detailResult: <%- serializejs(detailResult) %>,
displayConfig: displayConfig, displayConfig: displayConfig,
}, },
computed: { computed: {

6
views/submissions.ejs

@ -74,7 +74,7 @@
<script> <script>
$(function () { $(function () {
$('#my_submit').click(function () { $('#my_submit').click(function () {
$('[name=submitter]').val(<%- JSON.stringify(user.username) %>); $('[name=submitter]').val(<%- serializejs(user.username) %>);
$('#form').submit(); $('#form').submit();
}); });
}); });
@ -129,9 +129,9 @@ $(function () {
$('#select_language').dropdown(); $('#select_language').dropdown();
$('#select_status').dropdown(); $('#select_status').dropdown();
}); });
const itemList = <%- JSON.stringify(items) %>; const itemList = <%- serializejs(items) %>;
const socketUrl = "/rough"; const socketUrl = "/rough";
const displayConfig = <%- JSON.stringify(displayConfig) %>; const displayConfig = <%- serializejs(displayConfig) %>;
const vueApp = new Vue({ const vueApp = new Vue({
el: '#vueAppFuckSafari', el: '#vueAppFuckSafari',

6
views/submissions_item.ejs

@ -10,13 +10,13 @@ function formatSize(x, precision) {
return fixed + ' ' + unit; return fixed + ' ' + unit;
} }
const submissionUrl = <%- JSON.stringify(displayConfig.inContest ? const submissionUrl = <%- serializejs(displayConfig.inContest ?
syzoj.utils.makeUrl(['contest', 'submission', '20000528']) : syzoj.utils.makeUrl(['contest', 'submission', '20000528']) :
syzoj.utils.makeUrl(['submission', '20000528'])) %>; syzoj.utils.makeUrl(['submission', '20000528'])) %>;
const problemUrl = <%- JSON.stringify(displayConfig.inContest ? const problemUrl = <%- serializejs(displayConfig.inContest ?
syzoj.utils.makeUrl(['contest', contest.id, 'problem', '20000528']) : syzoj.utils.makeUrl(['contest', contest.id, 'problem', '20000528']) :
syzoj.utils.makeUrl(['problem', '20000528'])) %>; syzoj.utils.makeUrl(['problem', '20000528'])) %>;
const userUrl = <%- JSON.stringify(syzoj.utils.makeUrl(['user', '20000528'])) %>; const userUrl = <%- serializejs(syzoj.utils.makeUrl(['user', '20000528'])) %>;
Vue.component('submission-item', { Vue.component('submission-item', {
template: '#submissionItemTemplate', template: '#submissionItemTemplate',

Loading…
Cancel
Save