Skip to content

Commit de3f84c

Browse files
committed
XSS vulnerability fix - thank you to Jordan Milne (/u/largenocream) for the responsible discovery and contribution of a patch.
1 parent 12ecbd3 commit de3f84c

File tree

1 file changed

+90
-72
lines changed

1 file changed

+90
-72
lines changed

lib/snuownd.js

Lines changed: 90 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,89 +1375,107 @@
13751375
// rndr_html_tag(struct buf *ob, const struct buf *text, void *opaque, char* tagname, char** whitelist, int tagtype)
13761376
//NOT A CALLBACK!
13771377
function rndr_html_tag(out, text, options, tagname, whitelist, tagtype) {
1378-
var x, z, in_str = 0, seen_equals = 0, done, reset;
1379-
var attr = new Buffer()
1378+
var i, x, z, in_str = 0, seen_equals = 0, done = 0, done_attr = 0, reset = 0;
1379+
var attr;
1380+
var value;
13801381
var c;
1381-
1382+
13821383
out.s += '<';
1383-
1384-
var i = 1 + tagname.length;
1385-
1384+
13861385
if(tagtype == HTML_TAG_CLOSE) {
1387-
out.s += '/';
1388-
i += 1;
1386+
out.s += '/';
1387+
out.s += tagname;
1388+
out.s += '>';
1389+
return;
13891390
}
1390-
1391+
13911392
out.s += tagname;
1392-
1393-
if(tagtype != HTML_TAG_CLOSE) {
1394-
for(;i < text.s.length; i++) {
1395-
c = text.s[i];
1396-
done = 0;
1397-
reset = 0;
1398-
1399-
switch(c) {
1400-
case '>':
1401-
if(seen_equals && !in_str) {
1402-
done = 1;
1403-
reset = 1;
1404-
} else {
1405-
reset = 1;
1406-
}
1407-
break;
1408-
case '\'':
1409-
case '"':
1410-
if(!in_str)
1411-
in_str = c;
1412-
else if(in_str == c)
1413-
in_str = !in_str;
1393+
i = 1 + tagname.length;
1394+
1395+
attr = new Buffer();
1396+
value = new Buffer();
1397+
1398+
for(; i < text.s.length && !done; i++) {
1399+
c = text.s[i];
1400+
done = 0;
1401+
reset = 0;
1402+
done_attr = 0;
1403+
1404+
switch(c) {
1405+
case '>':
1406+
done = 1;
1407+
break;
1408+
case '\'':
1409+
case '"':
1410+
if(!seen_equals) {
1411+
reset = 1;
1412+
} else if(!in_str) {
1413+
in_str = c;
1414+
} else if(in_str == c) {
1415+
in_str = 0;
1416+
done_attr = 1;
1417+
} else {
1418+
value.s += c;
1419+
}
1420+
break;
1421+
case ' ':
1422+
if (in_str) {
1423+
value.s += ' ';
1424+
} else {
1425+
reset = 1;
1426+
}
1427+
break;
1428+
case '=':
1429+
if(seen_equals) {
1430+
reset = 1;
14141431
break;
1415-
default:
1416-
if(!in_str) {
1417-
switch(c) {
1418-
case ' ':
1419-
if(seen_equals) {
1420-
done = 1;
1421-
reset = 1;
1422-
} else
1423-
reset = 1;
1424-
break;
1425-
case '=':
1426-
if(seen_equals) {
1427-
reset = 1;
1428-
} else {
1429-
for(z=0; z < whitelist.length; z++) {
1430-
if(whitelist[z].length != attr.s.length)
1431-
continue;
1432-
for(x=0;x < attr.s.length; x++) {
1433-
if(whitelist[z][x].toLowerCase() != attr.s[x].toLowerCase())
1434-
break;
1435-
}
1436-
if(x == attr.s.length)
1437-
seen_equals = 1;
1438-
}
1439-
if(!seen_equals)
1440-
reset = 1;
1441-
}
1442-
break;
1443-
}
1432+
}
1433+
seen_equals = 1;
1434+
break;
1435+
default:
1436+
if(seen_equals && in_str || !seen_equals) {
1437+
if(seen_equals)
1438+
value.s += c;
1439+
else
1440+
attr.s += c;
1441+
}
1442+
break;
1443+
}
1444+
1445+
if(done_attr) {
1446+
var valid = 0;
1447+
for(z = 0; z < whitelist.length; z++) {
1448+
if(whitelist[z].length != attr.s.length) {
1449+
continue;
1450+
}
1451+
for(x = 0; x < attr.s.length; x++) {
1452+
if(whitelist[z][x].toLowerCase() != attr.s[x].toLowerCase()) {
1453+
break;
14441454
}
1455+
}
1456+
if(x == attr.s.length) {
1457+
valid = 1;
1458+
break;
1459+
}
14451460
}
1446-
1447-
if(done) {
1448-
out.s += ' ' + attr.s;
1449-
}
1450-
1451-
if(reset) {
1452-
seen_equals = 0;
1453-
in_str = 0;
1454-
attr.s = '';
1455-
} else {
1456-
attr.s += c;
1461+
if(valid && value.s.length && attr.s.length) {
1462+
out.s += ' ';
1463+
escape_html(out, attr.s, true);
1464+
out.s += "=\"";
1465+
escape_html(out, value.s, true);
1466+
out.s += '"';
14571467
}
1468+
reset = 1;
1469+
}
1470+
1471+
if(reset) {
1472+
seen_equals = 0;
1473+
in_str = 0;
1474+
attr.s = '';
1475+
value.s = '';
14581476
}
14591477
}
1460-
1478+
14611479
// bufrelease(attr);
14621480
out.s += '>';
14631481
}

0 commit comments

Comments
 (0)