Skip to content

Commit

Permalink
Use backticks (`) in all XSS payloads
Browse files Browse the repository at this point in the history
(Single-quotes mess with NoSQL queries)
  • Loading branch information
bkimminich committed Sep 25, 2018
1 parent 2dea370 commit 9605022
Show file tree
Hide file tree
Showing 10 changed files with 12 additions and 15 deletions.
8 changes: 4 additions & 4 deletions data/static/challenges.yml
Original file line number Diff line number Diff line change
Expand Up @@ -519,31 +519,31 @@
-
name: 'XSS Tier 1'
category: 'XSS'
description: 'Perform a <i>DOM</i> XSS attack with <code>&lt;iframe src="javascript:alert(&apos;xss&apos;)"&gt;</code>.'
description: 'Perform a <i>DOM</i> XSS attack with <code>&lt;iframe src="javascript:alert(`xss`)"&gt;</code>.'
difficulty: 1
hint: 'Look for an input field where its content appears in the HTML when its form is submitted.'
hintUrl: 'https://bkimminich.gitbooks.io/pwning-owasp-juice-shop/content/part2/xss.html#perform-a-reflected-xss-attack'
key: localXssChallenge
-
name: 'XSS Tier 2'
category: 'XSS'
description: 'Perform a <i>persisted</i> XSS attack with <code>&lt;iframe src="javascript:alert(&apos;xss&apos;)"&gt;</code> bypassing a <i>client-side</i> security mechanism.'
description: 'Perform a <i>persisted</i> XSS attack with <code>&lt;iframe src="javascript:alert(`xss`)"&gt;</code> bypassing a <i>client-side</i> security mechanism.'
difficulty: 3
hint: 'Only some input fields validate their input. Even less of these are persisted in a way where their content is shown on another screen.'
hintUrl: 'https://bkimminich.gitbooks.io/pwning-owasp-juice-shop/content/part2/xss.html#perform-a-persisted-xss-attack-bypassing-a-client-side-security-mechanism'
key: persistedXssChallengeUser
-
name: 'XSS Tier 3'
category: 'XSS'
description: 'Perform a <i>persisted</i> XSS attack with <code>&lt;iframe src="javascript:alert(&apos;xss&apos;)"&gt;</code> without using the frontend application at all.'
description: 'Perform a <i>persisted</i> XSS attack with <code>&lt;iframe src="javascript:alert(`xss`)"&gt;</code> without using the frontend application at all.'
difficulty: 3
hint: 'You need to work with the server-side API directly. Try different HTTP verbs on different entities exposed through the API.'
hintUrl: 'https://bkimminich.gitbooks.io/pwning-owasp-juice-shop/content/part2/xss.html#perform-a-persisted-xss-attack-without-using-the-frontend-application-at-all'
key: restfulXssChallenge
-
name: 'XSS Tier 4'
category: 'XSS'
description: 'Perform a <i>persisted</i> XSS attack with <code>&lt;iframe src="javascript:alert(&apos;xss&apos;)"&gt;</code> bypassing a <i>server-side</i> security mechanism.'
description: 'Perform a <i>persisted</i> XSS attack with <code>&lt;iframe src="javascript:alert(`xss`)"&gt;</code> bypassing a <i>server-side</i> security mechanism.'
difficulty: 4
hint: 'The "Comment" field in the "Contact Us" screen is where you want to put your focus on.'
hintUrl: 'https://bkimminich.gitbooks.io/pwning-owasp-juice-shop/content/part2/xss.html#perform-a-persisted-xss-attack-bypassing-a-server-side-security-mechanism'
Expand Down
2 changes: 1 addition & 1 deletion data/static/xchallenges.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
-
name: 'XSS Tier 5'
category: 'XSS'
description: 'Perform a <i>persisted</i> XSS attack with <code>&lt;iframe src="javascript:alert(&apos;xss&apos;)"&gt;</code> through an HTTP header.'
description: 'Perform a <i>persisted</i> XSS attack with <code>&lt;iframe src="javascript:alert(`xss`)"&gt;</code> through an HTTP header.'
difficulty: 4
hint: 'Finding a piece of displayed information that could originate from an HTTP header is the part of this challenge.'
hintUrl: 'https://bkimminich.gitbooks.io/pwning-owasp-juice-shop/content/part2/xss.html#perform-a-persisted-xss-attack-through-an-http-header'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ describe('SearchResultComponent', () => {
}))

it('should notify socket if search query includes XSS Tier 1 payload while filtering table', () => {
activatedRoute.setQueryParameter('<iframe src="javascript:alert(\'xss\')"> Payload')
activatedRoute.setQueryParameter('<iframe src="javascript:alert(`xss`)"> Payload')
spyOn(component.socket,'emit')
component.filterTable()
expect(component.socket.emit.calls.mostRecent().args[0]).toBe('localXSSChallengeSolved')
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/search-result/search-result.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class SearchResultComponent implements AfterViewInit,OnDestroy {

filterTable () {
let queryParam: string = this.route.snapshot.queryParams.q
if (queryParam && queryParam.includes('<iframe src="javascript:alert(\'xss\')">')) {
if (queryParam && queryParam.includes('<iframe src="javascript:alert(`xss`)">')) {
this.socket.emit('localXSSChallengeSolved', queryParam)
}
if (queryParam) {
Expand Down
2 changes: 1 addition & 1 deletion lib/startup/registerWebsocketEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const registerWebsocketEvents = (server) => {
})

socket.on('localXSSChallengeSolved', data => {
if (utils.notSolved(challenges.localXssChallenge) && utils.contains(data, '<iframe src="javascript:alert(\'xss\')">')) {
if (utils.notSolved(challenges.localXssChallenge) && utils.contains(data, '<iframe src="javascript:alert(`xss`)">')) {
utils.solve(challenges.localXssChallenge)
}
})
Expand Down
2 changes: 1 addition & 1 deletion models/feedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module.exports = (sequelize, { STRING, INTEGER }) => {
set (comment) {
const sanitizedComment = insecurity.sanitizeHtml(comment)
this.setDataValue('comment', sanitizedComment)
if (utils.notSolved(challenges.persistedXssChallengeFeedback) && utils.contains(sanitizedComment, '<iframe src="javascript:alert(\'xss\')">')) {
if (utils.notSolved(challenges.persistedXssChallengeFeedback) && utils.contains(sanitizedComment, '<iframe src="javascript:alert(`xss`)">')) {
utils.solve(challenges.persistedXssChallengeFeedback)
}
}
Expand Down
2 changes: 1 addition & 1 deletion models/product.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = (sequelize, { STRING, DECIMAL }) => {
description: {
type: STRING,
set (description) {
if (utils.notSolved(challenges.restfulXssChallenge) && utils.contains(description, '<iframe src="javascript:alert(\'xss\')">')) {
if (utils.notSolved(challenges.restfulXssChallenge) && utils.contains(description, '<iframe src="javascript:alert(`xss`)">')) {
utils.solve(challenges.restfulXssChallenge)
}
this.setDataValue('description', description)
Expand Down
2 changes: 1 addition & 1 deletion models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module.exports = (sequelize, { STRING, BOOLEAN }) => {
type: STRING,
unique: true,
set (email) {
if (utils.notSolved(challenges.persistedXssChallengeUser) && utils.contains(email, '<iframe src="javascript:alert(\'xss\')">')) {
if (utils.notSolved(challenges.persistedXssChallengeUser) && utils.contains(email, '<iframe src="javascript:alert(`xss`)">')) {
utils.solve(challenges.persistedXssChallengeUser)
}
this.setDataValue('email', email)
Expand Down
3 changes: 0 additions & 3 deletions routes/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ module.exports = function searchProducts () {
return ({ query }, res, next) => {
let criteria = query.q === 'undefined' ? '' : query.q || ''
criteria = (criteria.length <= 200) ? criteria : criteria.substring(0, 200)
if (utils.notSolved(challenges.localXssChallenge) && utils.contains(criteria, '<iframe src="javascript:alert(\'xss\')">')) {
utils.solve(challenges.localXssChallenge) // FIXME Verification on server side not possible as value never get submitted to it
}
models.sequelize.query('SELECT * FROM Products WHERE ((name LIKE \'%' + criteria + '%\' OR description LIKE \'%' + criteria + '%\') AND deletedAt IS NULL) ORDER BY name')
.then(([products, query]) => {
if (utils.notSolved(challenges.unionSqlInjectionChallenge)) {
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/searchSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('/#/search', () => {
it('search query should be susceptible to reflected XSS attacks', () => {
const EC = protractor.ExpectedConditions

searchQuery.sendKeys('<iframe src="javascript:alert(\'xss\')">')
searchQuery.sendKeys('<iframe src="javascript:alert(`xss`)">')
searchButton.click()
browser.wait(EC.alertIsPresent(), 5000, "'xss' alert is not present")
browser.switchTo().alert().then(alert => {
Expand Down

0 comments on commit 9605022

Please sign in to comment.