Binance’s $6.3B incident: what happened and how to reduce the risk
A compromised employee computer can put far more than local files at risk. We examine the Binance attack and show how controlled automation with Semaphore UI can limit what an attacker can reach, change and keep using.
Overview
On 29 October 2026, attackers reached Binance’s wallet signing systems. In its 3 November preliminary report, Binance put the affected assets at approximately $6.34 billion, with $2.85 billion frozen or intercepted. The intrusion began on employee computers.
That starting point is familiar far beyond cryptocurrency. A compromised workstation can expose production credentials, deployment rights and internal tools that provide a route to other employees’ devices. The engineering challenge is to keep those permissions from turning one compromised account into control of a critical service.
How the attack unfolded
Binance’s preliminary findings describe employee compromises in June and September, followed by a wider intrusion through internal AI tooling on 20 October. Attackers reached two colleagues’ computers and found a token for deploying containers. On 29 October, they used it to deploy malicious code that reached wallet signing systems and initiated unauthorized transfers.
-
Tampered Homebrew installer
Binance replaced the device and rotated credentials. The attacker had learned the engineer’s role and colleagues.
-
Malicious interview assignment
A malicious repository gave attackers a foothold on another employee’s computer.
-
Deployment token obtained
Internal AI tooling helped attackers reach colleagues and find the token.
-
17:15–19:56 UTC
Malicious container deployed
The stolen deployment token enabled malicious code to reach wallet signing systems.
-
20:05–20:09 UTC
Unauthorized transfers begin
-
23:56 UTC
Final unauthorized transfer settles
-
00:10 UTC
Ethereum delegation revoked
The on-chain permission required its own revocation.
The attackers also used the signing service to create an EIP-7702 delegation: permission for attacker-controlled code to act for an Ethereum wallet. That permission existed on the blockchain, independently of Binance’s withdrawal systems. Stopping withdrawals could not remove it. Binance needed a separate on-chain revocation.
The important distinction is between stopping an activity and removing the authority behind it. Replacing a device, revoking a deployment credential and cancelling a permission inside another system each address a different part of an intrusion.
What the incident reveals about production security
A laptop, a deployment system and a sensitive service do different jobs. The risk grows when access to one automatically opens the next. A stolen token can let an attacker replace software. That software can then act with permissions the employee never had directly.
Four questions help identify where to interrupt that progression:
- Credential exposure. What production access can an attacker obtain from one employee’s device?
- Deployment privileges. Who can change the code that runs with that access?
- Service authorization. Which actions will a sensitive service accept from that code?
- Persistent access. What new permissions could remain after the original account is disabled?
The aim is to limit how authority passes between systems and to identify and revoke any additional access created during an intrusion. The following sections examine four controls that support that goal.
Code inherits its permissions
Identify and revoke new credentials and permissions across all affected systems.
Control 1. Reduce the credentials a laptop can expose
A credential is useful to an attacker because another system accepts it as proof of authority. Keeping fewer production credentials on employee devices reduces what can be stolen when a tool, repository or browser session is compromised.
For routine work, an employee often needs permission to request an operation, such as restarting a service. The credential that performs it can stay with a separate execution identity. Reducing exposure then involves both removing unnecessary copies and managing the credentials that remain:
- Replace routine direct access with narrowly defined operations where practical.
- Use separate identities for separate duties and limit their scope and lifetime.
- Keep an inventory of credentials, their owners and how to revoke them.
This applies the principle in OWASP’s secret-management guidance: reduce human handling of secrets and grant only the access each identity needs. A stolen workstation then exposes fewer reusable credentials, and responders know who owns those that still need revoking.
Control 2. Treat deployment rights as production privileges
A secret can be hidden from a person but available to the code they deploy. Whoever can change that code may be able to read the secret, call an internal API or act as the application’s service account. Deployment access must therefore be assessed against the permissions of the resulting workload.
OWASP’s CI/CD security guidance treats repository changes, pipeline configuration and execution hosts as parts of the same security problem. Protection needs to cover the code before deployment and its permissions after deployment:
- Require review for production code and protect the repository branch that automation executes.
- Control changes to task definitions, dependencies and launch-time inputs as well as the main script.
- Give workloads only the credentials and network access needed for their function.
Two sets of controls must work together. Repository and deployment permissions determine who can change the code. Separate identity, host and network policies limit what that code can do once it runs. Central secret storage reduces exposure, while those policies constrain the program that uses the secret.
Control 3. Authorize the operation, not just the caller
A signing service can keep its private key hidden and still accept a harmful signing request. The same distinction applies to a database or cloud API: authenticating a workload identifies the caller, while authorization decides what it may do.
OWASP recommends checking authorization on every request and denying access unless it is explicitly allowed. At the receiving service, that means checking both the action and its target: permitted payment destinations and amounts, database operations or infrastructure changes.
The outcome should be a service that evaluates the requested action even when the caller is already trusted. Automation governs how work is requested. The receiving service governs which operations it will accept.
Control 4. Revoke access created during the intrusion
An attacker may use a legitimate identity to add another credential or grant further permissions. MITRE ATT&CK documents account manipulation as a way to preserve or increase access, including adding cloud credentials and SSH keys. Disabling the original session does not necessarily remove those changes.
Binance’s on-chain delegation illustrates why responders must inspect permissions in the affected system itself. Containment needs to cover both the initial foothold and the authority created through it:
- Limit which automation identities can create further credentials or grant permissions.
- Include newly created accounts, sessions and delegations in the response plan.
- Verify revocation at the system that enforces the permission, rather than treating a stopped task as proof of containment.
Following those steps gives responders a defined set of identities and permissions to investigate and revoke. It also makes containment testable: the team can check whether each known route into the affected service has actually closed.
These controls operate at different layers: the employee’s device, the deployment system, the receiving service and the response process. Each needs an owner and a way to verify that its restrictions hold when another layer is compromised.
How controlled automation helps
Automation management platforms address the part of this problem between an employee’s request and production execution. In Semaphore UI, a team can prepare a defined task, control who may run or change it, and execute it with a separate identity. Authorization inside the target service and revocation of permissions created elsewhere remain the responsibility of those systems and the response team.
Consider an on-call engineer who needs to restart an API service. A maintainer prepares a playbook and a Task Template that fixes the target hosts and how the restart runs. The engineer starts the task and reads the result, without opening an SSH session to production. The two paths below perform the same restart but place the execution credential in different hands.
Direct access
Service restarts
A compromised laptop may expose the reusable production credential.
Through Semaphore UI
Permission to run the saved task
Service restarts
In this configuration, the execution key stays off the employee’s device. A stolen session can still run its permitted tasks.
Building the restart workflow takes four connected steps: create a restricted execution identity, define what users may run or change, choose its execution environment, and make the result visible. Once those steps are in place, the same approach can be extended to deployments.
Step 1. Create a restricted execution identity
Start on the target hosts. Create an automation account whose privileged access is limited to restarting the API service. It should not be able to edit the service definition or run unrelated privileged commands. Use a separate, read-only credential to fetch the playbook repository. These restrictions determine what the automation can do even if its credential is misused.
In the project’s Key Store, register the SSH credential and select it in the production inventory that lists the target hosts. Choose local database storage or reference a protected server file or environment variable. For local storage, configure encryption keys and protect the key material separately from database backups.
If the team already uses a supported secret store, such as OpenBao in Pro or AWS Secrets Manager in Enterprise, register it under Key Store → Storages and reference the existing secret when creating the key. Restrict the integration to the secrets this workflow needs. The operator can then request the restart without retrieving its execution credential.
Step 2. Define what the operator may run or change
Next, save a “Restart API” template with the reviewed playbook, production inventory and required variables. Keep changes to those resources with maintainers. For operators, select a project role that allows execution without editing: the built-in Task Runner role can run every template in that project, so all of them must be appropriate for that group.
For access to selected templates, use Enterprise custom roles and template permissions with a base role that does not already grant project-wide execution. These grants are additive, so assigning a narrow custom role does not cancel broader permissions the user already holds.
This makes the distinction enforceable: operators may request a prepared restart, while maintainers control the code, targets and credentials behind it. Test the combined permissions with an operator account before granting production access.
Step 3. Put execution on a restricted runner
Install a remote runner on a dedicated host that can reach the API servers. When the operator starts “Restart API”, the runner executes the playbook and returns its output to Semaphore. Employees need access to Semaphore, while firewall rules can restrict the production management connection to the runner.
Give that execution host only the access needed for its assigned tasks:
- Separate production execution from less-trusted workloads and development environments.
- Limit the runner’s OS privileges, outbound connections and mounted credentials. Protect its authentication token and use verified HTTPS to connect to Semaphore.
- Use runner tags in Pro, such as
production, to route the template to the intended runners. Enforce the network restrictions on those hosts.
This narrows where production credentials can be used and which systems the task can reach. A runner is not an automatic sandbox: its tasks can use the files, credentials and network available to their process. Keep production execution separate from untrusted jobs, and harden and patch both the runner and Semaphore server.
Step 4. Review the run and make misuse visible
After the restart, the operator opens the task result to inspect its status, output and repository revision. Include a service health check in the playbook so the result shows whether the API recovered, not just whether the restart command returned successfully. Keep secrets out of that output.
Configure task result notifications for a channel the on-call team monitors, and agree who investigates unexpected runs. A successful task can still be unauthorized activity. During an investigation, correlate the execution record with host, identity-provider and secret-store logs to see how access was obtained and used.
The team now has a shared record of the requested operation and its outcome. That makes unusual activity easier to investigate, provided somebody monitors it and has a clear response procedure.
Applying the same controls to deployments
A deployment uses the same access model but also installs software. Create a separate “Deploy API” template with a deployment identity whose permissions are limited to that application. Its configuration needs to constrain both the code performing the deployment and the release it installs:
- Fix the deployment code and target. Use
deploy_api.ymlfrom a protectedmainbranch and theproduction-apiinventory. Disable branch, inventory and CLI-argument prompts. - Keep changes with maintainers. Operators may launch the template, while maintainers control its code, credentials and configuration.
- Validate release selection in the playbook. Check every launch-time variable that can influence the release. Resolve an allowed release identifier to an immutable artifact from the trusted build process and verify its origin and integrity before deployment. Reject arbitrary image references or unrecognized inputs.
These controls limit what a stolen operator session can deploy. Semaphore enforces task access. Git review and the playbook constrain code and artifacts. Permission to change that playbook remains a production privilege.
Whether the task restarts a service or deploys a release, the operator receives its result without receiving the execution credential. The team can now test the distinction that matters: which production actions remain possible through that operator’s session?
What a stolen session can still do
A stolen operator session can still request the operations that account is allowed to run. Even a permitted restart can disrupt a service if repeatedly triggered. Test the configured workflow with a realistic operator account in staging, covering both what it can do and how the team would respond to misuse:
- Task and input permissions. Try the actual roles and launch-time options, including alternative branches, inventories and arguments.
- Access beyond the intended operation. Check access to other templates, credentials and production systems, including what the runner’s process can reach.
- Detection and operational impact. Confirm who receives results, who investigates unexpected activity and whether repeated runs can cause unacceptable disruption.
- Revocation. Test session and token revocation, and identify any permissions the execution identity could create elsewhere.
Document the access the test account retains and close any route that exceeds the operation’s purpose. The team should finish the exercise knowing both what a stolen session could do and how to detect and contain that misuse.
Security in everyday work
Access controls work alongside endpoint protection and a team that knows how to respond. Make the prepared workflow convenient enough that people can use it without falling back to shared keys and undocumented shortcuts. Support it with a few everyday practices:
- Run unfamiliar installers and interview assignments in disposable, isolated environments without corporate credentials, host mounts or access to internal networks.
- Make suspicious activity easy to report early and without blame. Give people a clear contact and an incident-response path.
- Review access as duties change, maintain a controlled emergency-access procedure and rehearse revocation before an incident.
These practices connect prevention, detection and recovery to day-to-day work. They help keep the access model accurate as responsibilities change and give the team a familiar response when a suspicious event occurs.
Limit the reach of the next compromise
The central lesson is to limit how much authority one compromised identity can accumulate. Fewer credentials on laptops, reviewed automation, restricted execution hosts and authorization inside production services each reduce the routes an attacker can take.
Semaphore makes several of those controls part of a repeatable workflow: prepared tasks, separate run and edit permissions, centrally supplied credentials and visible execution records. Operators get the actions their jobs require, while maintainers retain control over the code and credentials behind them.
Start with one frequently used production operation: prepare its task template, assign the necessary operator permissions, and test the resulting access before retiring the direct connection it replaces. The useful measure of progress is how little an attacker can do with the next account they compromise.
Sources
- Binance, “29 October 2026 Binance Security Incident: Initial Findings and Response Update”. URL: https://www.binance.com/en/blog/community/3229153443759566763 (accessed: ).
- OWASP Foundation, “Secrets Management Cheat Sheet”. URL: https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html (accessed: ).
- OWASP Foundation, “CI/CD Security Cheat Sheet”. URL: https://cheatsheetseries.owasp.org/cheatsheets/CI_CD_Security_Cheat_Sheet.html (accessed: ).
- OWASP Foundation, “Authorization Cheat Sheet”. URL: https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html (accessed: ).
- MITRE ATT&CK, “Account Manipulation (T1098)”. URL: https://attack.mitre.org/techniques/T1098/ (accessed: ).
- Semaphore UI, “Task Templates”. URL: https://semaphoreui.com/docs/user-guide/task-templates (accessed: ).
- Semaphore UI, “Key Store”. URL: https://semaphoreui.com/docs/user-guide/key-store (accessed: ).
- Semaphore UI, “Inventory”. URL: https://semaphoreui.com/docs/user-guide/inventory (accessed: ).
- Semaphore UI, “Encryption Keys”. URL: https://semaphoreui.com/docs/admin-guide/security/encryption (accessed: ).
- Semaphore UI, “AWS Secrets Manager secret storage”. URL: https://semaphoreui.com/docs/user-guide/key-store/aws-secrets-manager (accessed: ).
- Semaphore UI, “Teams”. URL: https://semaphoreui.com/docs/user-guide/team (accessed: ).
- Semaphore UI, “Runners”. URL: https://semaphoreui.com/docs/admin-guide/runners (accessed: ).
- Semaphore UI, “Tasks”. URL: https://semaphoreui.com/docs/user-guide/tasks (accessed: ).
- Semaphore UI, “Alerts”. URL: https://semaphoreui.com/docs/user-guide/alerts (accessed: ).
