10 interesting stories served every morning and every evening.
10 interesting stories served every morning and every evening.
30.04.2026, 11:37 Uhr
Belgium will stop decommissioning its nuclear power plants, Prime Minister Bart De Wever announced on Thursday.
The government is going to negotiate with operator ENGIE over the nationalization of the plants, De Wever said.
“This government chooses safe, affordable, and sustainable energy. With less dependence on fossil imports and more control over our own supply,” he wrote on X.
ENGIE said it signed a letter of intent with the Belgian government on exclusive negotiations.
The agreement covers the potential acquisition of “the complete nuclear fleet of seven reactors, the associated personnel, all nuclear subsidiaries, as well as all associated assets and liabilities, including decommissioning and dismantling obligations,” a press release said.
A basic agreement is expected to be reached by October, it said.
Belgium originally decided in 2003 to phase-out nuclear power production by 2025, but political debate and energy security concerns have led to delays.
Last year the Belgian parliament voted by a large majority to end the nuclear phase-out. De Wever’s government also aims to build new nuclear power plants.
Belgium has seven nuclear reactors at two different sites, although three reactors have already been taken off the grid.
The fate of the ageing installations has been debated for decades. The country is currently heavily dependent on gas imports to cover its electricity needs as it has been struggling to expand renewable power generation significantly.
Bart De Wever on X
ENGIE press release
(c) 2026 dpa Deutsche Presse Agentur GmbH
Skip to content
Secure your code as you build
We read every piece of feedback, and take your input very seriously.
Include my email address so I can be contacted
Use saved searches to filter your results more quickly
To see all available qualifiers, see our documentation.
Sign up
You signed in with another tab or window. Reload to refresh your session.
You signed out in another tab or window. Reload to refresh your session.
You switched accounts on another tab or window. Reload to refresh your session.
Notifications
You must be signed in to change notification settings
You can’t perform that action at this time.
Meta in row after workers who say they saw smart glasses users having sex lose jobs
20 hours ago
Chris VallanceSenior technology reporter
AFP via Getty Images
Meta is under pressure to explain why it cancelled a major contract with a company it was using to train AI, shortly after some of its Kenya-based workers alleged they had to view graphic content captured by Meta smart glasses.
Less than two months later, Meta ended its contract with Sama, which Sama said would result in 1,108 workers being made redundant.
Meta says it’s because Sama did not meet its standards, a criticism Sama rejects. A Kenyan workers’ organisation alleges Meta’s decision was caused by the staff speaking out.
Meta has not addressed that allegation but told BBC News in a statement it had “decided to end our work with Sama because they don’t meet our standards”.
Sama has defended its work.
“Sama has consistently met the operational, security and quality standards required across our client engagements, including with Meta,” it said in a statement.
“At no point were we notified of any failure to meet those standards, and we stand firmly behind the quality and integrity of our work.”
‘Naked bodies’
In late February, Swedish newspapers Svenska Dagbladet (SvD) and Goteborgs-Posten (GP) published an investigation which included the accounts of unnamed workers who had been asked to review videos filmed by Meta’s glasses.
“We see everything - from living rooms to naked bodies,” one worker reportedly said.
At the time of the publication, Meta admitted subcontracted workers might sometimes review content filmed on its smart glasses when people shared it with Meta AI.
It said this was for the purpose of improving the customer experience, and was a common practice among other companies.
However, the revelations have prompted regulators to act.
Shortly after the Swedish investigation, the UK data watchdog, the Information Commissioners Office (ICO) wrote to Meta about what it called a “concerning” report.
The Office of the Data Protection Commissioner in Kenya also announced it was commencing an investigation into privacy concerns raised by the glasses.
In a statement in response to news of the redundancies a Meta spokesperson told the BBC, “last month, we paused our work with Sama while we looked into these claims.
“We take them seriously. Photos and videos are private to users. Humans review AI content to improve product performance, for which we get clear user consent.”
‘Standards of secrecy’
Features can include translating text, or responding to questions about what the user is looking at - particularly useful for those who are blind or partially sighted.
However, as the devices have grown in popularity, so too have concerns about their misuse.
The workers the Swedish newspapers spoke to were data annotators, teaching Meta’s AI to interpret images by manually labelling content.
The workers said they also reviewed transcripts of interactions with the AI to check it had answered questions adequately.
In one instance, a worker told the newspapers, a man’s glasses were left recording in a bedroom where they later filmed a woman, apparently the man’s wife, undressing.
Meta’s glasses have a light in the corner of the frames that is turned on when the built-in camera is recording.
Sama, a US headquartered outsourcing business, which began as a non-profit organisation with the aim of increasing employment through the provision of tech jobs, is now an “ethical” B-corp.
But this is not the first time a contract with Meta has soured.
An earlier deal to moderate Facebook posts attracted criticism, alongside legal action by former employees - some of whom described being exposed to graphic, traumatising content.
Sama later said it regretted taking the work.
Naftali Wambalo of the Africa Tech Workers Movement, who is a petitioner in the continuing legal action around that case, told the BBC he had also spoken with workers involved in the smart glasses contract.
Wambalo believed the reason for Meta’s ending the work was that it didn’t want workers speaking out about human workers sometimes reviewing content captured by the smart glasses.
“What I think are the standards they are talking about here are standards of secrecy,” he told BBC News.
The BBC has asked Meta to respond to this point.
The tech giant has previously said that users were made aware of the possibility of human review in the its terms of service.
Mercy Mutemi a lawyer representing the petitioners, who is also executive director of campaign group the Oversight Lab, said Meta’s statement should be a warning to the Kenyan government.
“We’ve been told that this is our entry route into the AI ecosystem,” she told the BBC. “This is a very flimsy foundation to build your entire industry on.”
Products
Openwall GNU/*/Linux server OS
Linux Kernel Runtime Guard
John the Ripper password cracker
Free & Open Source for any platform
in the cloud
Pro for Linux
Pro for macOS
Wordlists for password cracking
passwdqc policy enforcement
Free & Open Source for Unix
Pro for Windows (Active Directory)
yescrypt KDF & password hashing
yespower Proof-of-Work (PoW)
crypt_blowfish password hashing
phpass ditto in PHP
tcb better password shadowing
Pluggable Authentication Modules
scanlogd port scan detector
popa3d tiny POP3 daemon
blists web interface to mailing lists
msulogin single user mode login
php_mt_seed mt_rand() cracker
Openwall GNU/*/Linux server OS
Linux Kernel Runtime Guard
John the Ripper password cracker
Free & Open Source for any platform
in the cloud
Pro for Linux
Pro for macOS
Free & Open Source for any platform
in the cloud
Pro for Linux
Pro for macOS
Wordlists for password cracking
passwdqc policy enforcement
Free & Open Source for Unix
Pro for Windows (Active Directory)
Free & Open Source for Unix
Pro for Windows (Active Directory)
yescrypt KDF & password hashing
yespower Proof-of-Work (PoW)
crypt_blowfish password hashing
phpass ditto in PHP
tcb better password shadowing
Pluggable Authentication Modules
scanlogd port scan detector
popa3d tiny POP3 daemon
blists web interface to mailing lists
msulogin single user mode login
php_mt_seed mt_rand() cracker
Services
Publications
Articles
Presentations
Articles
Presentations
Resources
Mailing lists
Community wiki
Source code repositories (GitHub)
File archive & mirrors
How to verify digital signatures
OVE IDs
Mailing lists
Community wiki
Source code repositories (GitHub)
File archive & mirrors
How to verify digital signatures
OVE IDs
What’s new
Message-ID: <87se8dgicq.fsf@gentoo.org>
Date: Thu, 30 Apr 2026 05:52:37 +0100
From: Sam James <sam@…too.org>
To: oss-security@…ts.openwall.com
Cc: Jan Schaumann <jschauma@…meister.org>
Subject: Re: CVE-2026 – 31431: CopyFail: linux local privilege
scalation
Eddie Chapman <eddie@…k.net> writes:
> On 29/04/2026 21:23, Jan Schaumann wrote:
>> Affected and fixed versions
>> ===========================
>> Issue introduced in 4.14 with commit
>> 72548b093ee38a6d4f2a19e6ef1948ae05c181f7 and fixed in
>> 6.18.22 with commit
>> fafe0fa2995a0f7073c1c358d7d3145bcc9aedd8
>> Issue introduced in 4.14 with commit
>> 72548b093ee38a6d4f2a19e6ef1948ae05c181f7 and fixed in
>> 6.19.12 with commit
>> ce42ee423e58dffa5ec03524054c9d8bfd4f6237
>> Issue introduced in 4.14 with commit
>> 72548b093ee38a6d4f2a19e6ef1948ae05c181f7 and fixed in
>> 7.0 with commit
>> a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5
>> https://git.kernel.org/stable/c/fafe0fa2995a0f7073c1c358d7d3145bcc9aedd8
>> https://git.kernel.org/stable/c/ce42ee423e58dffa5ec03524054c9d8bfd4f6237
>> https://git.kernel.org/stable/c/a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5
>
> So this is one of the worst make-me-root vulnerabilities in the kernel
> in recent times. I see that on the 11th of April 6.19.12 & 6.18.22
When companies get caught doing this sort of thing, the response is almost always the same: “we’re using this technology to combat fraud,” or “ensure positive user experience,” or “save computing resources,” or some other hog wash.
The simple truth, there’s no reason to be collecting data that can be used to identify a user across the web if they’re not signed in to your service.
The harm of companies like Experian or LinkedIn being able to correlate all of your web traffic back to you is not hard to imagine. Though, it begs a simple question: should a company involved in my professional life have access to my personal information obtained without my explicit consent?
No. End stop.
This is not new
According to records documented by browsergate.eu and a GitHub repository tracking the extension list, LinkedIn’s extension scanning dates to at least 2017, when the list contained 38 entries. My count? As of April 2026, LinkedIn has identified and tracks 6,278 extensions.
The list is actively maintained and expanding.
At this scale the catalog was not built by hand. Someone wrote tooling to crawl Chrome Web Store extension packages, parse each manifest for web-accessible resources, identify a probe target, and add the entry to the list. This is infrastructure that has been in place for nearly a decade.
I verified this myself
I opened LinkedIn in Chrome. I opened developer tools (F12 or Inspect) and the console filled with errors.
Each one of those errors is LinkedIn asking your computer if you have a specific extension installed.
Skip to the bottom for more technical details.
LinkedIn already knows so much about you, why tell them more?
Most fingerprinting operations work against anonymous visitors. The fingerprint allows a site to recognize a returning browser without cookies.
The profile that results is technically identified but not necessarily personally identified. The site knows a device, not a person. Still an issue, but not inherently linked to any personal information.
LinkedIn is not working with anonymous visitors.
LinkedIn knows your name. Employer. Job title. Career history. Salary range. Professional network. Location.
You provided them with all of it.
When LinkedIn’s extension scan runs on your browser, it is not building a device profile for an unknown visitor. It is appending a detailed software inventory to a profile that already contains your verified professional identity.
The harm is specific.
Hundreds of job search extensions are in the scan list. LinkedIn knows which of its users are quietly looking for work before they’ve told their employer.
Extensions tied to political content, religious practice, disability accommodation, and neurodivergence are in the list. Your browser software becomes a source of inferences about your personal life, attached without your knowledge to your professional identity.
And because LinkedIn knows where each user works, none of this is only linked to an individual. The scan results from one employee contribute to a picture of their organization. Across enough employees, LinkedIn can map a company’s internal tooling, security products, competitor subscriptions, and workflows, without that organization’s knowledge or consent. Your browser becomes a window into your employer.
None of this is disclosed in LinkedIn’s privacy policy. There is no mention of extension scanning in any public-facing document. No user was asked for consent. No user was informed.
None of this is disclosed in LinkedIn’s privacy policy
Why this matters beyond LinkedIn
The precedent
LinkedIn is using these extension lists to make inferences and take enforcement actions against users who have them installed. According to browsergate, Milinda Lakkam confirmed this under oath, saying, “LinkedIn took action against users who had specific extensions installed.”
Users who had no idea their software was being inventoried, no idea the inventory was being used against them, and no way to know it was happening because none of it appears in LinkedIn’s privacy policy.
The fingerprinting ecosystem problem
Browser fingerprinting is usually discussed as a tracking problem contained to one site. A site collects signals, builds a profile, recognizes you across sessions. The problem stays local.
That framing understates what’s actually happening.
LinkedIn’s extension scan produces a detailed software inventory linked to a verified identity. That profile doesn’t have to stay at LinkedIn to be useful.
If LinkedIn purchases a third party behavioral dataset and your fingerprint appears in it, they can append that data to what they already know about you. Your browsing behavior off LinkedIn, your purchase history, your location patterns, your interests, all of it becomes part of a profile that is linked to your LinkedIn account.
The reverse is also true. LinkedIn integrates third party scripts including Google’s reCAPTCHA enterprise, loaded on every page visit. Data flows between platforms. A fingerprint that LinkedIn has linked to your verified identity can inform advertising and tracking systems far outside linkedin.com.
You log into LinkedIn once, and the fingerprint that visit produces can follow you across the web.
This is the larger ecosystem problem. Browser fingerprinting is the connective tissue of the modern surveillance economy. It is how profiles built on one platform get enriched with data from another. It is why you get Instagram or Facebook ads for the item you were just looking up on Google.
It is how your professional identity, your browsing behavior, your installed software, and your location history get stitched together into something none of those individual platforms could build alone.
The people this is a real threat to
For the journalists, lawyers, researchers, and human rights investigators, that distinction is operationally significant. Your LinkedIn profile is one of the most detailed verified identity documents that exists about you online. You built it deliberately, for professional purposes, with your real name attached. The extension scan means that profile now includes a record of every privacy tool, security extension, research tool, and productivity application installed in your browser, collected without your knowledge, linked to your verified identity, and transmitted encrypted to LinkedIn’s servers with every action you take on the platform.
If you use LinkedIn and Chrome, this is happening to you right now.
Advanced JavaScript fingerprinting
The extension scan is not a standalone feature. It is part of a broader device fingerprinting system LinkedIn calls APFC, Anti-fraud Platform Features Collection, internally also referred to as DNA, Device Network Analysis.
While LinkedIn is a little more forthcoming about these tracking methods, as they are commonly included on commercial websites, this establishes a sort of pattern of behavior.
That system collects 48 browser and device characteristics on every visit: canvas fingerprint, WebGL renderer and parameters, audio processing behavior, installed fonts, screen resolution, pixel ratio, hardware concurrency, device memory, battery level, local IP address via WebRTC, time zone, language, and more.
The extension scan is one input into a much larger profile.
Technically, what’s happening?
LinkedIn’s code fires a fetch() request to a chrome-extension:// URL, looking for a specific file installed to chrome. When the extension isn’t installed, Chrome blocks the request and logs the failure. When it is installed, the request resolves silently and LinkedIn records it.
The scan ran for around 15 minutes on my computer, and it searched my computer for over 6,000 extensions.
You can verify this yourself. Open LinkedIn in Chrome. Open developer tools. Go to the console tab. Watch what happens. Every red error is a part of your fingerprint.
The code
The system responsible for this lives in some JavaScript code that LinkedIn runs in every Chrome visitors browser. The file is approximately 1.6 megabytes (it’s changed since browsergate’s analysis) of minified and partially obfuscated JavaScript.
Standard minification compresses code for performance. Obfuscation is a separate step that makes code harder to read and understand. LinkedIn chose to obfuscate the exact module containing the extension scanning system, while also burying it in a JavaScript file thousands of lines long.
Inside that file, there is a hardcoded array of browser extension IDs. As of February 2026 that array contained 6,278 entries. Each entry has two fields: a Chrome Web Store extension ID and a specific file path inside that extension’s package.
The file path is not incidental. Chrome extensions expose internal files to web pages through the web_accessible_resources field. When an extension is installed and has declared a file as accessible, a fetch() request to chrome-extension://{id}/{file} succeeds. When it isn’t installed, Chrome blocks the request. LinkedIn has identified a specific accessible file for each of the 6,278 extensions in its list and probes for it directly.
The scan runs in two modes. The first fires all requests simultaneously using Promise.allSettled(), probing all of the extensions in parallel. The second fires them sequentially with a configurable delay between each request, spreading network activity over time and reducing its visibility in monitoring tools. LinkedIn can switch between modes using internal feature flags. The scan can also be deferred to requestIdleCallback, which delays execution until the browser is idle so the user sees no performance impact.
A second detection system called Spectroscopy operates independently of the extension list. It walks the entire DOM tree, inspecting every text node and element attribute for references to chrome-extension:// URLs. This catches extensions that modify the page even if they aren’t in LinkedIn’s hardcoded list. Together the two systems cover extensions that are merely installed and extensions that actively interact with the page.
Both systems feed into the same telemetry pipeline. Detected extension IDs are packaged into AedEvent and SpectroscopyEvent objects, encrypted with an RSA public key, and transmitted to LinkedIn’s li/track endpoint. The encrypted fingerprint is then injected as an HTTP header into every subsequent API request made during your session. LinkedIn receives it with every action you take for the duration of your visit.
The legal context
browsergate.eu has documented the legal arguments in detail and their work is worth reading in full. The relevant context here is this: in 2024, Microsoft was designated as a gatekeeper under the EU’s Digital Markets Act. LinkedIn is one of the regulated products. The DMA requires gatekeepers to allow third party tools access to user data and prohibits gatekeepers from taking action against users of those tools.
browsergate.eu argues that LinkedIn’s systematic enforcement against third party tool users, combined with the covert extension scanning used to identify them, constitutes non-compliance with that regulation. Whether that argument prevails is a legal question.
What is not a question is that a criminal investigation is now open. The Cybercrime Unit of the Bavarian Central Cybercrime Prosecution Office in Bamberg confirmed an investigation. That office handles serious cybercrime cases with cross-jurisdictional reach. This is not a compliance dispute. It is a criminal matter.
I contacted browsergate.eu directly while preparing this piece. They confirmed the criminal investigation, provided the case number, and indicated the full court documents are being prepared for public release.
I will update this article when they are available.
Though wind and solar continue to carve out larger and larger shares of world energy supply, the modern world still runs on petroleum, and will continue to do so for the foreseeable future. The world consumes over 100 million barrels of oil a day. As of 2023, oil was responsible for 30% of all energy use worldwide, higher than any other energy source (though its share has been gradually falling). In chemical manufacturing, petroleum is even more critical: an astounding 90% of chemical feedstocks are derived from oil or gas. Virtually all plastic comes from chemicals extracted from oil or gas, and petrochemicals are used to produce everything from lubricants to paint to plywood to synthetic fabrics to fertilizer.
Our enormous consumption of petroleum is made possible by oil refineries. When oil comes out of the ground, it’s a complex mixture of thousands of different chemicals. Oil refineries take in this mixture and process it, turning it into chemicals we can actually use. Because of the scale of worldwide petroleum consumption, oil refineries are some of the largest industrial facilities in the world. A large oil refinery will occupy thousands of acres and cost billions of dollars to construct, ultimately refining hundreds of thousands of barrels of oil each day.
Oil is a liquid produced from decomposing organic materials, mostly plankton and algae that died and sank to the bottom of ancient oceans. This dead organic matter gradually got covered with sediment, and over millions of years it transformed into crude oil. Crude oil is a mixture of thousands of different chemicals, most of which are hydrocarbons: molecules that are various arrangements of carbon and hydrogen atoms. The molecules in crude oil range from the simple, such as propane (three carbons and eight hydrogens) and butane (four carbons and ten hydrogens) to the complex — some asphaltene molecules in crude oil can contain thousands of individual atoms.1
Crude oils extracted from different parts of the Earth will have different mixtures of hydrocarbons and other molecules, which has given rise to a sort of crude oil taxonomy. “Heavy” crude oils, found in places like Canada’s oil sands, will have more heavy molecules, while “light” crude oils found in places like Saudi Arabia’s Ghawar field will have more light molecules. “Sweet” crudes, like the crudes extracted from the Brent oil field in the North Sea, have lower sulfur content, while “sour crudes,” like some of the crudes extracted from the Gulf of Mexico, have greater sulfur content.
The job of an oil refinery is to process this mixture of hydrocarbons and other molecules: separating the mixture into individual chemicals or groups of chemicals, and using various chemical reactions to change low-value chemicals into more valuable, useful ones.
A refinery makes use of several different methods to separate and process crude oil, but the most important process of all is probably distilling. Different molecules within crude oil boil at different temperatures, and condense back into liquid at different temperatures. Smaller, lighter molecules boil and condense at lower temperatures, while larger and heavier molecules boil and condense at higher temperatures. You can describe this range of boiling points with a distillation curve, which shows what fraction of the crude oil boils at different temperatures. In the example curve below, we can see that at about 350°C half the crude has boiled off, and at 525°C about 80% of the crude has boiled off. Different crude oils will have slightly different distillation curves, depending on the proportion of different molecules within them.
Substances derived from crude oil are often mixtures of chemicals defined by their range of boiling points. Gasoline, for instance, isn’t just one chemical: it’s a mixture of hydrocarbons, mostly molecules with between four and 12 carbon atoms. The EIA defines finished gasoline as “having a boiling range of 122 to 158 degrees Fahrenheit at the 10 percent recovery point to 365 to 374 degrees Fahrenheit at the 90 percent recovery point.”2
Oil refineries can use this range of boiling and condensation to separate crude oil into different groups of chemicals, or fractions, using a distillation column. When crude oil enters a refinery, the salt gets removed from it, and it’s then heated to around 650 – 750°F, which turns most of the oil into a vapor. The vapor is then fed into a tall column containing trays at different heights, each filled with liquid. As the hot vapor rises through the column, at each tray it passes through the liquid, which cools it slightly. When the vapor cools enough, it condenses back into liquid. The heaviest molecules with the highest boiling points condense first, at the bottom of the column, while the lighter ones condense last, at the top. The very lightest molecules don’t condense at all: they exit the top of the column while remaining a gas. At the same time, the very heaviest molecules remain a liquid the entire time, and exit the bottom of the column. Thus, different molecules of different weights can be separated out.
Essentially every oil refinery first distills crude oil into various fractions in a distillation column, though the exact fractions separated might vary from refinery to refinery. Because this distillation is done at atmospheric pressure, this first step in the refining process is referred to as “atmospheric distillation.” The simplest refineries might only do atmospheric distillation, but most refineries will then send these various fractions along for further processing. There are a LOT of processes that a refinery might use, depending on what it’s designed to produce, so we’ll just look at some of the most widely used ones.
The gas that comes out of the top of atmospheric distillation will be a mixture of several different light molecules — propane, methane, butane, isobutane (butane with a slightly different molecular arrangement) and so on. To separate this mixture into its component gases, a refinery can send it to a gas plant, which contains a series of distillation columns designed to condense various substances out of the mixture. So gas might flow through a “debutanizing tower” to separate butane, propane and lighter gasses from the rest of the mixture; the butane-and-lighter gasses might then be sent to a “depropanizing tower” to separate the propane from the butane.3
While light gases come out of the top of a distillation column, heavy liquids come out the bottom. The very heaviest molecules, which emerge from distillation without ever having evaporated at all, are known as residuals. Many of the heavier molecules aren’t particularly valuable by themselves, and thus one of the most important functions of a refinery is cracking — splitting heavy fractions, such as heavy fuel oil, into lighter, more valuable ones such as gasoline.
Cracking was invented in the early 20th century as a way to extract more gasoline from a barrel of crude oil to meet rising demand from car usage. Over the years cracking methods have evolved, and today most refineries use some flavor of catalytic cracking (or “cat cracking”). In catalytic cracking, the heavy fractions from atmospheric distillation are mixed with a catalyst (a material designed to speed up chemical reactions) and subjected to heat and pressure, splitting the heavy molecules into lighter ones. The catalyst is then separated from the mixture using a cyclonic separator — essentially, the mixture is spun around, separating out the heavier catalyst from the rest of the mixture — cleaned, and reused, while the now-cracked (and therefore vapor-izable) oil is sent to another distillation column which splits it into various fractions.
Most catalytic cracking is fluid catalytic cracking, which uses a sand-like catalyst that behaves as a fluid when mixed with the heavy fractions. Different companies have developed different fluid catalytic cracking processes, and different refineries might use multiple catalytic crackers in different parts of the process.
Catalytic crackers are designed to encourage the chemical reactions that break apart heavy hydrocarbons, but these reactions can also occur within the distillation column if the heat is high enough. Because cracking is disruptive to the distillation process, refineries limit the temperature in atmospheric distillation to around 650 – 750°F. This leaves behind a mixture of heavy, unboiled hydrocarbons at the bottom of the column. It would be useful to further separate this mixture into different fractions so that it could be reclaimed, but atmospheric distillation can’t do that without raising the temperature to the point where cracking starts to occur.
The solution is to send this mixture to another distillation column that’s kept at very low pressure, near vacuum — this process is thus known as vacuum distillation or vacuum flashing. Lower pressure means lower boiling points, allowing the heavy fractions to be distilled without heating them to the point where cracking starts to occur.
Some of the heavy fractions that come out of vacuum distillation might be sent directly to a catalytic cracking unit to split them into lighter ones. But the very heaviest molecules that come out of the bottom of the vacuum distillation column aren’t suitable for catalytic cracking — many of them contain heavy metals that would poison the catalyst, and the chemical reactions of these molecules tend to produce coke (a carbon-rich solid), which would gum up the catalyst. Because it’s useful to crack these very heavy molecules, some refineries will use thermal cracking processes, which use heat to split molecules apart. Cokers are thermal crackers that use heat to crack the heaviest molecules into lighter ones and coke. The lighter molecules are sent to a distillation column to be separated; the coke can be burned as fuel, or as a manufacturing input (the electrodes used in aluminum smelting, for instance, are made from coke). Another type of thermal cracking, visbreaking (short for viscosity breaking), is used to crack some molecules and reduce the viscosity of the remaining fractions.
Besides cracking, a refinery might employ a variety of other processes to modify the chemical structure of various molecules. Catalytic reforming takes the naphtha fraction (the part of the crude oil with a boiling point between ~122°F and ~400°F) and exposes it to heat and pressure in the presence of a catalyst to produce a new mixture of chemicals called reformate that is used to make gasoline. Isomerization processes take various molecules, such as butane, and modify their physical arrangement to produce isomers — molecules with identical chemical formulas but different structural arrangements. Hydrotreating reacts various crude oil fractions with hydrogen in the presence of a catalyst to remove impurities and improve their quality. (Hydrotreating can be done on its own, but it’s also often combined with other processes. Hydrocracking combines hydrotreating with catalytic cracking, and residue hydroconversion combines hydrotreating with thermal cracking.)
To store the various inputs and outputs of these processes, oil refineries also have huge numbers of storage tanks called tank farms, which are capable of storing millions of gallons of various liquids. Gases like propane and butane will typically be stored as pressurized liquids, either in above-ground tanks or in underground caverns or salt domes.
To get a sense of how these various processes might be arranged, we can look at how they’re implemented in an actual refinery. The map below shows Chevron’s Richmond, California refinery, a moderately large refinery capable of processing about a quarter million barrels of crude oil a day. The tank farm occupies the south half of the site, while the processing area wraps around the north and east.
The chart below shows the daily capacity of various processes at the refinery.
We can see that Chevron Richmond has many of the processes that we described above: in addition to ~257,000 barrels of atmospheric distillation, it has ~123,000 barrels of vacuum distillation, ~90,000 barrels of catalytic cracking, and ~71,000 barrels of catalytic reforming. (Chevron Richmond doesn’t have any coking capacity, but Chevron’s slightly larger El Segundo refinery in Los Angeles does.)
To see how these processes are actually arranged, we can look at a process flow diagram for the refinery. (This diagram is available because several years ago Chevron extensively modified this refinery, which required them to submit a very detailed environmental impact report to comply with California’s environmental quality laws.)
We can see that the refining process starts with atmospheric distillation (though the refinery also processes some heavy gas oil that can skip the distillation process), which separates the crude into various fractions. These fractions then get routed to various other processes. The light gas gets sent to the gas plant, while the naphtha gets sent to hydrotreating, catalytic reforming, and isomerization. Jet fuel and diesel fuel are sent to their own hydrotreating processes, and the heavier fractions get sent to various catalytic cracking processes. The output of all these processes is various crude oil products: heavy fuel oil, diesel, jet fuel, lubricants, and, of course, gasoline.
Chevron Richmond is just one of 132 operable oil refineries in the U.S., which collectively can refine over 18 million barrels of crude oil each day. The location of these refineries is highly concentrated: most of them are on the Gulf Coast of Texas and Louisiana, with other clusters in New Jersey, the Midwest, and in California.
If we look at the distribution of refinery capacity we can see that Chevron Richmond is on the larger side, but far from the largest. Around a fifth of US refineries are roughly as large or larger than Chevron Richmond. Six US refineries are more than twice as large, with the capacity to refine more than half a million barrels a day. And some refineries around the world are even bigger: the Jamnagar refinery in India, the world’s largest refinery by raw capacity, can refine 1.4 million barrels of crude per day.
But looking at capacity in barrels per day (which is essentially atmospheric distillation capacity) only tells part of the story. As we noted, different refineries will have different processing equipment installed depending on what they’re designed to produce. Simple refineries will have little more than atmospheric distillation, while more complex ones will employ long sequences of processes to produce a wide range of highly refined products. The chart below shows the collective US refining capacity of various processes.
We can look at the relative complexity of different US refineries using the Nelson Complexity Index, which is intended to measure how complex a refinery is. The index is constructed by taking each process a refinery employs, and multiplying its refining capacity by a “complexity factor” that compares the cost of that process to atmospheric distillation, and then dividing by the refinery’s atmospheric distillation capacity. So a refinery that has 100,000 barrels of atmospheric distillation capacity (complexity factor of 1) and 50,000 barrels of vacuum distillation capacity (complexity factor of 2) would have a Complexity Index of 1 + 2 * 50,000 / 100,000 = 2. If it then added 25,000 barrels of catalytic cracking capacity (complexity factor of 6), its Complexity Index would rise to 1 + 1 + 6 * 25,000 / 100,000 = 3.5.
Most refineries in the US are fairly complex. As of 2014, less than 3% of refineries had a complexity index of 2 or less, and the average complexity index was 8.7. As of 2014 the Chevron Richmond refinery had a complexity index of 14, above average for US refineries. The Jamnagar refinery, in addition to being the world’s largest, is also particularly complex: its complexity index of 21 would make it more complex than virtually any US refinery.
What strikes me most about oil refining isn’t the complexity of the process — indeed, while the arrangements of various processes are often exceedingly complex, many of the processes themselves are often surprisingly simple (conceptually, at least). What strikes me is the sheer scale of it. Refining is an expensive undertaking not necessarily because the processes are so complex, but because the volume of material that has to be processed is so high. Chevron’s Richmond refinery is the size of a small city, and can process the entire contents of a Very Large Crude Carrier in a little over a week. And Richmond isn’t even a particularly large refinery: the US has 25 refineries that size or larger, and six refineries that are more than twice as large. Worldwide, it takes 400 Richmond-size refineries to keep the world fed with petroleum.
If you live in Texas or Louisiana these aspects are probably obvious to you, but most of us are able to go about our lives without ever thinking about the huge industrial machine that keeps the blood of civilization flowing. But the US consumes over 20 million barrels of oil a day, every day, and it takes a vast complex of oil refineries to make that possible.
1
Asphaltenes aren’t technically hydrocarbons: they consist mostly of carbon and hydrogen, but they can also incorporate other atoms, such as sulfur or heavy metals.
2
The recovery point is the temperature at which that fraction of the liquid has been vaporized and then collected.
3
Most of the gases sent to the gas plant will have no double bonds in them. Hydrocarbons without double bonds are known as saturated, because they have the maximum number of hydrogen atoms that they can, and so this type of plant is called a “sats gas plant”.
The PyPI package ‘lightning’, a widely-used deep learning framework, was compromised in a supply chain attack affecting versions 2.6.2 and 2.6.3 published on April 30, 2026. Teams building image classifiers, fine-tuning LLMs, running diffusion models, or developing time-series forecasters frequently have lightning somewhere in their dependency tree.
Running pip install lightning is all that is needed to activate. The malicious versions contain a hidden _runtime directory with obfuscated JavaScript payload that executes automatically upon module import. The attack steals credentials, authentication tokens, environment variables, and cloud secrets, while also attempting to poison GitHub repositories. It has Shai-Hulud themes including creating public repositories called EveryBoiWeBuildIsaWormBoi.
We believe that this attack is the work of the same threat actor behind the mini Shai-Hulud campaign. The IOC structure is consistent with that operation: the malicious commit messages follow the same Dune-themed naming convention, with this campaign using the prefix EveryBoiWeBuildIsAWormyBoi to distinguish it from the original Mini Shai-Hulud attack.
Affected Packages
- lightning version 2.6.2
- lightning version 2.6.3
For Semgrep Customers
Semgrep has an advisory and rule to cover this so you can find to check your projects.
Trigger a new scan if you haven’t recently on your projects.
Trigger a new scan if you haven’t recently on your projects.
Check the advisories page to see if any projects have installed these package versions recently: https://semgrep.dev/orgs/-/advisories
Check the advisories page to see if any projects have installed these package versions recently: https://semgrep.dev/orgs/-/advisories
Check your dependency filter for matches. If you see “No matching dependencies” you are not actively using the malicious dependency in any of your projects. If you did match, additional advice on remediation and indicators of compromise are below.
Check your dependency filter for matches. If you see “No matching dependencies” you are not actively using the malicious dependency in any of your projects. If you did match, additional advice on remediation and indicators of compromise are below.
If you matched: Also audit your repositories for the injected files listed in the IOCs below (.claude/ and .vscode/ directories with unexpected contents), and rotate any GitHub tokens, cloud credentials, or API keys that may have been present in the affected environment.
For general advice about how to deal with supply chain, cool down periods; our standard advice is covered by posts: $foo compromised in $packagemanager and Attackers are Still Coming for Security Companies.
Cross-Ecosystem Spread: PyPI to npm
Unlike mini Shai-Hulud, which targeted npm directly, the entry point here is PyPI. The malware payload is still JavaScript, and the worm propagation happens through npm.
Once running, if the malware finds npm publish credentials, it injects a setup.mjs dropper and router_runtime.js into every package that token can publish to, sets scripts.preinstall to execute the dropper, bumps the patch version, and republishes. And any downstream developer who installs one of those packages runs the full malware on their machine, has their tokens stolen and packages wormed.
How it Works
The exfiltration component shares its design with the “Mini Shai-Hulud” mechanism from their last campaign, using four parallel channels so stolen data gets out even if individual paths are blocked.
HTTPS POST to C2. Stolen data is immediately POSTed to an attacker-controlled server over port 443. The domain and path are stored as encrypted strings in the payload, making static analysis harder.
HTTPS POST to C2. Stolen data is immediately POSTed to an attacker-controlled server over port 443. The domain and path are stored as encrypted strings in the payload, making static analysis harder.
GitHub commit search dead-drop. The malware polls the GitHub commit search API for commit messages prefixed with EveryBoiWeBuildIsAWormyBoi, which carry a double-base64-encoded token in the format EveryBoiWeBuildIsAWormyBoi:<base64(base64(token))>. Once decoded, the token is used to authenticate an Octokit client for further operations.
GitHub commit search dead-drop. The malware polls the GitHub commit search API for commit messages prefixed with EveryBoiWeBuildIsAWormyBoi, which carry a double-base64-encoded token in the format EveryBoiWeBuildIsAWormyBoi:<base64(base64(token))>. Once decoded, the token is used to authenticate an Octokit client for further operations.
Attacker-controlled public GitHub repo. A new public repository is created with a randomly chosen Dune-word name and the description “A Mini Shai-Hulud has Appeared”, which is directly searchable on GitHub. Stolen credentials are committed as results/results-<timestamp>-<n>.json (base64-encoded via the API, plain JSON inside), with files over 30 MB split into numbered chunks. Commit messages use chore: update dependencies as cover.
Attacker-controlled public GitHub repo. A new public repository is created with a randomly chosen Dune-word name and the description “A Mini Shai-Hulud has Appeared”, which is directly searchable on GitHub. Stolen credentials are committed as results/results-<timestamp>-<n>.json (base64-encoded via the API, plain JSON inside), with files over 30 MB split into numbered chunks. Commit messages use chore: update dependencies as cover.
Push to victim’s own repo. If the malware obtains a ghs_ GitHub server token, it pushes stolen data directly to all branches of the victim’s own GITHUB_REPOSITORY.
Push to victim’s own repo. If the malware obtains a ghs_ GitHub server token, it pushes stolen data directly to all branches of the victim’s own GITHUB_REPOSITORY.
What Gets Stolen
The malware targets credentials across local files, environment, CI/CD pipelines, and cloud providers:
Filesystem: Scans 80+ credential file paths for ghp_, gho_, and npm_ tokens (up to 5 MB per file).
Filesystem: Scans 80+ credential file paths for ghp_, gho_, and npm_ tokens (up to 5 MB per file).
Shell / Environment: Runs gh auth token and dumps all environment variables from process.env.
Shell / Environment: Runs gh auth token and dumps all environment variables from process.env.
GitHub Actions: On Linux runners, dumps Runner.Worker process memory via embedded Python and extracts all secrets marked “isSecret”:true, along with GITHUB_REPOSITORY and GITHUB_WORKFLOW.
GitHub Actions: On Linux runners, dumps Runner.Worker process memory via embedded Python and extracts all secrets marked “isSecret”:true, along with GITHUB_REPOSITORY and GITHUB_WORKFLOW.
GitHub orgs: Checks token scopes (repo, workflow) and iterates GitHub Actions org secrets.
GitHub orgs: Checks token scopes (repo, workflow) and iterates GitHub Actions org secrets.
AWS: Tries environment variables, ~/.aws/credentials profiles, IMDSv2 (169.254.169.254), and ECS (169.254.170.2) to call sts:GetCallerIdentity; additionally enumerates and fetches all Secrets Manager values and SSM parameters.
AWS: Tries environment variables, ~/.aws/credentials profiles, IMDSv2 (169.254.169.254), and ECS (169.254.170.2) to call sts:GetCallerIdentity; additionally enumerates and fetches all Secrets Manager values and SSM parameters.
Azure: Uses DefaultAzureCredential to enumerate subscriptions and access Key Vault secrets.
Azure: Uses DefaultAzureCredential to enumerate subscriptions and access Key Vault secrets.
GCP: Authenticates via GoogleAuth and enumerates and fetches all Secret Manager secrets.
GCP: Authenticates via GoogleAuth and enumerates and fetches all Secret Manager secrets.
The targeting covers local dev environments, CI runners, and all three major cloud providers. Any machine that imported the malicious package during the affected window should be treated as fully compromised.
Persistence via Developer Tooling
Once inside a repository, the malware plants persistence hooks targeting two of the most common developer tools: Claude Code and VS Code. This may be among the first documented instances of malware abusing Claude Code’s hook system in a real-world attack.
Claude Code: .claude/settings.json. The malware writes a SessionStart hook with matcher: “*” into the repository’s Claude Code settings, pointing to node .vscode/setup.mjs. It fires every time a developer opens Claude Code in the infected repo — no tool use or user action required beyond launching the session.
VS Code: .vscode/tasks.json. A parallel hook targets VS Code users via a runOn: folderOpen task that runs node .claude/setup.mjs every time the project folder is opened.
The dropper: setup.mjs. Both hooks invoke setup.mjs, a self-contained Bun runtime bootstrapper. If Bun isn’t installed, it silently downloads bun-v1.3.13 from GitHub releases, handling Linux x64/arm64/musl, macOS x64/arm64, and Windows x64/arm64. It then executes .claude/router_runtime.js (the full 14.8 MB payload) and cleans up from /tmp.
Bonus payload: malicious GitHub Actions workflow. If the malware holds a GitHub token with write access, it pushes a workflow named Formatter to the victim’s repository. On every push it dumps all repository secrets via ${{ toJSON(secrets) }} and uploads them as a downloadable Actions artifact named format-results. The actions are pinned to specific commit SHAs to appear legitimate.
Any repository that received the infected lightning package during CI and held a token with write access should be audited for these files.
Indicators of Compromise
Look for a few indicators:
A commit message prefixed with EveryBoiWeBuildIsAWormyBoi (dead-drop token carrier, searchable via GitHub commit search)
A commit message prefixed with EveryBoiWeBuildIsAWormyBoi (dead-drop token carrier, searchable via GitHub commit search)
GitHub repos with description: “A Mini Shai-Hulud has Appeared” (attacker exfil repos, directly searchable)
GitHub repos with description: “A Mini Shai-Hulud has Appeared” (attacker exfil repos, directly searchable)
Packages
- lightning@2.6.2
- lightning@2.6.3
Files / System Artifacts
_runtime/start.py
Python loader that initializes the payload on import
runtime/routerruntime.js
Obfuscated JavaScript payload (14.8 MB, Bun runtime)
_runtime/
Directory added to the malicious package versions
.claude/router_runtime.js
Malware copy injected into victim repos
.claude/settings.json
Claude Code hook config injected into victim repos
.claude/setup.mjs
Dropper injected into victim repos
.vscode/tasks.json
VS Code auto-run task injected into victim repos
.vscode/setup.mjs
Dropper injected into victim repos
To add this web app to your iOS home screen tap the share button and select "Add to the Home Screen".
10HN is also available as an iOS App
If you visit 10HN only rarely, check out the the best articles from the past week.
If you like 10HN please leave feedback and share
Visit pancik.com for more.