-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
99 lines (90 loc) · 3.04 KB
/
index.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
/*
* This project obfuscates arbitrary sql queries by first converting
* the sql to json. Then the json keys are translated to new variable
* names in alphabetical order.
* Like "tableA" -> "a"
* "orders" -> "b"
* ...
* "users" -> "A"
* ...
* "users123" -> "aA"
* ...
* the new json object is then converted back into a valid sql query
* and displayed to the user.
*/
const sql2json = require('./sql2json');
const Json2sql = sql2json.json2sql;
const Sql2json = sql2json.sql2json;
// NOTE module hangs on semicolon
// obj = new Sql2json("select height, weight, color from item;");
/*
* newTable returns a new name for tables, maintains it's own internal state
*/
var newNameConstructor = function(beginningCharCode) {
var nameCharCodes = [beginningCharCode - 1];
return function() {
var leastSignificantDigit = nameCharCodes.pop()
leastSignificantDigit += 1;
if (leastSignificantDigit > beginningCharCode + 25) {
nameCharCodes.push(beginningCharCode)
nameCharCodes.push(beginningCharCode)
} else {
nameCharCodes.push(leastSignificantDigit)
}
return String.fromCharCode(...nameCharCodes);
}
};
var obfuscate = function() {
// reset obfuscators between runs
var newColumnName = newNameConstructor(97);
var newTableName = newNameConstructor(65);
var newTempWhereColumnName = newNameConstructor(97);
/*
* parseWhereBranch traverses a branch recursively and replaces any column names
* TODO build lookup table of replacements to properly obfuscate where clause,
* for now we naively replace where-clause literals linearly
* TODO factor out from obfuscate, nested due to dependency on newTempWhereColumnName
*/
var parseWhereBranch = function(node) {
if (node.type === 'operator') {
parseWhereBranch(node.left);
parseWhereBranch(node.right);
} else {
node.value = newTempWhereColumnName();
}
};
// get input
var inputArea = document.getElementById('input');
var inputString = inputArea.value;
if (inputString === '') {
// user did not provide input, obfuscate placeholder text instead
inputString = inputArea.placeholder;
}
// TODO remove when parsing properly handles trailing semicolon
inputString = inputString.trim()
if (inputString.endsWith(';')) {
inputString = inputString.slice(0, -1);
}
// obfuscate input
try {
obj = new Sql2json(inputString);
json = obj.toJSON();
json.select.forEach((selection) => {
selection.value = newColumnName()
})
json.from = 'A'
if(json.where) {
parseWhereBranch(json.where.left)
parseWhereBranch(json.where.right)
}
var result = Json2sql.toSQL(json) + ';';
} catch (e) {
var result = 'Could not parse sql! If you believe this is a bug please open an issue on github.com/morenoh149/sql-obfuscator';
}
// put result in DOM
var resultArea = document.getElementById('translation');
resultArea.innerHTML = result;
}
document.addEventListener("DOMContentLoaded", function(event) {
document.getElementById('submit').onclick = obfuscate;
});