Skip to content
Open
Show file tree
Hide file tree
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
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## 2026-07-06 - Prevent Information Leakage in RPC Errors
**Vulnerability:** Internal RPC error messages (e.g. from bitcoind-rpc) were being exposed directly to users via `message.reply(err.message)` when a transaction failed. This can leak sensitive internal information (like network details, specific failure reasons, or connection paths).
**Learning:** Error messages from internal components like RPC daemon wrappers often contain details not intended for users. The bot needs to handle these errors internally (logging them for debug purposes) and return a generic error message to the user.
**Prevention:** Replaced `message.reply(err.message)` with `console.error(err); message.reply('An internal error occurred. Please try again later.')` across all tipbot modules to ensure users only see safe error messages.
6 changes: 3 additions & 3 deletions bot/modules/dogeTipper.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ function doWithdraw(message, tipper, words, helpmsg) {
}
doge.sendFrom(tipper, address, Number(amount), function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
message.channel.send({
embed: {
Expand Down Expand Up @@ -263,7 +263,7 @@ function doTip(bot, message, tipper, words, helpmsg) {
function sendDOGE(bot, message, tipper, recipient, amount, privacyFlag) {
getAddress(recipient.toString(), function (err, address) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
doge.sendFrom(
tipper,
Expand All @@ -274,7 +274,7 @@ function sendDOGE(bot, message, tipper, recipient, amount, privacyFlag) {
null,
function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
if (privacyFlag) {
let userProfile = message.guild.members.get(recipient); // ⚑ Bolt: O(1) direct ID lookup vs O(N) linear search;
Expand Down
6 changes: 3 additions & 3 deletions bot/modules/exampleTipper.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ function doWithdraw(message, tipper, words, helpmsg) {
}
ltc.sendFrom(tipper, address, Number(amount), function(err, txId) {
if (err) {
message.reply(err.message).then(message => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then(message => message.delete(10000));
} else {
message.channel.send({embed:{
title: '**:outbox_tray::money_with_wings::moneybag:Litecoin (LTC) Transaction Completed!:moneybag::money_with_wings::outbox_tray:**',
Expand Down Expand Up @@ -228,11 +228,11 @@ function doTip(bot, message, tipper, words, helpmsg) {
function sendLTC(bot, message, tipper, recipient, amount, privacyFlag) {
getAddress(recipient.toString(), function(err, address) {
if (err) {
message.reply(err.message).then(message => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then(message => message.delete(10000));
} else {
ltc.sendFrom(tipper, address, Number(amount), 1, null, null, function(err, txId) {
if (err) {
message.reply(err.message).then(message => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then(message => message.delete(10000));
} else {
if (privacyFlag) {
let userProfile = message.guild.members.get(recipient) // ⚑ Bolt: O(1) direct ID lookup vs O(N) linear search;
Expand Down
6 changes: 3 additions & 3 deletions bot/modules/ftcTipper.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ function doWithdraw(message, tipper, words, helpmsg) {
}
ftc.sendFrom(tipper, address, Number(amount), function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
message.channel.send({
embed: {
Expand Down Expand Up @@ -263,7 +263,7 @@ function doTip(bot, message, tipper, words, helpmsg) {
function sendFTC(bot, message, tipper, recipient, amount, privacyFlag) {
getAddress(recipient.toString(), function (err, address) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
ftc.sendFrom(
tipper,
Expand All @@ -274,7 +274,7 @@ function sendFTC(bot, message, tipper, recipient, amount, privacyFlag) {
null,
function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
if (privacyFlag) {
let userProfile = message.guild.members.get(recipient); // ⚑ Bolt: O(1) direct ID lookup vs O(N) linear search;
Expand Down
6 changes: 3 additions & 3 deletions bot/modules/lbcTipper.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ function doWithdraw(message, tipper, words, helpmsg) {
}
lbc.sendFrom(tipper, address, Number(amount), function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
message.channel.send({
embed: {
Expand Down Expand Up @@ -263,7 +263,7 @@ function doTip(bot, message, tipper, words, helpmsg) {
function sendLBC(bot, message, tipper, recipient, amount, privacyFlag) {
getAddress(recipient.toString(), function (err, address) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
lbc.sendFrom(
tipper,
Expand All @@ -274,7 +274,7 @@ function sendLBC(bot, message, tipper, recipient, amount, privacyFlag) {
null,
function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
if (privacyFlag) {
let userProfile = message.guild.members.get(recipient); // ⚑ Bolt: O(1) direct ID lookup vs O(N) linear search;
Expand Down
6 changes: 3 additions & 3 deletions bot/modules/protonTipper.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ function doWithdraw(message, tipper, words, helpmsg) {
}
proton.sendFrom(tipper, address, Number(amount), function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
message.channel.send({
embed: {
Expand Down Expand Up @@ -263,7 +263,7 @@ function doTip(bot, message, tipper, words, helpmsg) {
function sendPROTON(bot, message, tipper, recipient, amount, privacyFlag) {
getAddress(recipient.toString(), function (err, address) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
proton.sendFrom(
tipper,
Expand All @@ -274,7 +274,7 @@ function sendPROTON(bot, message, tipper, recipient, amount, privacyFlag) {
null,
function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
if (privacyFlag) {
let userProfile = message.guild.members.get(recipient); // ⚑ Bolt: O(1) direct ID lookup vs O(N) linear search;
Expand Down
6 changes: 3 additions & 3 deletions bot/modules/pxcTipper.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ function doWithdraw(message, tipper, words, helpmsg) {
}
pxc.sendFrom(tipper, address, Number(amount), function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
message.channel.send({
embed: {
Expand Down Expand Up @@ -263,7 +263,7 @@ function doTip(bot, message, tipper, words, helpmsg) {
function sendPXC(bot, message, tipper, recipient, amount, privacyFlag) {
getAddress(recipient.toString(), function (err, address) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
pxc.sendFrom(
tipper,
Expand All @@ -274,7 +274,7 @@ function sendPXC(bot, message, tipper, recipient, amount, privacyFlag) {
null,
function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
if (privacyFlag) {
let userProfile = message.guild.members.get(recipient); // ⚑ Bolt: O(1) direct ID lookup vs O(N) linear search;
Expand Down
6 changes: 3 additions & 3 deletions bot/modules/rvnTipper.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ function doWithdraw(message, tipper, words, helpmsg) {
}
rvn.sendFrom(tipper, address, Number(amount), function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
message.channel.send({
embed: {
Expand Down Expand Up @@ -263,7 +263,7 @@ function doTip(bot, message, tipper, words, helpmsg) {
function sendRVN(bot, message, tipper, recipient, amount, privacyFlag) {
getAddress(recipient.toString(), function (err, address) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
rvn.sendFrom(
tipper,
Expand All @@ -274,7 +274,7 @@ function sendRVN(bot, message, tipper, recipient, amount, privacyFlag) {
null,
function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
if (privacyFlag) {
let userProfile = message.guild.members.get(recipient); // ⚑ Bolt: O(1) direct ID lookup vs O(N) linear search;
Expand Down
6 changes: 3 additions & 3 deletions bot/modules/ufoTipper.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ function doWithdraw(message, tipper, words, helpmsg) {
}
ufo.sendFrom(tipper, address, Number(amount), function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
message.channel.send({
embed: {
Expand Down Expand Up @@ -267,7 +267,7 @@ function doTip(bot, message, tipper, words, helpmsg) {
function sendUFO(bot, message, tipper, recipient, amount, privacyFlag) {
getAddress(recipient.toString(), function (err, address) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
ufo.sendFrom(
tipper,
Expand All @@ -278,7 +278,7 @@ function sendUFO(bot, message, tipper, recipient, amount, privacyFlag) {
null,
function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
if (privacyFlag) {
let userProfile = message.guild.members.get(recipient); // ⚑ Bolt: O(1) direct ID lookup vs O(N) linear search;
Expand Down
6 changes: 3 additions & 3 deletions bot/modules/vtlTipper.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ function doWithdraw(message, tipper, words, helpmsg) {
}
vtl.sendFrom(tipper, address, Number(amount), function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
message.channel.send({
embed: {
Expand Down Expand Up @@ -263,7 +263,7 @@ function doTip(bot, message, tipper, words, helpmsg) {
function sendVTL(bot, message, tipper, recipient, amount, privacyFlag) {
getAddress(recipient.toString(), function (err, address) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
vtl.sendFrom(
tipper,
Expand All @@ -274,7 +274,7 @@ function sendVTL(bot, message, tipper, recipient, amount, privacyFlag) {
null,
function (err, txId) {
if (err) {
message.reply(err.message).then((message) => message.delete(10000));
console.error(err); message.reply("An internal error occurred. Please try again later.").then((message) => message.delete(10000));
} else {
if (privacyFlag) {
let userProfile = message.guild.members.get(recipient); // ⚑ Bolt: O(1) direct ID lookup vs O(N) linear search;
Expand Down