/
fileServingSpec.js
154 lines (129 loc) · 5.88 KB
/
fileServingSpec.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
const frisby = require('frisby')
const config = require('config')
const utils = require('../../lib/utils')
const URL = 'http://localhost:3000'
let blueprint
for (const product of config.get('products')) {
if (product.fileForRetrieveBlueprintChallenge) {
blueprint = product.fileForRetrieveBlueprintChallenge
break
}
}
describe('Server', () => {
it('GET responds with index.html when visiting application URL', () => {
return frisby.get(URL)
.expect('status', 200)
.expect('header', 'content-type', /text\/html/)
.expect('bodyContains', 'main-es2015.js')
.expect('bodyContains', 'runtime-es2015.js')
.expect('bodyContains', 'polyfills-es2015.js')
})
it('GET responds with index.html when visiting application URL with any path', () => {
return frisby.get(URL + '/whatever')
.expect('status', 200)
.expect('header', 'content-type', /text\/html/)
.expect('bodyContains', 'main-es2015.js')
.expect('bodyContains', 'runtime-es2015.js')
.expect('bodyContains', 'polyfills-es2015.js')
})
it('GET a restricted file directly from file system path on server via Directory Traversal attack loads index.html instead', () => {
return frisby.get(URL + '/public/images/../../ftp/eastere.gg')
.expect('status', 200)
.expect('bodyContains', '<meta name="description" content="Probably the most modern and sophisticated insecure web application">')
})
it('GET a restricted file directly from file system path on server via URL-encoded Directory Traversal attack loads index.html instead', () => {
return frisby.get(URL + '/public/images/%2e%2e%2f%2e%2e%2fftp/eastere.gg')
.expect('status', 200)
.expect('bodyContains', '<meta name="description" content="Probably the most modern and sophisticated insecure web application">')
})
it('GET serves a security.txt file', () => {
return frisby.get(URL + '/.well-known/security.txt')
.expect('status', 200)
})
it('GET serves a robots.txt file', () => {
return frisby.get(URL + '/robots.txt')
.expect('status', 200)
})
})
describe('/public/images/padding', () => {
it('GET tracking image for "Score Board" page access challenge', () => {
return frisby.get(URL + '/assets/public/images/padding/1px.png')
.expect('status', 200)
.expect('header', 'content-type', 'image/png')
})
it('GET tracking image for "Administration" page access challenge', () => {
return frisby.get(URL + '/assets/public/images/padding/19px.png')
.expect('status', 200)
.expect('header', 'content-type', 'image/png')
})
it('GET tracking image for "Token Sale" page access challenge', () => {
return frisby.get(URL + '/assets/public/images/padding/56px.png')
.expect('status', 200)
.expect('header', 'content-type', 'image/png')
})
it('GET tracking image for "Privacy Policy" page access challenge', () => {
return frisby.get(URL + '/assets/public/images/padding/81px.png')
.expect('status', 200)
.expect('header', 'content-type', 'image/png')
})
})
describe('/encryptionkeys', () => {
it('GET serves a directory listing', () => {
return frisby.get(URL + '/encryptionkeys')
.expect('status', 200)
.expect('header', 'content-type', /text\/html/)
.expect('bodyContains', '<title>listing directory /encryptionkeys</title>')
})
it('GET a non-existing file in will return a 404 error', () => {
return frisby.get(URL + '/encryptionkeys/doesnotexist.md')
.expect('status', 404)
})
it('GET the Premium Content AES key', () => {
return frisby.get(URL + '/encryptionkeys/premium.key')
.expect('status', 200)
})
it('GET a key file whose name contains a "/" fails with a 403 error', () => {
frisby.fetch(URL + '/encryptionkeys/%2fetc%2fos-release%2500.md', {}, { urlEncode: false })
.expect('status', 403)
.expect('bodyContains', 'Error: File names cannot contain forward slashes!')
})
})
describe('Hidden URL', () => {
it('GET the second easter egg by visiting the Base64>ROT13-decrypted URL', () => {
return frisby.get(URL + '/the/devs/are/so/funny/they/hid/an/easter/egg/within/the/easter/egg')
.expect('status', 200)
.expect('header', 'content-type', /text\/html/)
.expect('bodyContains', '<title>Welcome to Planet Orangeuze</title>')
})
it('GET the premium content by visiting the AES decrypted URL', () => {
return frisby.get(URL + '/this/page/is/hidden/behind/an/incredibly/high/paywall/that/could/only/be/unlocked/by/sending/1btc/to/us')
.expect('status', 200)
.expect('header', 'content-type', 'image/jpeg')
})
it('GET the missing "Thank you!" image for assembling the URL hidden in the Privacy Policy', () => {
return frisby.get(URL + '/we/may/also/instruct/you/to/refuse/all/reasonably/necessary/responsibility')
.expect('status', 404)
})
it('GET Klingon translation file for "Extra Language" challenge', () => {
return frisby.get(URL + '/assets/i18n/tlh_AA.json')
.expect('status', 200)
.expect('header', 'content-type', /application\/json/)
})
it('GET blueprint file for "Retrieve Blueprint" challenge', () => {
return frisby.get(URL + '/assets/public/images/products/' + blueprint)
.expect('status', 200)
})
it('GET crazy cat photo for "Missing Encoding" challenge', () => {
return frisby.get(URL + '/assets/public/images/uploads/%F0%9F%98%BC-%23zatschi-%23whoneedsfourlegs-1572600969477.jpg')
.expect('status', 200)
})
it('GET folder containing access log files for "Access Log" challenge', () => {
return frisby.get(URL + '/support/logs/access.log.' + utils.toISO8601(new Date()))
.expect('status', 200)
.expect('header', 'content-type', /application\/octet-stream/)
})
it('GET path traversal does not work in folder containing access log files', () => {
return frisby.get(URL + '/support/logs/../../../../etc/passwd')
.expect('status', 403)
})
})