on master help sign in
Additional sanitization on topic and tags to prevent onclick injection
7828142virtualsnow
scripts/hallway.js+6−2
@@ -171,8 +171,8 @@ function Hallway (sites) {
171 const parts = line.replace(' ', '\t').split('\t')
171 const parts = line.replace(' ', '\t').split('\t')
172 const date = parts[0].trim()
172 const date = parts[0].trim()
173 const body = escapeHtml(parts[1].trim()).trim()
173 const body = escapeHtml(parts[1].trim()).trim()
174− const channel = body.substr(0, 1) === '/' ? body.split(' ')[0].substr(1).toLowerCase() : body.substr(0, 1) === '@' ? 'veranda' : 'lobby'
174+ const channel = body.substr(0, 1) === '/' ? cleanTags(body.split(' ')[0].substr(1).toLowerCase()) : body.substr(0, 1) === '@' ? 'veranda' : 'lobby'
175− const tags = (body.match(reTag) || []).map(a => a.substr(a.indexOf('#') + 1).toLowerCase())
175+ const tags = (body.match(reTag) || []).map(a => cleanTags(a.substr(a.indexOf('#') + 1).toLowerCase()))
176 const offset = new Date() - new Date(date)
176 const offset = new Date() - new Date(date)
177 entries.push({ date, body, author, offset, channel, tags })
177 entries.push({ date, body, author, offset, channel, tags })
178 }
178 }
@@ -215,6 +215,10 @@ function escapeHtml (unsafe) {
215 return unsafe.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;')
215 return unsafe.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;')
216}
216}
217
217
218+function cleanTags (unsafe){
219+ return unsafe.replace(/([^a-z0-9]+)/gi, '-')
220+}
221+
218function stripHash (hash) {
222function stripHash (hash) {
219 const decoded = decodeURIComponent(hash)
223 const decoded = decodeURIComponent(hash)
220 return decoded.charAt(0) === '#' ? decoded.substring(1) : decoded
224 return decoded.charAt(0) === '#' ? decoded.substring(1) : decoded