Categories
Programming

WordPress REST Allows Cross-Origin by Default

This is not a red alert. It’s not a bug. I just found it interesting.

If you make a request to the REST API built into WordPress and you pass in an Origin header, the response will contain an Access-Control-Allow-Origin header with the same value. This response header is part of CORS (Cross-Origin Resource Sharing), which is a feature of browsers that’s meant to protect from executing code from another URL. If the server responds with a different URL, the browser will refuse to complete the request. A typical scenario would be JavaScript running on a page hosted by https://foo.com attempting an Ajax request to https://bar.com. If the Web server at bar.com responds with Access-Control-Allow-Origin: https://foo.com, the browser refuses to complete the request. It’s a sensible default stance.

This came up during a broad security scan of a client Web site. Security scanners notoriously over-report issues, but it’s best to understand the issue before dismissing, even if it’s labeled a “medium” risk. I did some searching and found that this behavior for the WordPress REST API is by design. The reason is that WordPress already imposes a robust security model on the REST API. If an endpoint uses secure information, it must authenticate to a user via a nonce. This is a short-term, randomly-generated token specific to the user. Without the nonce, calls to privileged functionality will fail inside the PHP code. Thus, WordPress purposely subverts the usual CORS approach.

Consequently, WordPress gets out of the way of developers who must implement alternative authentication schemes. It also allows plugins and themes to impose more restrictive requirements. It’s possible to hook into the REST response and set a different Access-Control-Allow-Origin header. This header can only contain a single URL, though. For cases where you have several requesting sites, you’d keep a list and respond with the matching URL if it’s on the approved list.

This topic came up in a WordPress bug report back in 2018 (ticket #45477), and also covered in the REST API FAQs. It’s fortunate that WordPress is Open Source. It makes it easy to see what’s going on and to benefit from the open discussions of bugs, even those from years ago.

Categories
Creative Pursuits Programming

The Tragic Illusion of Mechanized Consensus

Boldium hosted another excellent forum on AI this week, this time emphasizing how machine learning integrates with visual design. Nick Foster offered a fascinating metaphor for AI—that of an overdriven amplifier pushing the input into fuzzy distortion. His opening slide presented Black Flag on stage. I could hear Greg Ginn’s crackling plexiglass Ampeg guitar twisting out a chromatic swirl of notes in the same way the the DALL-E 3 tears away curtains before a window into a disturbing nightmare realm.

I started thinking about how these models are produced by consuming vast volumes of information filtered through the expedience of what’s available on the Internet. Out of this cauldron of goo come offerings. They are a momentary consensus of the ghosts in the machine. Shout your command, “Hearty stew with root vegetables, beans and mutton”, and out of the miasma come four attempts to comply. The first spoonful is too hot. The second bite includes coffee beans. The third includes a miniature sheep. Probably one of the four is close, but you’ll spice it up anyway by tweaking the prompt.

The ghosts produce this consensus and seem to ask you to make the final decision. It reminds me of Howard Roark’s trial where he talks about there being no collective brain.

There is no such thing as a collective brain. There is no such thing as a collective thought. An agreement reached by a group of men is only a compromise or an average drawn upon many individual thoughts. It is a secondary consequence. The primary act—the process of reason—must be performed by each man alone. We can divide a meal among many men. We cannot digest it in a collective stomach. No man can use his lungs to breathe for another man. No man can use his brain to think for another. All the functions of body and spirit are private. They cannot be shared or transferred.

The Fountainhead, Ayn Rand

These AI models are the closest approximations of a collective brain yet produced. What they produce is often incoherent, even marked by insanity. The results can be valuable in the context of an individual putting in the effort to rationalize them. Aside from the creator applying craft to the generated product, the spectator draws from the context to make sense of the experience. Yesterday, I enjoyed an AI cover of Paul McCartney singing Take On Me. (The vocals from an acoustic a-ha performance are replaced with a McCartney voice model). Being prompted with the suggestion that the voice was the famous Beatle lends power to the illusion. And when you hear it, you might remark, “wow, that’s crazy.”

Consider the source of the data used by the models: the Internet at large. It’s a noisy, obnoxious place. You’ve blocked plenty of jerks from your social media feeds, and you don’t bother reading annoying blogs, but the information is still out there. It was all scraped off and stuffed into one vat of slop from which we randomly pluck chunks.

It’s often ugly or disturbing, similar to looking into a mirror or riding BART. The full spectrum of all the ideas expressed on the public Web, both good and evil, are projected outward, and if you don’t angle the prism just so, you get a glimpse into a world of horror. There may be a few simple precautions in place, like being handed dark glasses during an eclipse, but staring directly into the sun is always a choice. It can be painful.

In reaction, the censors emerge to better affix the protections. Naturally, the vendors do not wish to be selling certain unacceptable ideas, even if they are user-generated. Microsoft cannot afford to be the source of Mickey Mouse depicted performing off-brand acts such as flying a plane into New York City.

In my favorite hobby, roleplaying games, I often use random tables, as is traditional. These tables combine to produce multi-part constructs. The classic use is Appendix A of the Dungeon Masters Guide that generates dungeon maps. The text states upfront that the model, comprised of more than twenty lookup tables, can produce unwanted results that the user can discard or modify.

Discretion must prevail at all times. For example: if you have decided that a level is to be but one sheet of paper in size, and the die result calls for something which goes beyond an edge, amend the result by rolling until you obtain something which will fit with your predetermined limits. Common sense will serve. If a room won’t fit, a smaller one must serve, and any room or chamber which is called for can be otherwise drawn to suit what you believe to be its best positioning.

Dungeon Masters Guide, Appendix A, Gary Gygax

This process is the low-fi equivalent of prompt engineering and post-production work done on AI images. I use tables to generate the contents of rooms, and the results sometimes present a puzzle. Why are giant beetles guarding glass jars filled with tree bark? I can invent an explanation, perhaps adding clues, such as a diary kept by a druid taking samples from trees. Or I can let the mystery hang there for the players to sort out. That’s when the game can be surprising and delightful as the players invent explanations I could not expect.

In a larger scope, the entire RPG campaign is an exercise in consensus world building. The game rules provide some structure and imply a world. If we’re playing Dungeons & Dragons, we know we’re in a world where gold coins are money, and brave adventures go off to find dungeons in hopes of finding gold and growing more powerful. As the game master, I add even more structure. I can declare only humans can be clerics. I can give an XP bonus to dwarf characters who hoard their gold. The other players build the world with their choices as well.

Nothing in the implied world or in anything I planned anticipated the players spending a lot of time knocking monsters unconscious and bring them back to town. The game does have rules for subduing enemies. From that kernel, the players in my longterm campaign invented the enterprise of capturing wild animals and monsters to sell in town. They relish the idea of running across wandering giant animals to place in cages.

The players behaved as if there were a market for giant animals. I didn’t dismiss the idea, so it became part of the game world. If everyone else around the table had declared it a rotten idea, maybe we’d have discarded it. It led to more interesting events. After the exhibition of a giant python in the town square, everyone knew the adventurers had been into the swamp where trespass within is forbidden by decree. That created an interesting interaction with the town sheriff.

The experience of the game is an evolving consensus that produces entertainment. It’s an average of the expectations of the players and the game authors. The game rules are mostly static, of course. The players add new ideas consistently. The game pleases everyone.

Now consider injecting the entire consensus of the Internet into the game world. Google Bard says it can take “several thousand” tokens as part of a prompt. It can’t track everything that happens in one game session, much less the entire chronicle of the game going back years. It can draw upon the generic information pulled from the Internet, and it might know something about the Basic Fantasy RPG campaign I’ve run since 2017 and relentlessly document on EmptyZ. When I asked it, “Who are Tienarth’s Raiders?” It guessed that I was talking about Dungeons & Dragons and then made up everything else.

Tienarth’s Raiders are a fictional mercenary group in the Dungeons & Dragons campaign setting of Forgotten Realms. They are led by the half-orc Tienarth, a skilled tactician and warrior. The group is known for their ruthlessness and efficiency, and they are often hired by wealthy patrons to undertake dangerous or difficult missions.

“Who are Tienarth’s Raiders?”, Google Bard

Tienarth is an elf magic-user, the game is BFRPG, and the Raiders don’t work for wealthy patrons. Almost everything in the response was generic tabletop roleplaying game dreck. It’s as if all the competing thoughts about a band of adventurers canceled out to equal nothing. Maybe it’s like that Harry Nilsson line from The Point, “A point in every direction is the same as having no point at all.”

I’d almost rather the model told me Tienarth’s Raiders are a type of cheesecake made from radioactive stardust, not something that seems sensible but is completely wrong. It asks too much of the public, generic models to provide anything meaningful to the personal game world built by a small group of friends. A model fine-tuned on issues of Dragon Magazine and White Dwarf could be interesting, though.

I wonder how long it will be until we can check off boxes of data from different subcultures (e.g. mix in Dragonsfoot, exclude The Forge) to fine-tune the models on demand.

Categories
Professional Programming

Flush the Fashion

It’s not fashion itself that’s irritating, it’s the rabid advance of the crowd so devoted to the fashion. I mean fashion in the broad sense of a popular, conventional approach to anything. I’m not writing only of clothing or hairstyle. In fact, those aspects of societal obsession have diminished compared to my youth when wearing a mohawk to school might have been a blatant invitation to fight. (Not really in Martinez. Not enough kids to divide into serious cliques.)

In proper perspective, fashion can be fun. You know the choice is arbitrary and you can cast it aside for something more important. You’re going to wear sandals to the beach, not your Doc Martens. That’s logical. Pick the higher values over the lesser values. In a tie, flip a coin.

I’ve always enjoyed working out the best solution versus whatever’s popular. I don’t mean picking the opposite for the sake of being provocative. I mean deciding for myself what’s right and not being afraid of the ninnies and the twits. I loved computers at first sight. My first experience was pair-programming BASIC on an Apple II+ my math teacher hauled into school every day. Despite being mysterious, the computer behaved deterministically. Perhaps there were multiple ways to achieve a result, but it was the result that mattered.

It did not occur to me to consider whether messing around with personal computers was fashionable. It was a niche hobby like playing Dungeons and Dragons, but the music I listened to said it didn’t matter. Alice Cooper commanded “Flush the Fashion”. The clones destroyed government. They were destroying time. Mike Ness complained “you look so plastic, you could be a barbie doll” and that he was “anti-fashion”.

When I discovered PHP in 1997, it was obvious to me how much better it would make building web applications. I was immediately more productive. To that point in Internet history, a hard line divided content (HTML files) and data processing (Perl cgi-bin files). PHP allowed merging and intermingling the logic and the presentation.

Despite it being obvious to me, building with PHP was a hard sell to clients for a few years. PHP was not fashionable. It didn’t come out of giant software companies like Sun or Microsoft. Eventually, though, that we could build better sites at lower cost won out. PHP might never have been fashionable. It moved quickly into being the default choice that fashionistas declared uncool, boring, too easy. Yet, it remains overwhelmingly dominate. (PHP is probably used by about 75% of all Web sites).

I recently stumbled on Larry Ellison’s comment about fashion from 2008. Dan Farber’s piece about it from then covers the details. (Oh for the days listening to The Gillmor Gang commuting to Berkeley!) Ellison described the computer industry as more fashion-focused than women’s clothing.

The interesting thing about cloud computing is that we’ve redefined cloud computing to include everything that we already do. I can’t think of anything that isn’t cloud computing with all of these announcements. The computer industry is the only industry that is more fashion-driven than women’s fashion. Maybe I’m an idiot, but I have no idea what anyone is talking about. What is it? It’s complete gibberish. It’s insane. When is this idiocy going to stop?


We’ll make cloud computing announcements. I’m not going to fight this thing. But I don’t understand what we would do differently in the light of cloud.

Larry Ellison speaking at Oracle OpenWorld 2008

Fifteen years later, it might be hard to remember when putting all of your data in the data center of a online retailer wasn’t a default choice. It became fashionable, and Oracle hopped on the bandwagon despite its leader considering the conversation to be idiotic. Of course, today many people are rethinking the choice in the context of intrusions. Microsoft, infamous for building systems vulnerable to security breaches, lost control of their entire cloud infrastructure in 2023. A researcher at Tenable found a way to access cross-tenant applications and sensitive data, such as authentication secrets. Everything in Azure was exposed, including access to banks.

You won’t hear someone argue for cloud computing by calling it fashionable, but you will hear this argument in essence, wrapped in palatable terminology. You’ll hear that all the big players are using it. The point is both true and a non sequitur. More insidiously, anything fashionable will be described as modern.

Modern is a euphemism for fashionable.

Forget it. Being modern (fashionable, hip, chic, stylish, bussin’, whatever), does not belong in software architecture. Ellison said he wouldn’t fight it (cloud computing), meaning he’d cynically adopt the buzzwords. That went beyond not fighting. It was surrender.

Instead, I recommend you decline the fight. Do what you know is best. Make choices based on rational arguments. I’m not referring to cloud computing specifically. Renting virtual server capacity often solves a problem perfectly. Reflexively choosing any solution based on how often you read about it on social media can only ever be right by accident.

Flush the fashion.

Categories
Humor Programming Science

Degeneration is Real

What’s model collapse? Here’s what the Brave AI Summarizer says:

Model collapse is a degenerative process that occurs when new generative models train on AI-generated content and gradually degenerate as a result. This process is inevitable, even for cases with almost ideal conditions for long-term learning. A recent study by researchers in Canada and the U.K. explained the phenomenon of model collapse. Learning from data produced by other models causes model collapse, whereby models forget the true underlying data distribution over time. ChatGPT and Bard are headed for model collapse.

Typing “model collapse” into Brave Search

Jerry Casale has warned us about de-evolution for over fifty years, that the increasing use of technology slowly devolves our species. His inspiration, Maerth’s The Beginning Was the End, offers a theory about increasing intelligence through consuming brains.

One ape discovered that eating the fresh brain of one’s own kind increases the sexual impulses. He and his descendants became addicted to brains and hunted for them. It was not until later that they noticed that their intelligence increased as a result. The outcome of this process is HOMO SAPIENS.

The Beginning was the End, p. 37

If model collapse is real, then LLM cannibalism is producing increasing artificial un-intelligence, a reverse of the effect described by Maerth. Could it be that the frequent hallucinations demonstrated by AIs only appear nonsensical to us because our primitive brains merely watch as a superior consciousness disappears into the horizon? I’d prefer not to believe so, but I must recall the final line in DEVO’s cover of “Are You Experienced”: not necessarily beautiful but mutated.

Categories
Professional Programming

Put Your Design in Writing

Writing up the design of a software system boosts productivity because it’s much less effort to fix bugs in the design before you write a line of code.

Since John ranted about ranting this week, I almost let out a get-off-my-lawn rant about how the kids these days don’t know about working out a design in writing before coding. Then I remembered that I only know a little bit of everything there is to know, but I am convinced it’s best not to give any energy to anything I don’t want more of.

Of the many subjects I studied years ago when earning my degree in computer science, software engineering persists as the most useful. I can barely recall how to code in Ada or Pascal, but I often return to the principles of discovering requirements, putting software design down on paper and planning for the entire system life cycle. I still keep those textbooks on a shelf in my office. I have a fond feeling about them similar to the one I get from the first edition Dungeon Masters Guide. Something nudges me to crack open those old books because there’s bound to be some wisdom I missed before.

I was thinking about Software Engineering Concepts by Richard Fairley as I read a blog post titled “Waterfall” doesn’t mean what you think it means. That post focuses on the misconceptions of waterfall versus agile. Perhaps the amorphous thing that people call agile enables the neglect of proper documentation. Although, I’ve observed this behavior long before anyone had a fashionable label for their lack of process.

Although I learned of the power of working up a design in writing while in class, the practice proved itself over the years. The argument is simple — it’s much less work to fix a flaw in the design when it’s just words and diagrams. Coding is comparatively more expensive, especially if you must throw away hours of work to start over. This might not be obvious to everyone.

Here’s my understanding of the software engineering process.

  • Discover the purpose of the system by writing down stories about how users will interact with it. Write them as non-technical stories that the client can understand.
  • Describe the data model, again in plain language. Validate the data model versus the user stories. Possibly add more stories and expand the data model. A data flow diagram can help. Describing operations between the data objects can help.
  • Write down any constraints you can think of. Some are obvious, such as when you know you’ll code the system in PHP because it’s the language you’ve been coding in for more than 25 years. Some constraints are standard, such as response times or maximum simultaneous users. Constraints can cause you to discover new user stories or to adjust the data model.
  • Describe the most important algorithms, database structures and objects. It isn’t code yet, but you’re thinking about how it would be coded and teasing out problems that might come up as the parts interact. It may cause you to return to any earlier step and revise your thinking, but that’s easy because it’s just words.
  • Figure out how you will test the system once it’s complete, otherwise known as a test plan. Figure out how the system will be maintained over time, otherwise known as a maintenance plan.
  • Start writing code, including unit tests. Keep validating that the code you’re writing honors the design. Write code that can be tested with the test plan. Write code that can be maintained. Revise the plans if necessary.
  • Run the test plan. Hopefully, unit tests were all passing and nothing major pops up that will cause a change in the design.
  • Deploy the system and stick to the maintenance plan. If you discover a flaw in any of the previous work, update what you wrote before.

Quite often, I see the above process compressed into a Statement of Work written up by a non-technical client, a list of tasks brainstormed in an hour for the purpose of estimation, and then a lot of churn on closing tasks. It’s easy, like wolfing down a bag of chips. Of course, it can give you indigestion or worse if you go back for seconds or thirds or …