Skip to content

add bank-bridge - #14607

Open
theshane0314 wants to merge 1 commit into
runelite:masterfrom
theshane0314:add-bank-bridge
Open

add bank-bridge#14607
theshane0314 wants to merge 1 commit into
runelite:masterfrom
theshane0314:add-bank-bridge

Conversation

@theshane0314

Copy link
Copy Markdown
Contributor

Adds Bank Bridge — serves your bank, inventory, worn equipment and real levels to a gear-planning website over a local-only WebSocket. There is no server, no account, no token and no telemetry; nothing leaves the machine.

Source: https://github.com/theshane0314/bank-bridge-plugin

What it does

Binds a WebSocket to 127.0.0.1, first free port in 37767-37776 — the same range WikiSync uses, deliberately, so a page can scan one range and find whichever plugin is installed. A page connects and requests GetBank; it gets back item ids and quantities plus real skill levels. Browsers allow this from an https:// page because loopback is a potentially trustworthy origin, which is the same mechanism the wiki's DPS calculator already relies on.

Security

I've flagged the relevant points myself rather than leave them to be found:

  • Binds 127.0.0.1 explicitly, not a wildcard bind plus a firewall rule.
  • A WebSocket is not subject to same-origin, so every handshake's Origin is checked against an allowlist (osrs.plaincandle.dev, localhost, 127.0.0.1, plus a user config field). Missing Origin is rejected; anything else is closed before a byte is sent.
  • Known limit, stated in the listing warning and the README: a native program already running on the user's machine can forge Origin. It could equally read the RuneLite directory, so it isn't an escalation — but it is not claimed as a boundary against local software. The boundary is against websites.
  • It cannot observe a bank PIN. A PIN is entered on a widget, and the plugin references no widget reads, no key or mouse listeners, no varbit/varclient reads, no chat, menu or script hooks. Its whole contact with the client is five calls: game state, local player, real skill levels, account hash (used only to name a local cache file), and the containers ItemContainerChanged hands it. A Gradle task accountSafetyCheck fails the build on any reference to those APIs and gates build, check, run, runHarness and shadowJar; it's tested by planting a deliberate violation and confirming the build breaks.
  • No reflection, no native code. One runtime dependency, Java-WebSocket, with its transitive slf4j-api excluded so the client's own version is used.

Threading

All game reads happen on the client thread inside ItemContainerChanged / StatChanged / GameTick and are cached as immutable lists behind volatile references. WebSocketManager holds no reference to Client or ClientThread, so a socket request is answered from cache and can never reach — let alone block — the client thread. Sends run on a daemon executor; the disk write is debounced and also off-thread.

Testing

./gradlew runHarness boots the real WebSocketManager against a seeded store and drives it with a real WebSocket client — 22 checks covering origin accept/reject/missing, protocol, payload shape, error handling, config gating and port release. Nothing under test is mocked. Verified in-game against a live account, and port fallback confirmed live with WikiSync holding 37767.

@runelite-github-app

runelite-github-app Bot commented Aug 2, 2026

Copy link
Copy Markdown

@runelite-github-app

Copy link
Copy Markdown

This plugin requires a review from a Plugin Hub maintainer. The reviewer will request any additional changes if needed.


Internal use only: Reviewer details Maintainer details

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant