Skip to content

Commit

Permalink
Replaced further challenge checks with one-liner function
Browse files Browse the repository at this point in the history
  • Loading branch information
bkimminich committed Jan 17, 2020
1 parent 4519031 commit 0d0a39f
Show file tree
Hide file tree
Showing 22 changed files with 54 additions and 149 deletions.
4 changes: 1 addition & 3 deletions models/product.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ module.exports = (sequelize, { STRING, DECIMAL }) => {
description: {
type: STRING,
set (description) {
if (utils.notSolved(challenges.restfulXssChallenge) && utils.contains(description, '<iframe src="javascript:alert(`xss`)">')) {
utils.solve(challenges.restfulXssChallenge)
}
utils.solveIf(challenges.restfulXssChallenge, () => { return utils.contains(description, '<iframe src="javascript:alert(`xss`)">') })
this.setDataValue('description', description)
}
},
Expand Down
8 changes: 2 additions & 6 deletions models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,15 @@ module.exports = (sequelize, { STRING, BOOLEAN }) => {
defaultValue: '',
set (username) {
username = insecurity.sanitizeLegacy(username)
if (utils.notSolved(challenges.usernameXssChallenge) && utils.contains(username, '<script>alert(`xss`)</script>')) {
utils.solve(challenges.usernameXssChallenge)
}
utils.solveIf(challenges.usernameXssChallenge, () => { return utils.contains(username, '<script>alert(`xss`)</script>') })
this.setDataValue('username', username)
}
},
email: {
type: STRING,
unique: true,
set (email) {
if (utils.notSolved(challenges.persistedXssUserChallenge) && utils.contains(email, '<iframe src="javascript:alert(`xss`)">')) {
utils.solve(challenges.persistedXssUserChallenge)
}
utils.solveIf(challenges.persistedXssUserChallenge, () => { return utils.contains(email, '<iframe src="javascript:alert(`xss`)">') })
this.setDataValue('email', email)
}
},
Expand Down
5 changes: 1 addition & 4 deletions routes/2fa.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ async function verify (req, res) {
if (!isValid) {
return res.status(401).send()
}

if (utils.notSolved(challenges.twoFactorAuthUnsafeSecretStorageChallenge) && user.email === 'wurstbrot@' + config.get('application.domain')) {
utils.solve(challenges.twoFactorAuthUnsafeSecretStorageChallenge)
}
utils.solveIf(challenges.twoFactorAuthUnsafeSecretStorageChallenge, () => { return user.email === 'wurstbrot@' + config.get('application.domain') })

const [basket] = await models.Basket.findOrCreate({ where: { userId }, defaults: {} })

Expand Down
8 changes: 2 additions & 6 deletions routes/b2bOrder.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,11 @@ module.exports = function b2bOrder () {
res.json({ cid: body.cid, orderNo: uniqueOrderNumber(), paymentDue: dateTwoWeeksFromNow() })
} catch (err) {
if (err.message && err.message.match(/Script execution timed out.*/)) {
if (utils.notSolved(challenges.rceOccupyChallenge)) {
utils.solve(challenges.rceOccupyChallenge)
}
utils.solveIf(challenges.rceOccupyChallenge, () => { return true })
res.status(503)
next(new Error('Sorry, we are temporarily not available! Please try again later.'))
} else {
if (utils.notSolved(challenges.rceChallenge) && err.message === 'Infinite loop detected - reached max iterations') {
utils.solve(challenges.rceChallenge)
}
utils.solveIf(challenges.rceChallenge, () => { return err.message === 'Infinite loop detected - reached max iterations' })
next(err)
}
}
Expand Down
8 changes: 3 additions & 5 deletions routes/basket.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@ module.exports = function retrieveBasket () {
models.Basket.findOne({ where: { id }, include: [{ model: models.Product, paranoid: false }] })
.then(basket => {
/* jshint eqeqeq:false */
if (utils.notSolved(challenges.basketAccessChallenge)) {
utils.solveIf(challenges.basketAccessChallenge, () => {
const user = insecurity.authenticatedUsers.from(req)
if (user && id && id !== 'undefined' && id !== 'null' && user.bid != id) { // eslint-disable-line eqeqeq
utils.solve(challenges.basketAccessChallenge)
}
}
return user && id && id !== 'undefined' && id !== 'null' && user.bid != id // eslint-disable-line eqeqeq
})
if (basket && basket.Products && basket.Products.length > 0) {
for (let i = 0; i < basket.Products.length; i++) {
basket.Products[i].name = req.__(basket.Products[i].name)
Expand Down
7 changes: 1 addition & 6 deletions routes/basketItems.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,7 @@ module.exports.addBasketItem = function addBasketItem () {
BasketId: basketIds[basketIds.length - 1],
quantity: quantities[quantities.length - 1]
}

if (utils.notSolved(challenges.basketManipulateChallenge)) {
if (user && basketItem.BasketId && basketItem.BasketId !== 'undefined' && user.bid != basketItem.BasketId) { // eslint-disable-line eqeqeq
utils.solve(challenges.basketManipulateChallenge)
}
}
utils.solveIf(challenges.basketManipulateChallenge, () => { return user && basketItem.BasketId && basketItem.BasketId !== 'undefined' && user.bid != basketItem.BasketId }) // eslint-disable-line eqeqeq

const basketItemInstance = models.BasketItem.build(basketItem)
basketItemInstance.save().then((basketItem) => {
Expand Down
6 changes: 1 addition & 5 deletions routes/changePassword.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ module.exports = function changePassword () {
} else {
models.User.findByPk(loggedInUser.data.id).then(user => {
user.update({ password: newPassword }).then(user => {
if (utils.notSolved(challenges.changePasswordBenderChallenge) && user.id === 3 && !currentPassword) {
if (user.password === insecurity.hash('slurmCl4ssic')) {
utils.solve(challenges.changePasswordBenderChallenge)
}
}
utils.solveIf(challenges.changePasswordBenderChallenge, () => { return user.id === 3 && !currentPassword && user.password === insecurity.hash('slurmCl4ssic') })
res.json({ user })
}).catch(error => {
next(error)
Expand Down
4 changes: 1 addition & 3 deletions routes/createProductReviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ const insecurity = require('../lib/insecurity')
module.exports = function productReviews () {
return (req, res, next) => {
const user = insecurity.authenticatedUsers.from(req)
if (user && user.data.email !== req.body.author && utils.notSolved(challenges.forgedReviewChallenge)) {
utils.solve(challenges.forgedReviewChallenge)
}
utils.solveIf(challenges.forgedReviewChallenge, () => { return user && user.data.email !== req.body.author })
db.reviews.insert({
product: req.params.id,
message: req.body.message,
Expand Down
4 changes: 1 addition & 3 deletions routes/currentUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ module.exports = function retrieveLoggedInUser () {
if (req.query.callback === undefined) {
res.json(response)
} else {
if (utils.notSolved(challenges.emailLeakChallenge)) {
utils.solve(challenges.emailLeakChallenge)
}
utils.solveIf(challenges.emailLeakChallenge, () => { return true })
res.jsonp(response)
}
}
Expand Down
4 changes: 1 addition & 3 deletions routes/dataExport.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ module.exports = function dataExport () {
}
const emailHash = insecurity.hash(email).slice(0, 4)
for (const order of userData.orders) {
if (order.orderId.split('-')[0] !== emailHash && utils.notSolved(challenges.dataExportChallenge)) {
utils.solve(challenges.dataExportChallenge)
}
utils.solveIf(challenges.dataExportChallenge, () => { return order.orderId.split('-')[0] !== emailHash })
}
res.status(200).send({ userData: JSON.stringify(userData, null, 2), confirmation: 'Your data export will open in a new Browser window.' })
},
Expand Down
4 changes: 1 addition & 3 deletions routes/easterEgg.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ const challenges = require('../data/datacache').challenges

module.exports = function serveEasterEgg () {
return (req, res) => {
if (utils.notSolved(challenges.easterEggLevelTwoChallenge)) {
utils.solve(challenges.easterEggLevelTwoChallenge)
}
utils.solveIf(challenges.easterEggLevelTwoChallenge, () => { return true })
res.sendFile(path.resolve(__dirname, '../frontend/dist/frontend/assets/private/threejs-demo.html'))
}
}
16 changes: 5 additions & 11 deletions routes/fileServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,11 @@ module.exports = function servePublicFiles () {
}

function verifySuccessfulPoisonNullByteExploit (file) {
if (utils.notSolved(challenges.easterEggLevelOneChallenge) && file.toLowerCase() === 'eastere.gg') {
utils.solve(challenges.easterEggLevelOneChallenge)
} else if (utils.notSolved(challenges.directoryListingChallenge) && file.toLowerCase() === 'acquisitions.md') {
utils.solve(challenges.directoryListingChallenge)
} else if (utils.notSolved(challenges.forgottenDevBackupChallenge) && file.toLowerCase() === 'package.json.bak') {
utils.solve(challenges.forgottenDevBackupChallenge)
} else if (utils.notSolved(challenges.forgottenBackupChallenge) && file.toLowerCase() === 'coupons_2013.md.bak') {
utils.solve(challenges.forgottenBackupChallenge)
} else if (utils.notSolved(challenges.misplacedSignatureFileChallenge) && file.toLowerCase() === 'suspicious_errors.yml') {
utils.solve(challenges.misplacedSignatureFileChallenge)
}
utils.solveIf(challenges.easterEggLevelOneChallenge, () => { return file.toLowerCase() === 'eastere.gg' })
utils.solveIf(challenges.directoryListingChallenge, () => { return file.toLowerCase() === 'acquisitions.md' })
utils.solveIf(challenges.forgottenDevBackupChallenge, () => { return file.toLowerCase() === 'package.json.bak' })
utils.solveIf(challenges.forgottenBackupChallenge, () => { return file.toLowerCase() === 'coupons_2013.md.bak' })
utils.solveIf(challenges.misplacedSignatureFileChallenge, () => { return file.toLowerCase() === 'suspicious_errors.yml' })
}

function endsWithWhitelistedFileType (param) {
Expand Down
22 changes: 6 additions & 16 deletions routes/fileUpload.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ function handleZipFileUpload ({ file }, res, next) {
.on('entry', function (entry) {
const fileName = entry.path
const absolutePath = path.resolve('uploads/complaints/' + fileName)
if (absolutePath === path.resolve('ftp/legal.md') && utils.notSolved(challenges.fileWriteChallenge)) {
utils.solve(challenges.fileWriteChallenge)
}
utils.solveIf(challenges.fileWriteChallenge, () => { return absolutePath === path.resolve('ftp/legal.md') })
if (absolutePath.includes(path.resolve('.'))) {
entry.pipe(fs.createWriteStream('uploads/complaints/' + fileName).on('error', function (err) { next(err) }))
} else {
Expand All @@ -62,35 +60,27 @@ function handleZipFileUpload ({ file }, res, next) {
}

function checkUploadSize ({ file }, res, next) {
if (utils.notSolved(challenges.uploadSizeChallenge) && file.size > 100000) {
utils.solve(challenges.uploadSizeChallenge)
}
utils.solveIf(challenges.uploadSizeChallenge, () => { return file.size > 100000 })
next()
}

function checkFileType ({ file }, res, next) {
if (utils.notSolved(challenges.uploadTypeChallenge) && !(utils.endsWith(file.originalname.toLowerCase(), '.pdf') ||
utils.endsWith(file.originalname.toLowerCase(), '.xml') || utils.endsWith(file.originalname.toLowerCase(), '.zip'))) {
utils.solve(challenges.uploadTypeChallenge)
}
utils.solveIf(challenges.uploadTypeChallenge, () => { return !(utils.endsWith(file.originalname.toLowerCase(), '.pdf') ||
utils.endsWith(file.originalname.toLowerCase(), '.xml') || utils.endsWith(file.originalname.toLowerCase(), '.zip')) })
next()
}

function handleXmlUpload ({ file }, res, next) {
if (utils.endsWith(file.originalname.toLowerCase(), '.xml')) {
if (utils.notSolved(challenges.deprecatedInterfaceChallenge)) {
utils.solve(challenges.deprecatedInterfaceChallenge)
}
utils.solveIf(challenges.deprecatedInterfaceChallenge, () => { return true })
if (file.buffer && !utils.disableOnContainerEnv()) { // XXE attacks in Docker/Heroku containers regularly cause "segfault" crashes
const data = file.buffer.toString()
try {
const sandbox = { libxml, data }
vm.createContext(sandbox)
const xmlDoc = vm.runInContext('libxml.parseXml(data, { noblanks: true, noent: true, nocdata: true })', sandbox, { timeout: 2000 })
const xmlString = xmlDoc.toString(false)
if (utils.notSolved(challenges.xxeFileDisclosureChallenge) && (matchesSystemIniFile(xmlString) || matchesEtcPasswdFile(xmlString))) {
utils.solve(challenges.xxeFileDisclosureChallenge)
}
utils.solveIf(challenges.xxeFileDisclosureChallenge, () => { return (matchesSystemIniFile(xmlString) || matchesEtcPasswdFile(xmlString)) })
res.status(410)
next(new Error('B2B customer complaints via file upload have been deprecated for security reasons: ' + utils.trunc(xmlString, 200) + ' (' + file.originalname + ')'))
} catch (err) {
Expand Down
4 changes: 1 addition & 3 deletions routes/likeProductReviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ module.exports = function productReviews () {
count++
}
}
if (count > 2 && utils.notSolved(challenges.timingAttackChallenge)) {
utils.solve(challenges.timingAttackChallenge)
}
utils.solveIf(challenges.timingAttackChallenge, () => { return count > 2 })
db.reviews.update(
{ _id: id },
{ $set: { likedBy: likedBy } }
Expand Down
8 changes: 2 additions & 6 deletions routes/order.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ module.exports = function placeOrder () {
const basketProducts = []
let totalPoints = 0
basket.Products.forEach(({ BasketItem, price, deluxePrice, name, id }) => {
if (utils.notSolved(challenges.christmasSpecialChallenge) && BasketItem.ProductId === products.christmasSpecial.id) {
utils.solve(challenges.christmasSpecialChallenge)
}
utils.solveIf(challenges.christmasSpecialChallenge, () => { return BasketItem.ProductId === products.christmasSpecial.id })

models.Quantity.findOne({ where: { ProductId: BasketItem.ProductId } }).then((product) => {
const newQuantity = product.dataValues.quantity - BasketItem.quantity
Expand Down Expand Up @@ -127,9 +125,7 @@ module.exports = function placeOrder () {
doc.font('Times-Roman', 15).text(req.__('Thank you for your order!'))
doc.end()

if (utils.notSolved(challenges.negativeOrderChallenge) && totalPrice < 0) {
utils.solve(challenges.negativeOrderChallenge)
}
utils.solveIf(challenges.negativeOrderChallenge, () => { return totalPrice < 0 })

if (req.body.UserId) {
if (req.body.orderDetails.paymentId === 'wallet') {
Expand Down
4 changes: 1 addition & 3 deletions routes/premiumReward.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ const challenges = require('../data/datacache').challenges

module.exports = function servePremiumContent () {
return (req, res) => {
if (utils.notSolved(challenges.premiumPaywallChallenge)) {
utils.solve(challenges.premiumPaywallChallenge)
}
utils.solveIf(challenges.premiumPaywallChallenge, () => { return true })
res.sendFile(path.resolve(__dirname, '../frontend/dist/frontend/assets/private/JuiceShop_Wallpaper_1920x1080_VR.jpg'))
}
}
4 changes: 1 addition & 3 deletions routes/privacyPolicyProof.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ const challenges = require('../data/datacache').challenges

module.exports = function servePrivacyPolicyProof () {
return (req, res) => {
if (utils.notSolved(challenges.privacyPolicyProofChallenge)) {
utils.solve(challenges.privacyPolicyProofChallenge)
}
utils.solveIf(challenges.privacyPolicyProofChallenge, () => { return true })
res.sendFile(path.resolve(__dirname, '../frontend/dist/frontend/assets/private/thank-you.jpg'))
}
}
8 changes: 2 additions & 6 deletions routes/redirect.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,8 @@ module.exports = function performRedirect () {
return ({ query }, res, next) => {
const toUrl = query.to
if (insecurity.isRedirectAllowed(toUrl)) {
if (utils.notSolved(challenges.redirectCryptoCurrencyChallenge) && (toUrl === 'https://explorer.dash.org/address/Xr556RzuwX6hg5EGpkybbv5RanJoZN17kW' || toUrl === 'https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm' || toUrl === 'https://etherscan.io/address/0x0f933ab9fcaaa782d0279c300d73750e1311eae6')) {
utils.solve(challenges.redirectCryptoCurrencyChallenge)
}
if (utils.notSolved(challenges.redirectChallenge) && isUnintendedRedirect(toUrl)) {
utils.solve(challenges.redirectChallenge)
}
utils.solveIf(challenges.redirectCryptoCurrencyChallenge, () => { return toUrl === 'https://explorer.dash.org/address/Xr556RzuwX6hg5EGpkybbv5RanJoZN17kW' || toUrl === 'https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm' || toUrl === 'https://etherscan.io/address/0x0f933ab9fcaaa782d0279c300d73750e1311eae6' })
utils.solveIf(challenges.redirectChallenge, () => { return isUnintendedRedirect(toUrl) })
res.redirect(toUrl)
} else {
res.status(406)
Expand Down
4 changes: 1 addition & 3 deletions routes/saveLoginIp.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ module.exports = function saveLoginIp () {
var loggedInUser = insecurity.authenticatedUsers.from(req)
if (loggedInUser !== undefined) {
var lastLoginIp = req.headers['true-client-ip']
if (utils.notSolved(challenges.httpHeaderXssChallenge) && lastLoginIp === '<iframe src="javascript:alert(`xss`)">') {
utils.solve(challenges.httpHeaderXssChallenge)
}
utils.solveIf(challenges.httpHeaderXssChallenge, () => { return lastLoginIp === '<iframe src="javascript:alert(`xss`)">' })
if (lastLoginIp === undefined) {
lastLoginIp = utils.toSimpleIpAddress(req.connection.remoteAddress)
}
Expand Down
9 changes: 2 additions & 7 deletions routes/updateProductReviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,8 @@ module.exports = function productReviews () {
{ multi: true }
).then(
result => {
if (result.modified > 1 && utils.notSolved(challenges.noSqlReviewsChallenge)) {
// More than one Review was modified => challange solved
utils.solve(challenges.noSqlReviewsChallenge)
}
if (user && user.data && result.original[0].author !== user.data.email && utils.notSolved(challenges.forgedReviewChallenge && result.modified === 1)) {
utils.solve(challenges.forgedReviewChallenge)
}
utils.solveIf(challenges.noSqlReviewsChallenge, () => { return result.modified > 1 })
utils.solveIf(challenges.forgedReviewChallenge, () => { return user && user.data && result.original[0].author !== user.data.email && result.modified === 1 })
res.json(result)
}, err => {
res.status(500).json(err)
Expand Down
Loading

0 comments on commit 0d0a39f

Please sign in to comment.