Skip to content

v4.1.0 - MacOS - #261

Merged
Anof-cyber merged 20 commits into
masterfrom
dev
Oct 18, 2026
Merged

Anof-cyber merged 20 commits into
masterfrom
dev

Conversation

@Anof-cyber

Copy link
Copy Markdown
Member

Pull Request

⚠️ IMPORTANT - READ BEFORE SUBMITTING

Required Pre-Submission Checklist

  • I have read the CONTRIBUTING.md file
  • I have created a GitHub issue for this change and linked it below
  • I have forked the dev branch (NOT master)
  • I understand that the master branch is ONLY updated when a new release is created
  • I understand that pull requests to master will be REJECTED

⛔ Critical Information

DO NOT submit a pull request directly to the master branch. The master branch is only updated when a new release is created. No direct commits or merges are accepted to master - neither from the InterceptSuite team nor from contributors.

All changes MUST be submitted to the dev branch, which contains the latest code and commits.

You MUST create a GitHub issue first before submitting a pull request. This allows the InterceptSuite team to:

  • Verify if the bug is already fixed in the development branch
  • Confirm if a new feature is accepted and approved
  • Avoid duplicate work

Pull requests without an associated issue will be rejected.


Pull Request Details

Type of Change

  • Bug Fix
  • New Feature
  • Code Improvement/Refactoring
  • Documentation Update
  • Other (please describe):

Related GitHub Issue

Issue Link:

Platform(s) Affected

  • Windows
  • macOS
  • Linux
  • Cross-platform/All

macOS Application Changes

Does this pull request include changes to the macOS application?

  • Yes
  • No

If YES, you MUST answer the following:

macOS Code Signing & Verification

  • I have signed the macOS app with a valid Apple Developer account
  • I have run the signed application on macOS to verify my changes work as expected
  • I confirm the application launches and functions correctly with my changes

⚠️ Important: If you cannot sign the macOS app to verify your code changes work, please DO NOT submit this pull request. Instead, use the GitHub issue you created to let the InterceptSuite team fix the bug or add the feature. You will need to wait for the next release.


Description of Changes

What does this pull request do?

How has this been tested?

  • Test environment (OS, version, etc.):
  • Test steps:
  • Test results:

Compilation & Dependencies

  • I have reviewed the CONTRIBUTING.md file for compilation instructions
  • I have verified all required libraries and packages are documented
  • My changes compile without errors
  • My changes do not introduce new dependencies (or I have documented them below)

New dependencies (if any):


Screenshots/Logs (if applicable)


Additional Context


Final Checklist

  • My code follows the project's coding style
  • I have commented my code, particularly in hard-to-understand areas
  • I have updated documentation as needed
  • My changes do not generate new warnings or errors
  • I have tested my changes on the target platform(s)
  • I have verified this change is based on the latest dev branch
  • I understand that pull requests without an associated GitHub issue will be rejected

Anof-cyber and others added 20 commits October 17, 2026 22:41
…ith administrator rights

The finish-page checkbox launched ProxyBridge.exe directly from the elevated installer, so the app inherited admin rights and kept them until restarted, which defeats the engine-service design (the app is meant to run as a normal user). It is now started through Explorer, which runs it with the signed-in user's normal rights.
…#205)

By default the Connections log shows a connection once per (process, destination, port, action). The new Settings option logs every new TCP connection and every new UDP flow (a flow = process + local port + destination + action; logged again only after 30 s of silence so busy or blocked UDP senders do not flood the log). Off by default, saved per profile (LogEveryConnection), applied through a new engine call and service message (protocol version 4). Rules are unaffected; only what is listed changes. README updated.
…nsion

- fix the retain cycle UDPAssociation -> NWUDPSession -> read handler -> UDPAssociation
  that kept every UDP flow's association, session, control connection and flow
  alive after teardown (found with `leaks`); the handler now holds the association
  weakly and release() swaps it out before cancelling
- pre-parse rules once when they are added instead of per connection, ignore empty
  list segments so "Safari;" no longer matches every process
- cache the socks5 udp header and relay endpoint per destination
- track pending proxy handshakes in the shared sweep timer instead of one timer
  closure per flow
- close the relay and cancel the proxy connection on every error path, check
  socks5 name/credential lengths (UInt8 overflow trap)
- on client EOF send a FIN upstream and tear down after a short grace

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…sed (#233)

applicationShouldTerminateAfterLastWindowClosed let AppKit decide, and on
macOS 26 dismissing the status item menu counts as the last window closing.
It now always returns false, and closing the main window quits explicitly when
"Close to Menu Bar" is off.
- release-mac/windows/linux no longer run on release events. each one is a
  workflow_dispatch with a required `tag` input, checks out that tag and attaches
  its installer to that release, so a release for one OS does not build the others
- macOS workflows read the pkg version from build.sh instead of a hardcoded
  3.2.0, which made productsign look for a pkg that build.sh never created
- build.sh fails when its VERSION differs from MARKETING_VERSION in the Xcode project
The system extension is only replaced when its version changes, so the build
number is bumped to keep upgrades from earlier test installs working.
…tRules

- socks5 replies are read with exact sizes from the address type, an ipv6 or
  domain reply used to leave bytes in the client's data and a banner sent right
  behind the reply was swallowed
- http connect replies are parsed up to the end of the headers and any 2xx opens
  the tunnel (a "200" anywhere in a 407 used to count), bytes after the headers
  are delivered to the client first
- rules are evaluated before any proxy config is checked, so BLOCK and DIRECT
  rules work with no proxy (udp included), a rule routing to a missing proxy or
  udp to an http proxy is logged once instead of silently going direct
- new setRules message replaces the whole rule list atomically, no window where
  new connections are matched against a half built list

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Falls back to clear + add for an extension that predates setRules.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Both providers run in the same extension process, so the json file was only
extra work (a write per new address, a stat per connection, a re-parse on
change) and left the visited domains on disk. Removes the file older versions
wrote, caps domains per address and returns the newest first.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The old loop walked the file one byte at a time through an async sequence and
held it all in memory. Adds timeouts, throttled progress and a safe file name,
and updates the stale fallback version.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…dows app

When a proxy has the option on, TCP connections ask it for the name the app
looked up (socks5 domain address / CONNECT host:port) instead of the ip. The
name is the newest DNS answer for that address and only used for 5 minutes, any
other case falls back to the ip. Names come out of DNS packets, so only letters,
digits . - _ are ever sent (a space or CRLF would inject into the CONNECT line)
and an ip literal is not treated as a name.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
On by default for new proxies and for proxies saved before the option existed,
the same default as the windows app. Sent to the extension with the proxy config.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
MacOS/tests holds the checks that caught the UDP association leak, the proxy
reply parsing bugs and the BLOCK-without-proxy bug:

- pbtest.py runs the end-to-end suites against the installed app (routing,
  SOCKS5/HTTP/auth, DIRECT, BLOCK, UDP, reply parsing, per-proxy hostnames,
  stress, DNS, idle UDP reaper, leaks). servers.py provides the local test
  proxies, pbudp.c the UDP client, pbtest.pbprofile imports the five test
  proxies and ten rules in one step
- logic/run.sh compiles the matcher and DNS map tests against the real
  extension sources, no installed extension needed

The end-to-end suites need the system extension approved, so they run locally.
Root .gitignore ignores *.py, this folder re-includes them.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- add a Linux job (c-cpp) that builds the library, eBPF program, CLI and GTK GUI
  with build.sh under CodeQL, with its own category so it does not replace the
  Windows c-cpp results
- the Windows job compiled 4 of 15 C files (one of 11 core files, none of the
  service). it now compiles every .c file of the core, service, CLI and GUI
  from the folders, fails on a compile error and fails if C code appears
  outside the covered folders. the Linux job has the same guard
- rename the jobs to "Analyze (c-cpp, windows)", "Analyze (swift, macos)" and
  "Analyze (c-cpp, linux)". categories of the existing jobs are unchanged

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…osetta

distribution.xml had no hostArchitectures, so the Installer on Apple silicon
assumed an Intel-only package and offered to install Rosetta, even though the
app and the system extension are universal. The options element now lists
x86_64 and arm64.

Checked in a clean macOS VM without Rosetta: the old package shows "To install
ProxyBridge, you need to install Rosetta", the new one goes straight to the
normal installer.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…nown issues

Supported: Windows 4.2.x, macOS 4.1.x, Linux 4.x.x. Adds accepted risks
(plaintext credentials and exported profiles, update download verified by HTTPS
only, full Network Extension entitlement set, unvalidated imports, no
app/extension heartbeat, down proxy is not bypassed) and known issues (UDP only
through SOCKS5, UDP rules match on the process on macOS, half-closing clients).
Describes the DNS proxy provider and the in-memory domain table on macOS.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ic PR check

- CONTRIBUTING.md: a "read this first" section with why the guidelines are
  strict (three code bases, one maintainer), the five rules (dev only, complete
  template, issue commented on first, signed macOS testing, existing tests must
  pass), macOS build/signing/test details, a Linux setup and a Testing section
- pull request templates for Windows, macOS and Linux plus a default one. All ask
  for local test details (what was run, result, failures, tests added/removed),
  macOS also asks for signing details. No checkboxes to tick by hand
- PR Check workflow: closes pull requests that do not target dev (with a
  comment), labels and comments on missing issue/template details. Maintainers,
  same-repository branches and bots are skipped. Runs with pull_request_target
  and never checks out pull request code

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ned runner and installer launcher

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@github-advanced-security

Copy link
Copy Markdown
Contributor

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Comment thread MacOS/tests/pbtest.py
def events(since):
out = []
try:
for line in open(LOG):
Comment thread MacOS/tests/pbtest.py
return
# servers.py prints asyncio shutdown noise when it is stopped, keep that out of the test output
_servers = subprocess.Popen([sys.executable, os.path.join(HERE, "servers.py")], stdout=subprocess.DEVNULL,
stderr=open(os.path.join(WORK, "servers.err"), "w"), env=os.environ)
Comment thread MacOS/tests/pbtest.py
check("C1 --version", v.returncode == 0 and v.stdout.startswith("ProxyBridge CLI "), v.stdout.strip() or v.stderr.strip())
bad = subprocess.run([app, "--cli", "--bogus"], capture_output=True, text=True)
check("C2 unknown option exits with 2 and a message", bad.returncode == 2 and "Unknown option" in bad.stderr, f"exit {bad.returncode}")
profile = open(os.path.join(HERE, "pbtest.pbprofile")).read()
Comment thread MacOS/tests/pbtest.py
continue
if e["t"] >= since:
out.append(e)
except FileNotFoundError:
Comment thread MacOS/tests/servers.py
await w.drain()
if w.can_write_eof():
w.write_eof()
except Exception:
Comment thread MacOS/tests/servers.py
for w in (cw, uw):
try:
w.close()
except Exception:
Comment thread MacOS/tests/servers.py
ev("udp_pkt", proxy=self.name, dest=host, port=port)
try:
self.transport.sendto(data[off:], (host, port))
except Exception:
Comment thread MacOS/tests/servers.py
ev("tcp_closed", proxy=name, src=peer[1], active=active["tcp"])
try:
w.close()
except Exception:
Comment thread MacOS/tests/servers.py
ev("tcp_closed", proxy=name, src=peer[1], active=active["tcp"])
try:
w.close()
except Exception:
@Anof-cyber
Anof-cyber merged commit fe1cedf into master Oct 18, 2026
13 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants