fix: add authentication to local mixed inbound to prevent SOCKS5 localhost bypass - #147
Open
godfantom1111-debug wants to merge 1 commit into
Open
Conversation
The local mixed proxy (127.0.0.1:12334) was running without authentication, allowing any app on the device to connect and discover the real VPN server IP — bypassing per-app split tunneling and VpnService isolation entirely, including Android Private Spaces. Fix: generate ephemeral random credentials (crypto/rand) on each startup and set them on the HTTPMixedInboundOptions.Users field, which hiddify-sing-box already supports. The credentials are threaded through to all internal consumers (tunnel service, profile downloads, independent instances) so existing functionality is not broken. Verified with per-app-split-bypass-poc: before the fix the PoC retrieved the server IP via the unauthenticated proxy; after the fix it reports "VPN not found" / "IP via proxy: -". Reported by: https://habr.com/ru/articles/1020080/ PoC: https://github.com/runetfreedom/per-app-split-bypass-poc Changes: - v2/config/hiddify_option.go: add MixedUser/MixedPassword fields - v2/config/builder.go: generate credentials, set Users on inbound - extension/system/admin_service_vpn/admin_tun_service.go: handle TypeMixed in addition to TypeSOCKS for tunnel credential passing - v2/hcommon/request/url_request.go: add SocksUser/SocksPass to Request - v2/hcore/independent_instance.go: thread credentials through - v2/hcore/static_data.go: add ListenUser/ListenPassword fields - v2/hcore/start.go: populate credentials from mixed inbound
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the "localhost attack" vulnerability described in https://habr.com/ru/articles/1020080/ and demonstrated by https://github.com/runetfreedom/per-app-split-bypass-poc
The local mixed proxy (
127.0.0.1:12334) was running without authentication, allowing any app on the device to connect to it directly and discover the real VPN server IP — bypassingVpnService, per-app split tunneling, and Android Private Space isolation entirely.Root cause
builder.go:setInbound()creates aTypeMixedinbound withHTTPMixedInboundOptionsbut leavesUsersempty. Thehiddify-sing-boxfork already supportsUsers []auth.Useron the mixed inbound — it just wasn't being set.Fix
crypto/randon each startup (never hardcoded, never persisted to config files)HTTPMixedInboundOptions.Usersadmin_tun_service.go): now reads credentials fromTypeMixedinbound in addition toTypeSOCKSurl_request.go):Requeststruct now acceptsSocksUser/SocksPassindependent_instance.go): credentials stored and used inContentFromURLUDP concern
Not an issue here: the mixed inbound listener uses
Network: []string{N.NetworkTCP}only — UDP is tunneled over TCP and is therefore protected by the same authentication.Verification
Tested with per-app-split-bypass-poc on a real Android device (Redmi, Android 16, Life operator, Belarus):
IP via proxy: <VPN server IP>Status: VPN not found/IP via proxy: -✅Files changed
v2/config/hiddify_option.goMixedUser/MixedPasswordtoInboundOptions(runtime only,json:"-")v2/config/builder.gocrypto/rand, setUserson mixed inboundextension/system/admin_service_vpn/admin_tun_service.goTypeMixedalongsideTypeSOCKSfor Android VPN tunnelv2/hcommon/request/url_request.goSocksUser/SocksPassfields toRequestv2/hcore/independent_instance.goHiddifyInstance, use inContentFromURLv2/hcore/static_data.goListenUser/ListenPasswordtoHiddifyInstancev2/hcore/start.goListenUser/ListenPasswordfrom mixed inbound optionsThe author of the original vulnerability report explicitly asked the community to submit PRs: «Если мы все вместе обратимся к ним или кто-то пришлёт PR, то это исправят»