Skip to content

Commit

Permalink
feat: implement exact location for each bidi char
Browse files Browse the repository at this point in the history
  • Loading branch information
Simone Sanfratello authored and lmammino committed Dec 16, 2022
1 parent ea58be4 commit c621341
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 43 deletions.
80 changes: 44 additions & 36 deletions rules/detect-trojan-source.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,58 @@
/**
* Detect trojan source attacks that employ unicode bidi attacks to inject malicious code
* @author Luciamo Mammino
* @author Simone Sanfratello
* @author Liran Tal
*/

'use strict';

const dangerousBidiChars = ['\u061C', '\u200E', '\u200F', '\u202A', '\u202B', '\u202C', '\u202D', '\u202E', '\u2066', '\u2067', '\u2068', '\u2069'];
const dangerousBidiCharsRegexp = /[\u061C\u200E\u200F\u202A\u202B\u202C\u202D\u202E\u2066\u2067\u2068\u2069]/gu;

function hasTrojanSource({ sourceText }) {
function hasTrojanSource({ sourceText, offsetLine }) {
const sourceTextToSearch = sourceText.toString();

for (const bidiChar of dangerousBidiChars) {
if (sourceTextToSearch.includes(bidiChar)) {
return true;
const lines = sourceTextToSearch.split(/\r?\n/);

return lines.reduce((reports, line, lineIndex) => {
let match;
let offset = lineIndex == 0 ? offsetLine : 0;

while ((match = dangerousBidiCharsRegexp.exec(line)) !== null) {
reports.push({ line: lineIndex, column: offset + match.index });
}

return reports;
}, []);
}

function report({ context, node, tokens, message }) {
if (!tokens || !Array.isArray(tokens)) {
return;
}
tokens.forEach((token) => {
const reports = hasTrojanSource({ sourceText: token.value, offsetLine: token.loc.start.column });

return false;
reports.forEach((report) => {
context.report({
node: node,
data: {
text: token.value,
},
loc: {
start: {
line: token.loc.start.line + report.line,
column: report.column,
},
end: {
line: token.loc.start.line + report.line,
column: report.column + 1,
},
},
message,
});
});
});
}

//------------------------------------------------------------------------------
Expand All @@ -36,36 +72,8 @@ module.exports = {
create: function (context) {
return {
Program: function (node) {
// at the start of analyzing a code path
if (node.tokens && Array.isArray(node.tokens)) {
node.tokens.forEach((token) => {
if (hasTrojanSource({ sourceText: token.value })) {
context.report({
node: node,
data: {
text: token.value,
},
loc: token.loc,
message: "Detected potential trojan source attack with unicode bidi introduced in this code: '{{text}}'.",
});
}
});
}

if (node.comments && Array.isArray(node.comments)) {
node.comments.forEach((comment) => {
if (hasTrojanSource({ sourceText: comment.value })) {
context.report({
node: node,
data: {
text: comment.value,
},
loc: comment.loc,
message: "Detected potential trojan source attack with unicode bidi introduced in this comment: '{{text}}'.",
});
}
});
}
report({ context, node, tokens: node.tokens, message: "Detected potential trojan source attack with unicode bidi introduced in this code: '{{text}}'." });
report({ context, node, tokens: node.comments, message: "Detected potential trojan source attack with unicode bidi introduced in this comment: '{{text}}'." });
},
};
},
Expand Down
26 changes: 19 additions & 7 deletions test/detect-trojan-source.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ tester.run(ruleName, Rule, {
console.log("You are an admin.");
}
`,
errors: [{ message: /Detected potential trojan source attack with unicode bidi introduced in this code/i, line: 3, endLine: 3, column: 26, endColumn: 55 }],
errors: [
{ message: /Detected potential trojan source attack with unicode bidi introduced in this code/i, line: 3, endLine: 3, column: 31, endColumn: 32 },
{ message: /Detected potential trojan source attack with unicode bidi introduced in this code/i, line: 3, endLine: 3, column: 33, endColumn: 34 },
{ message: /Detected potential trojan source attack with unicode bidi introduced in this code/i, line: 3, endLine: 3, column: 51, endColumn: 52 },
{ message: /Detected potential trojan source attack with unicode bidi introduced in this code/i, line: 3, endLine: 3, column: 53, endColumn: 54 },
],
},
],
});
Expand All @@ -47,14 +52,21 @@ tester.run(`${ruleName} in comment-line`, Rule, {
var isAdmin = false;
/*‮ } ⁦if (isAdmin)⁩ ⁦ begin admins only */
console.log("You are an admin.");
/* end admins only ‮ { ⁦*/
/* end admins only ‮
{ ⁦*/
/* end admins only ‮
⁦*/
/* end admins only ‮ \r\n { ⁦*/
`,
errors: [
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 3, endLine: 3, column: 7, endColumn: 50 },
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 5, endLine: 5, column: 7, endColumn: 33 },
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 6, endLine: 7, column: 7, endColumn: 15 },
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 3, endLine: 3, column: 7, endColumn: 8 },
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 3, endLine: 3, column: 11, endColumn: 12 },
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 3, endLine: 3, column: 24, endColumn: 25 },
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 3, endLine: 3, column: 26, endColumn: 27 },

{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 5, endLine: 5, column: 24, endColumn: 25 },
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 6, endLine: 6, column: 1, endColumn: 2 },

{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 7, endLine: 7, column: 24, endColumn: 25 },
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 8, endLine: 8, column: 4, endColumn: 5 },
],
},
],
Expand Down

0 comments on commit c621341

Please sign in to comment.