Skip to content

Commit c0c9e32

Browse files
committed
submission,username,password length limits
1 parent 6c5eb6b commit c0c9e32

File tree

6 files changed

+52
-7
lines changed

6 files changed

+52
-7
lines changed

api/controllers/Accounts.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,11 @@ const login = async (req, res) => {
185185
let user = null
186186
if (/^[a-zA-Z0-9_]+$/.test(req.body.username)) user = await collections.users.findOne({ username: req.body.username.toLowerCase() });
187187
else user = await collections.users.findOne({ email: req.body.username.toLowerCase() });
188+
189+
if (req.body.password.length > 200 || req.body.password.length < 1) throw new Error('WrongDetails');
190+
188191
if (!user) throw new Error('WrongDetails');
192+
189193
else if (await argon2.verify(user.password, req.body.password)) {
190194
if (NodeCacheObj.get("emailVerify") && "code" in user) {
191195
res.send({ success: false, error: "need-verify", emailVerify: user.email })
@@ -242,10 +246,14 @@ const create = async (req, res) => {
242246
}
243247

244248
if (!/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(req.body.email)) throw new Error('BadEmail');
245-
if (!/^[a-zA-Z0-9_]+$/.test(req.body.username)) return res.send({
249+
if (!/^[a-zA-Z0-9_]{1,50}$/.test(req.body.username)) return res.send({
246250
success: false,
247251
error: "bad-username"
248252
})
253+
if (req.body.password.length > 200 || req.body.password.length < 1) return res.send({
254+
success: false,
255+
error: "bad-password"
256+
})
249257
let responseObj = { success: true }
250258
let insertObj = {
251259
username: req.body.username.toLowerCase(),

api/controllers/Challenges.js

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ const submit = async (req, res) => {
460460
type: 'submission'
461461
}) >= chall.max_attempts) throw new Error('Exceeded');
462462
}
463+
if (req.body.flag.length > 1000) throw new Error('InvalidFlagLength');
463464
let submitted = false
464465
if (NodeCacheObj.get("teamMode") && req.locals.username in usernameTeamCache) {
465466
const team = usernameTeamCache[req.locals.username]
@@ -589,7 +590,7 @@ const submit = async (req, res) => {
589590

590591
await insertTransaction(true);
591592
await collections.cache.updateOne({}, { '$set': { latestSolveSubmissionID: latestSolveSubmissionID } })
592-
593+
593594
res.send({
594595
success: true,
595596
data: 'correct'
@@ -628,6 +629,13 @@ const submit = async (req, res) => {
628629
error: 'exceeded'
629630
});
630631
return;
632+
case 'InvalidFlagLength':
633+
res.code(403);
634+
res.send({
635+
success: false,
636+
error: 'InvalidFlagLength'
637+
});
638+
return;
631639
default:
632640
throw new Error(err)
633641
}
@@ -656,6 +664,9 @@ const newChall = async (req, res) => {
656664
initial: req.body.initial,
657665
minSolves: req.body.minSolves
658666
};
667+
for (let i = 0; i < req.body.flags.length; i++) {
668+
if (!(req.body.flags[i].length <= 1000 && req.body.flags[i].length >= 1)) throw new Error('InvalidFlagLength');
669+
}
659670
if (req.body.tags) doc.tags = req.body.tags;
660671
if (req.body.hints) {
661672
doc.hints = req.body.hints;
@@ -721,14 +732,23 @@ const newChall = async (req, res) => {
721732
error: 'validation'
722733
});
723734
}
735+
else if (err.message == 'InvalidFlagLength') {
736+
res.code(400);
737+
res.send({
738+
success: false,
739+
error: 'validation'
740+
});
741+
}
724742
}
725743
}
726744

727745
const edit = async (req, res) => {
728746
const collections = Connection.collections
729747
try {
730748
if (req.locals.perms < 2) throw new Error('Permissions');
731-
749+
for (let i = 0; i < req.body.flags.length; i++) {
750+
if (!(req.body.flags[i].length <= 1000 && req.body.flags[i].length >= 1)) throw new Error('InvalidFlagLength');
751+
}
732752

733753
let updateObj = {};
734754
let unsetObj = {};
@@ -742,6 +762,7 @@ const edit = async (req, res) => {
742762
}
743763
}
744764
}
765+
745766
let latestSolveSubmissionID = NodeCacheObj.get("latestSolveSubmissionID")
746767
latestSolveSubmissionID += 1
747768
NodeCacheObj.set("latestSolveSubmissionID", latestSolveSubmissionID)
@@ -804,6 +825,13 @@ const edit = async (req, res) => {
804825
error: 'validation'
805826
});
806827
}
828+
else if (err.message == 'InvalidFlagLength') {
829+
res.code(400);
830+
res.send({
831+
success: false,
832+
error: 'validation'
833+
});
834+
}
807835
if (err.name == 'MongoServerError') {
808836
switch (err.code) {
809837
case 11000:

client/src/AdminPanel/adminChallengeCreate.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ const CreateChallengeForm = (props) => {
272272
{...field}
273273
name={[field.name]}
274274
fieldKey={[field.fieldKey]}
275-
rules={[{ required: true, message: 'Missing flag' }]}
275+
rules={[{ required: true, message: 'Missing flag' }, { message: "Please enter a flag that is < 1000 characters", pattern: /^.{1,1000}$/ }]}
276276
>
277277
<Input style={{ width: "50ch" }} placeholder="Flag" />
278278
</Form.Item>

client/src/AdminPanel/adminChallengeEdit.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const CreateChallengeForm = (props) => {
2929

3030
//Render existing categories select options
3131

32-
useEffect(() => {
32+
useEffect(() => {
3333
let existingCats = []
3434
for (let i = 0; i < props.allCat.length; i++) {
3535
existingCats.push(<Option key={props.allCat[i].key} value={props.allCat[i].key}>{props.allCat[i].key}</Option>)
@@ -297,7 +297,7 @@ const CreateChallengeForm = (props) => {
297297
{...field}
298298
name={[field.name]}
299299
fieldKey={[field.fieldKey]}
300-
rules={[{ required: true, message: 'Missing flag' }]}
300+
rules={[{ required: true, message: 'Missing flag' }, { message: "Please enter a flag that is < 1000 characters", pattern: /^.{1,1000}$/ }]}
301301
>
302302
<Input style={{ width: "50ch" }} placeholder="Flag" />
303303
</Form.Item>

client/src/Challenges/challengesTagSort.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,14 @@ class ChallengesTagSort extends React.Component {
487487
duration: 3
488488
});
489489
}
490+
else if (data.error === "InvalidFlagLength") {
491+
notification["error"]({
492+
message: 'Oops. Your flag is too long.',
493+
description:
494+
'Please do not spam the server with submissions that are too long.',
495+
duration: 3
496+
});
497+
}
490498
else {
491499
console.log(data.error)
492500
message.error({ content: "Oops. Unknown error" })

client/src/Login/login.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ class Login extends React.Component {
404404
<Form.Item
405405
name="username"
406406

407-
rules={[{ required: true, message: 'Please enter a username' }, { message: "Please enter an alphanumeric username (without spaces)", pattern: /^[a-zA-Z0-9_]+$/ }]}
407+
rules={[{ required: true, message: 'Please enter a username' }, { message: "Please enter an alphanumeric username (without spaces) <= 50 characters.", pattern: /^[a-zA-Z0-9_]{1,50}$/ }]}
408408
>
409409
<Input id="register-username" allowClear prefix={<UserOutlined className="site-form-item-icon" />} placeholder="Enter a new username" />
410410
</Form.Item>
@@ -428,6 +428,7 @@ class Login extends React.Component {
428428
required: true,
429429
message: 'Please input your password!',
430430
},
431+
{ message: "Please enter a password that is >= 1 character and <= 200 characters", pattern: /^.{1,200}$/ }
431432
]}
432433
hasFeedback
433434
>

0 commit comments

Comments
 (0)