This document describes how to report a security issue with the Sijka Builder
Fee Approval page (approve.sijka.xyz) and what the project considers
in-scope and out-of-scope.
For implementation details of the defenses themselves, see the Security model section of the README.
Please email reports to prt1sn@proton.me.
Telegram is also fine for first contact: @SijkaRobot (mention the word "security" in the first message so it routes correctly).
The same contacts are listed in our security.txt, served
at https://approve.sijka.xyz/.well-known/security.txt.
- A clear description of the issue and its impact.
- Steps to reproduce (URL, browser, wallet, network state if relevant).
- Proof-of-concept code or screenshots when applicable.
- Your preferred attribution (real name / handle / anonymous).
| Stage | Target |
|---|---|
| Acknowledge receipt | within 72 hours |
| Initial assessment + severity rating | within 7 days |
| Mitigation in production | severity-dependent (critical: ≤72h; high: ≤14d) |
| Public disclosure (coordinated) | after fix is deployed and users had time to update approvals |
We will keep you informed throughout. If you don't hear back within 72 hours, please ping the Telegram contact above — email can occasionally be lost.
The worst-case attack we defend against:
A user lands on
approve.sijka.xyz, clicks "Approve", and ends up signing an EIP-712 payload that authorizes a different builder address or a higher fee cap than what the page displays — without realizing it.
Any vector that leads to this is critical and in scope. The most important defenses against it are:
- The page is plain static files with no external script sources (see
the CSP —
script-src 'self' 'unsafe-eval', no third-party JS is allowed to execute). - The builder address and fee rate are constants compiled into
app.js, not derived from URL parameters, DOM input, or fetched data. There is no user-controllable surface that can change what gets signed. - The full builder address is displayed in the page UI for the user to compare byte-for-byte against what their wallet shows in the signature prompt.
- Page refuses to operate over plain HTTP —
app.jsaborts immediately iflocation.protocol !== 'https:', in addition to HSTS preload at the browser level. - No subresource is mutable by a third party — Tailwind is self-hosted (verified to be byte-identical to the official build, see the manifest).
- The page at
https://approve.sijka.xyzand any subpath served from it. - The static assets in this repository (
index.html,app.js,styles.css,tailwind-config.js,tailwind.js,security.txt, logo/favicon). - The reverse-proxy and TLS configuration that serves them
(see
Caddyfile.examplefor the reference setup). - The deployment posture documented in
the README
(Cloudflare proxy, Origin Certificate,
ufwlockdown to CF ranges,fail2banreading the real client IP).
The following are not considered project vulnerabilities. Please don't file them — they're documented here so you don't waste time:
- Hyperliquid protocol issues. Builder fees, signature validation, and
the
/exchangeand/infoendpoints are implemented by Hyperliquid. Report those to https://hyperliquid.gitbook.io/hyperliquid-docs/. - Wallet vulnerabilities. MetaMask, OKX, Rabby, Phantom, Coinbase, etc. Report to their respective security teams.
- Cloudflare Email Obfuscation injecting
<script src="/cdn-cgi/scripts/email-decode.min.js">into the HTML. This is a CF feature that protects the contact email from scrapers; it doesn't affect page behaviour. It does cause the servedindex.htmlto differ in bytes from the file in this repo — that's a known trade-off, see the README note. - Scam Sniffer / wallet-extension phishing warnings on a fresh domain. These are expected for any new builder app until we're added to their allowlists. We are submitting.
- Reports based on the
'unsafe-eval'CSP directive. This is currently required by the Tailwind Play CDN JIT compiler. We're aware; a precompiled Tailwind build is the planned long-term mitigation. - Self-XSS (pasting attacker code into your own browser console).
- Lack of rate limiting on a static page that performs no server-side
work. There is nothing to rate-limit on our side — submissions go directly
to
api.hyperliquid.xyz. - Username enumeration, password complexity, account lockout — the page has no accounts.
- Issues only reproducible on end-of-life browsers (anything older than the current and previous major release of Chrome / Firefox / Safari).
- Phishing copies of the page hosted on other domains. Please report
these to wallet phishing-lists (MetaMask
eth-phishing-detect, Scam Sniffer) rather than to us; we'll happily coordinate but the mitigation lives in those projects.
- Any way to get a wallet to sign a different builder address, fee rate, or
domain than what
app.jsconstructs. - CSP bypass that allows third-party script execution from the page.
- DOM-based or stored XSS in any of the page assets.
- Way to make the page operate when loaded over HTTP/
file://. - Origin-IP discovery that bypasses the Cloudflare proxy lockdown.
We follow coordinated disclosure: we'd appreciate a chance to fix the issue and notify any affected users before public details are published.
There is no required embargo period, but we'd ask for at least 14 days after acknowledgement (or earlier if the fix is already live) before publishing technical details.
We will publicly credit reporters in the project changelog / repository unless they request anonymity.
We don't currently run a paid bounty program. The project is small and unfunded. We're happy to issue public acknowledgements, signed thank-yous, and reference letters where helpful. If usage of the page grows and a bounty makes sense, we'll set one up and announce it here.
Reporters who helped us close real issues will be listed here.
(empty — be the first :))