Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion java/jdbc/src/main/java/ai/ottermind/sqlx/JdbcWorker.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,24 @@ public static void main(String[] args) {
System.exit(1);
}
}
/**
* Replace standalone occurrences of a secret. A secret that is only part of a word or a
* hostname stays: the password "oracle" must not turn "docs.oracle.com" into
* "docs.[redacted].com", and a short username must not mangle unrelated words.
*/
static String redactSecret(String text, String secret) {
StringBuilder out = new StringBuilder(text.length());
int index = 0;
while (true) {
int at = text.indexOf(secret, index);
if (at < 0) { out.append(text, index, text.length()); return out.toString(); }
int end = at + secret.length();
boolean standalone = (at == 0 || boundary(text.charAt(at - 1))) && (end == text.length() || boundary(text.charAt(end)));
out.append(text, index, at).append(standalone ? "[redacted]" : secret);
index = end;
}
}
private static boolean boundary(char value) { return !(Character.isLetterOrDigit(value) || value == '.'); }
boolean run(JsonNode request) throws IOException {
JsonNode config = request.path("connection");
JsonNode sql = request.path("statements");
Expand Down Expand Up @@ -119,7 +137,7 @@ boolean run(JsonNode request) throws IOException {
if (e.getSQLState() != null && !e.getSQLState().startsWith("08") && !e.getSQLState().startsWith("HYT") && !(e instanceof SQLTimeoutException) && !(e instanceof SQLRecoverableException)) outcome = "failed";
}
String message = Objects.toString(failure.getMessage(), failure.getClass().getSimpleName());
for (String key : List.of("username", "password")) { String secret=config.path(key).asText(); if (!secret.isEmpty()) message=message.replace(secret,"[redacted]"); }
for (String key : List.of("username", "password")) { String secret=config.path(key).asText(); if (!secret.isEmpty()) message=redactSecret(message, secret); }
emit("error", "index", current, "code", code, "message", message, "outcome", outcome);
for (int i=current==null ? 0 : current+1; i<sql.size(); i++) emit("skipped", "index", i);
emit("complete", "success", false);
Expand Down
Loading