Half-Elf on Tech

Thoughts From a Professional Lesbian

Author: Ipstenu (Mika Epstein)

  • Plugins: Sex and Gutenberg

    Plugins: Sex and Gutenberg

    Look, I get that a mess of people hate Gutenberg. I like it, but that’s my opinion and that’s okay. I’m fine if you hate something I like, it doesn’t hurt me at all. What I don’t like are people being jerks to Gutenberg devs. In fact, I truly dislike people who are just mean to anyone, Dev or not. One of my weirder jobs as the Plugin Rep was balancing protecting users and protecting developers.

    It gets really weird when the developer is the user.

    I Hate Gutenberg

    That’s how we’ll start this one. Alan (not his real name) hated Gutenberg and posted a ‘review’ that was basically offering to bribe Automattic to stop making it. The forum mods very nicely said “hey man, this isn’t a real review, could you do that instead?”

    Alan…

    I was under the impression that ultimately Automattic is in control of the WordPress Core. If not them, then someone is, the buck stops somewhere. The drive to make this core is most likely coming from wordpress.com, an Automattic asset that uses themes that do not include a page builder.

    Alan on the WordPress.org Forums (post redacted)

    He went on to try and argue about usability etc. Now, to his credit, this was in the early days when it absolutely had some accessibility issues. It was also at the era that it was en vogue to bash Gutenberg … I’m not sure that era has ended yet. But basically Alan, no. WordPress.org is not going to stop developing Gutenberg. And no, Automattic doesn’t rule the world.

    The thing that was a little interesting is that Alan had left a few other turds of reviews (the eloquent “Don’t waste your time.” and using reviews for support). Five months prior, he’d got shirty about a review being moderated and not approved in a ‘timely’ (i.e. 5 minutes) fashion. Seriously. Five goddamn minutes.

    Kickbacks?

    The weekend rolls around. Most people are off enjoying the world and not WordPressing. That’s when Alan uses his second account to leave another review. His second account was, interestingly, the one he used to own his plugins. You can see how this landed in my lap.

    His other account was the one I was familiar with since he’d had a weird complaint that WooCommerce wasn’t accepting new plugins on their site a couple years ago, and he tried to buy someone’s plugin so he could be there. Alan also left a bunch of crappy reviews as that account, including a rant that someone charged people for their service (admittedly that plugin did do an asshat move by switching from free to pay, but still, the review was “They charge!” and not “The plugin sucks because …!” which is different).

    So on the weekend, Alan runs into another post by someone who mentions a plugin they’re using is conflicting with something. This was not Alan’s plugin. But Alan decided he’d fix it. He replied three times within 30 minutes that he was going to fix it, had ideas about fixing it, and had a fix. The robots (aka Akismet) flagged him as spam for the rapid posting and content since it had links.

    This happens, but it rarely requires anyone to ask this:

    Can a moderator please approve my posts above? I have posted a fix.

    Yes, I know this plugin is bad for your askimet kickbacks, but we want this, not askimet.

    Alan in the Forums on a Sunday

    Kickbacks? Akismet? I guess he realized he was caught as spam.

    And what does Alan do? He gets his other account, the non-plugin-dev one, and repeats his posts with this added on:

    Wow, speak your mind around here, and get the silent treatment. Core needs a fork soon. Ever since Gutenberg actually. Clearly (sexual?) favors are being exchanged, why else would automattic include changes that almost nobody wants, and actively hates? 

    Alan in the forums on a Sunday via his alt account

    … What?

    You Read That Right

    Yes, Alan said sexual favours were exchanged for … Gutenberg? Which had nothing to do with this plugin nor its conflict. And he wasn’t being given the silent treatment, it was a goddamn weekend, and I’ve spent over a decade telling the volunteers of WordPress to take a fucking weekend off!

    Forums reported him to Plugins and I read it on Monday. In the intervening hours, there were more complaints, from both accounts, and more rants that had nothing to do with the plugin that Alan was fixing. Given that he had already been warned the year before about making everything about his Gutenhate …

    A gif of Jan Brady saying "Marcia, Marcia, Marcia!"

    Alan clearly was incapable of (or unwilling to) restrain himself from ad hominem attacks and making everything about Gutenberg. In fact, if we go to tape, the year prior he claimed someone in Switzerland controlled all emails. The thing was, he just … posted that on .Org.

    Not as a reply, not as a comment about a plugin or theme.

    Not as related to a WordCamp.

    The post was really just “This website [WordPress.org] controls all email and are using their power to destroy my business.”

    It was clear to me what had to happen.

    Besides the fact that you were posting on a weekend and we are a 100% volunteer run service, accusing people of sexual favors in this manner is an egregiously unwelcome way in which to behave in public. It is aggressively offensive, rude, and in violation of multiple forum and plugin guidelines.

    Using a second account with which to make those comments shows you did this absolutely with malicious intent. You didn’t even wait an hour between asking your post to be approved and leaving such a comment. This behavior is an escalation to your aggressive, and incorrect, attack on Automattic regarding Gutenberg last year.

    We feel your actions demonstrate you simply are not willing to be a productive member of this community and as such we are invoking our right to remove hosting of your plugins at any time.

    Me via email to Alan

    There’s a lot more boilerplate, but more or less it tells you “Don’t make another account, and stop wasting everyone’s time here.” If you can’t play well with others, then open source isn’t going to be the place for you.

    In My Defence…

    Alan began his reply by saying he never intended that part of his reply to be public. So he … made it on a public forum, in the hopes his alternate account wasn’t blocked? Even though he knew about Slack and regularly used it to complain about being moderated.

    He went on to complain that the forum mods had a vendetta and clearly knew him from work. I have to admit, I blinked a lot there. His excuse was people clearly hated him from work and it spilled over? Why would they hate you at work, Alan? Why would someone from your job hate you so much as to make up shit about you here? He blamed the PC ‘woke’ world, and demanded to know who said such things because he had never seen any complaints. The same complaints that carried over from his work.

    Then he went on to say it was clearly a vendetta of the plugins team against non-Automattic owned ‘security’ apps. His was used by, I think, 500 or so people. Not what I consider a ‘well used’ plugin, more of a niche thing. This isn’t a judgement call! I have plugins used by fewer than that. It’s just like saying Lindys sells more cheesecake than strudel.

    That was a Guys & Dolls joke.

    But on topic, let’s see. The takeaways from Alan’s email are:

    1. Intent to be abusive? Check.
    2. Not understanding that multiple people are admins and can read posts? Check.
    3. Demanding explanation for non-related topics? Check.
    4. Claims he was never warned even though he replied to those warnings? Check.
    5. Claims we’re sensitive after accusing people of sexual impropriety? Check.
    6. Hiding behind claims of ‘woke’ abuse? Check
    7. Incorrectly assuming it’s about plugin in question? Check.

    Conclusion? Angry person who thinks he can mistreat anyone. And just for a bonus:

    Further, based on this overreaction, I can only conclude that I am correct. Gutenburg’s authors are providing sex, money and drugs to high ranking decision makers at Automattic.

    Alan via email to Plugins

    I still don’t (never have) work for Automattic. I’ve been to a lot of WordCamps and I’ve never been offered money or drugs or sex for favours doing plugin reviews. Was I always talking to the wrong people? Was there a secret orgy I was excluded from!? Now I want to know!

    Not really. None of that has any place in my WordPress life. Sorry folks, my sex life is not related to plugins or WordPress, and very much not your business.

    And for Alan, I just shrugged and moved on.

  • Plugins: My Way Or Nothing

    Plugins: My Way Or Nothing

    Back when I started explaining why I dislike security plugins, I mentioned hating people who thought they knew everything.

    Noah (not his real name) is a good example of that kind of drama.

    Not Safe Enough

    Very rarely do plugins get an email that starts out with claims we’re too dumb to understand security.

    In this case, Noah submitted a search plugin. Not a security plugin. And on a quick look, it had the following serious issues:

    • direct access to files with POST calls outside of functions
    • calling wp-config.php directly to get DB access
    • non-prefixed functions, defines, and classes
    • non-sanitized data being processed and non-escaped data being output

    Pretty normal in so far as poorly written plugins go, and Noah got an email with the usual details on what’s wrong and what to fix.

    Noah did not take it well and claimed our rules were arbitrary and made to protect people. Yes? I mean, of course the rules are there to protect people! And one can argue any rule is ‘arbitrary,’ but that’s how they work. Noah went on to say that was okay, but rules had disadvantages too. To that end, sure, he’s got a point. The rules do limit innovation to an extent but usually that’s got a reason.

    The email went on for 1500 words about the problems people face (resource usage, mostly, and caching), and Noah included this gem:

    You are not able to solve these problems since you waste all of your time defining rules, handling security problems and bothering people who are offering their assistance to you for free.

    Noah via email to Plugins

    We wouldn’t have to make all those guidelines and handle security issues if people actually fixed them, but I felt that was besides the point.

    Let’s be honest here, Noah’s email was a lot of drama and words, signifying nothing at all. Making WordPress faster and having it use fewer resources is a great idea. But sir, this is an Arby’s. Or rather, Noah my man, this is a search plugin that has obvious security issues (sanitizing/escaping), makes dangerous calls that won’t always work (calling wp-config.php which can be moved), and crap for prefixes.

    Not Smart Enough

    I did pick out the line “you can’t understand what I do” and rolled my eyes. Generally speaking, if someone tells you that, they’re the fool, not you. It’s like people who jump to tell you “I have a decade experience in WordPress!” They want their perceived standing in the community to excuse behaviour. That may happen, but I never cared if it was Matt himself submitting a plugin. Security is security. Hell, I once closed my own plugin for a security issue I’d missed 5 years prior (hilariously I only realized it was mine when I was about to hit send — there was a lot of laughing).

    And I absolutely am smart enough to take one look at Noah’s code and recognize that his entire point was to have a plugin search WordPress and intentionally not use the built in WordPress security features. Like nonces. Normally that is from a lack of education and I think of it as a no-harm/no-foul. I remember when I didn’t really understand nonces, after all!

    But in Noah’s case, he believed he was smarter than everyone else using WordPress and, instead of submitting patches to improve it for everyone, he was just going to circumvent WordPress’ security entirely. And that is a non-starter.

    I am also smart enough to see his plugin could be brought into compliance pretty easily, which was why I didn’t reject, I pended.

    Not Clever Enough

    I replied to Noah explaining his rant was pretty off topic not to mention very wrong in many places. The code was not safe to use, and we generally didn’t accept plugins that didn’t ‘use’ WordPress unless it was safe.

    Perhaps I should explain a little here… See, there are two issues with calling wp-load.php or wp-config.php. The first issue is that people can, and do, move both the config file and the wp-content folders, so there would have to be a lot of fallbacks to make sure it would work for everyone. The second is that calling those directly is how you obviate WordPress’ security.

    A sneaky third is that there’s no reason you should need to do that in the first place. If you call your plugin properly, with init and so on, then you get all the fun WordPress stuff without the drama. I know it’s a concept a lot of pure PHP devs struggle with, especially when they want to have ‘a url’ that people can use on their site (like a plugin wants your site to have example.com/myplugin), because that is a little tricky with WordPress.

    In the email to Noah I made it clear. If he wanted to be hosted on WordPress.org, he had to follow the guidelines and that included our security requirements.

    I mean, come on, here’s the part of the email where I tell him to sanitize, and he asks if that’s correct:

    > When you include POST/GET/REQUEST/FILE calls in your plugin, it’s important to sanitize, validate, and escape them.

    Did you ever think, if this is really correct?

    Noah via email to Plugins

    Yes. Yes I do think it’s correct to sanitize, escape, and validate.

    Also telling him “you must use the most appropriate function for sanitizing” (by which I mean ‘don’t sanitize a number as a text field, y’all’) he says:

    Who are you, that you think you are allowed to tell me what I “must use”? Are you thinking, you would be god?

    Noah via email to plugins

    A god?

    A screenshot that says "I am a generous god."

    Jokes aside, Noah made it clear he thought the rules were bullshit, and he had no intention of ‘helping’ anyone. I shrugged, rejected his plugin, suspended his account, sent his emails to the blocked bin, and moved on my way.

    One Year Later…

    A new search plugin showed up, and at first it didn’t trigger any memories for me. In fact, this version had corrected most of the things I’d flagged in the first one. A lot of people submit similar plugins, but at this point I was about 7ish years into reviews, so I was pretty good at spotting repeats.

    Just like people have writing styles, people have coding styles.

    Around halfway through the review, something clicked. I went and checked, and lo and behold it was Noah! He used a new domain, but DNS showed the same person owned both domains. Him. And he wasn’t really trying to hide it since, when I rejected the plugin, he replied from his first account’s email.

    He explained that in the last couple of weeks, we’d ‘twice’ gotten in trouble together. I thought I hadn’t heard from him in nearly a year, and now I was worried he had used multiple accounts. But before I got into that work, I read his email.

    I Didn’t Read His Email

    It’s true. I skimmed his 2500+ word email that was filled with … well … bullshit. He claimed that the use of saved replies meant I was ignorant and only doing that because it was easy… You know what, let me bullet point.

    1. He thinks Automattic owns the plugin review team.
    2. He believes he was 100% right and I was wrong, but he made the security changes anyway.
    3. I was selfish for not listening to him, but he’s not rude for not listening to me.
    4. He doesn’t believe telling me I’m stupid and paranoid was rude.
    5. He expected me to do the emotional labor of telling him how to behave.
    6. He claimed I rejected his plugin without a word (even though he replied to the email where I explained it was for abusive behaviour).
    7. He’s mad I rejected his resubmission, even though the original email said NOT to resubmit or make a new account (… I mean …).

    I did not reply since at the end he’d said this:

    This is my very last attempt to offer my software to you. If you don’t answer this email, I will delete the plug-in. But I believe you would serve WordPress better if you would give the software a chance.

    Noah via email to Plugins

    Alas, he tried twice more that year before (seemingly) giving up.

    Oh, and no, he didn’t have other accounts. He was sniffing some glue to come up with a claim that he and I had been in contact at all after that first rejection.

  • Docked Libraries and DNSMasque

    Docked Libraries and DNSMasque

    I use Docker at work because it’s what we have to use to build sites on specific servers (like WordPress VIP). Honestly, I like it because everything is nicely isolated, but it has been known to have some … let’s call them ‘quirks’ with the newer M1 and M2 chip Macs.

    You know what I have.

    And I had some drama on a Friday afternoon, because why the hell not.

    Drama 1: libc-bin

    After working just fine all day, I quit out of Docker to run something else that likes to use a lot of processing power. When I popped back in and started my container, it blew a gasket on me:

    21.39 Setting up npm (9.2.0~ds1-1) ...
    21.40 Processing triggers for libc-bin (2.36-9+deb12u1) ...
    22.74 npm ERR! code EBADENGINE
    22.74 npm ERR! engine Unsupported engine
    22.74 npm ERR! engine Not compatible with your version of node/npm: npm@10.1.0
    22.74 npm ERR! notsup Not compatible with your version of node/npm: npm@10.1.0
    22.74 npm ERR! notsup Required: {"node":"^18.17.0 || >=20.5.0"}
    22.74 npm ERR! notsup Actual:   {"npm":"9.2.0"}
    

    I was using Node 16 as a holdover from some work I was doing back at DreamHost. Of course the first thing I did was update Node to 18, but no matter what I tried, Docker would not run the right version!

    I looked at the Dockerfile and saw this section:

    # Development tooling dependencies
    RUN apt-get update \
    	&& apt-get install -y --no-install-recommends \
    		bash less default-mysql-client git zip unzip \
    		nodejs npm curl pv \
    		msmtp libz-dev libmemcached-dev \
    	&& npm install --global npm@latest \
    	&& rm -rf /var/lib/apt/lists/*
    

    When I broke it apart, it was clear than apt-get install was installing the wrong version of Node!

    Maddening. I wrestled around, and finally I added FROM node:18 to the top of my Dockerfile to see if that declare would work (after all, Docker supports multiple FROM calls since 2017).

    To my surprise, it did! Almost…

    Drama 2: PHP

    It broke PHP.

    While you can have multiple FROM calls in modern Docker, you have to make sure that you place them properly. Since node was the new thing, I put it as the second FROM call. In doing so, it overrode the PHP call a few lines down, causing the build to fail on PHP.

    Our Dockerfile is using something like the older version of the default file (I know I know, but I can only update a few things at a time, I have 4 tickets out there to modernize things, including PHPCS), I had to move the call for FROM wordpress:php8.1-fpm to right above the line where we call PHP.

    You may not have that. But if you add in that from node and it breaks PHP telling you it can’t run? That’s probably why.

    Huzzah, the build works! PHP and Node are happy … but then …

    Drama 3: UDP Ports

    Guess what happened next?

    Error response from daemon: Ports are not available: exposing port 
    UDP 0.0.0.0:53 -> 0.0.0.0:0: listen udp 0.0.0.0:53: bind: address 
    already in use
    

    I shouted “FOR FUCKS SAKE!”

    I did not want to edit the compose.yml file. Not one bit. If it works for everyone else, it should be that way.

    Thankfully, Docker has a way to override with compose.override.yml (we have a docker-compose.override.yml file, old school name, old school project). I was already using that because, for some dumb reason, the only way to get the database working was to add in this:

    services:
      db:
        platform: linux/amd64
    

    It’s not a super dumb reason, it’s a Docker vs M1 chipset reason. Still, it was annoying as all get out.

    Naturally, I assumed override meant anything I put in there would override the default. So I tossed this in:

      dnsmasq:
        ports:
          - "54:54/udp"
    

    Turns out, override doesn’t mean override when it comes to ports. I went to the documentation, and there is no mention of how to override ports. On to the Googles! A lot of searching finally landed me on an old, closed ticket that implied I could do exactly what I wanted.

    After reading that whole long ass ticket I determined the syntax is this:

      dnsmasq:
        ports: !reset
          - "54:54/udp"
    

    Finally I could get my site up and running! No idea why that isn’t documented, since the dnsmasq issue is a known compat issue with MacOS.

    Drama 4: Update All The Things

    Then I did the dumbest thing on the planet.

    I updated the following:

    • Docker
    • Everything I use from HomeBrew
    • Mac OS (only the minor – I’m not jumping to the next major release on a Friday afternoon!)

    But I have good news this time.

    Everything worked.

    Final Drama…

    The thing was, I didn’t really want to have to edit the Dockerfile. It’s a tetchy beast, and we all use different OSes (I’m M1, one person is older Mac, one is Windows). Cross compatibility is a bit issue. I did test a number of alternatives (like defining engine in package.json and even mimicking our other setups).

    At the end of the day, nothing worked except the above. No matter what, libc-bin was certain I was using NPM 10, which I wasn’t. I wish I’d found a better solution, but so far, this is the only way I could convince my Dockerfile that when you install via apt, you really want to use the latest.

  • Plugins: Threatening to Go Public

    Plugins: Threatening to Go Public

    A lot, like a lot a lot, of people threaten to go public with how evil the Plugins team is. That rarely works out for them, since most of the time I’m very good about covering my bases, giving people just enough rope to hang themselves, and documenting it to CYA. Also most of the time they’re wrong. If I’m wrong, I apologize and try to make amends.

    But they still threaten. Few people it’s rarely going to be what they want, since they’ll say “I was banned because I refused to fix X” or “My plugin was rejected because wouldn’t change X” and that reflects on them, not me. Now that does depend on what X is, like sometimes it’s as weird as not documenting a remote call, or it’s not wanting to use the default jQuery. A lot of people refuse to stop including libraries that are default in WP for reasons I cannot fathom.

    Today’s story is about one of those where X was a security issue.

    Security Closure

    One of the fun/annoying parts of plugins are security reports. We get a lot and they’re rarely well written so they take time to unpack what the plugin is and what exactly the issue is. Dion has since crafted a way to collect more of the details to expedite (which helps a lot), but back then? I did it all manually, checking and testing every time.

    That routine and practice is a large part of why it’s taking so long for folks to catch up after I left, I had a routine and muscle memory working for me on top of a decade of experience. They’re individually about as fast as I was when I started, and back then we had a lot fewer plugins and a lot simpler ones!

    This report was for a valid XSS and SQL injection issue on a plugin untouched for 6 years. No big deal, mistakes happen and this was clearly a mistake. The plugin was closed and the dev emailed.

    Now these old and non-updated plugin closures usually fall into two categories:

    1. The developer replies, fixes the plugin, all is happy
    2. The developer never replies, plugin is closed forever, sadness reigns

    But then we got the weird one.

    Note: My wife always laughs when I say ‘and then it got weird’ because it’s usually already pretty weird.

    This guy, let’s call him Glen (not his real name), emailed back and said he hadn’t updated but he tested the plugin and it worked on the then stable version of WordPress. Great. But he has to fix the code. So he was told “If you have not updated the plugin on SVN, we will not review it” among other things.

    Glen complained that he did this shit for free (join the club, Glen) and he was the reason WordPress was popular (… what?), and for sure he would not be able to update on short notice. The plugin was already closed and if you’re wondering what notice, he meant the time to disclosure. Remember after 60 days the site will say (in broad terms) why a plugin was closed.

    Now. Saying you can’t fix the plugin asap is totally okay. Take the time you need, but I am not reopening if it’s not safe. Period. It was already 0-day’d.

    Glen wanted me to call him (Hah!) and he would tell me all about WordPress’s many, obvious, security issues.

    No Phone Calls

    I told him no, I would not give him my number.

    He was reminded that the plugin is his responsibility, not mine. I don’t work for him any more than he for me. We’re all volunteers, yadda yadda, and by the way, here’s how you report WP core issues. Finally he was reminded the plugin was already closed, and he could take the time he needed to correct it, even years.

    He agreed to update, when he could. Again, I told him that was fine, and to do what he could when he could, we understood. But Glen got all fired up over being “asked” to “look into” his security issues and continued to complain that he had to fix his own plugin.

    For the record, everyone has 60 days before the reason for closure is made public. There has never been an ultimate limit to fix the plugin after closure. The longest has been over a year. I never cared if it takes you 6 minutes or 6 hours or 6 years! But Glen? Well … he threatened to post on social.

    So let’s get it clear. Glen was going to post on social that:

    1. He was told about a security issue in a plugin he hadn’t touched in 6 years, his plugin was closed, and he was given a timeline for disclosure of why it was closed.
    2. He ignored the security issue and said it worked on 5.X so it’s all good.
    3. He was told we would not reopen the plugin unless he updated.
    4. He decided it was rude of us to say that.
    5. He accused the plugin team of being rich (hah).
    6. He threatened to tell everyone the whole story.

    Besides the fact that it’s not going to go his way (people would read “You refused to fix your own plugin and demanded a known vulnerable plugin be restored?”), it’s pointless. It wouldn’t change anything. The plugin would remain closed and he’d get banned for threats. Because the textbook word there is he was trying to extort us by threatening … dog shaming?

    Stop Hitting Yourself

    I pointed out that his ‘version’ wasn’t going to make him look good. He was welcome to go public if he wanted, but again, all he was being asked was to fix the plugin when he could, and no, I would not reopen it until it was fixed.

    He doubled down, used some choice words about the matter, and was banned.

    I don’t think he ever did go public, but he never fixed his plugin or self-hosted it either.

  • Plugins: Mask of Many Faces

    Plugins: Mask of Many Faces

    There’s a term we use a lot in WordPress forum/plugin work, called Sock Puppets. That’s what we call an account someone makes with the intent of disguising who they are, usually to troll or for some other nefarious purpose. For plugin reviews in particular, the sock puppets are generally used to make fake reviews. Specifically they make a bunch of fake accounts to make five-star reviews for their own plugin.

    While there is a claim that people use sock-puppets to leave one-star reviews for other plugins, that’s really not common. In fact, I only remember three times, and all three ended with banned companies. It’s not worth it. We’re a lot more kind if you make fake reviews for yourself, than if you do it to hurt others.

    Fake reviews are a huge issue everywhere. Amazon and Apple have zero tolerance on them, and will punt you if you do it. On WordPress, I tried to be gentler and I would regularly warn people we caught them, please stop it, and we removed the reviews. If it happened a second time, their accounts were suspended until they replied to confirm they understood. The next step was the final warning (any non-security issues will result in a ban), and after that I would punt.

    Friends or Puppets?

    One day a trio of plugin developers reviewed each other’s plugins. They specifically made fake accounts to do it. They were caught and admonished. They each replied in pretty thoughtless ways:

    1. Replied 4 times, one saying they were all roommates, and said ‘god sees all’ (Zorro)
    2. Replied that he was thinking about quitting WP (Doug)
    3. Replied about bathing (Wally)

    All names are fake. And no, I’m not kidding about Wally:

    Stop brushing and bathing.

    A lot of viruses when will destroy you, then you will understand the importance of cleaning your body and mind.

    Your behaviour is abnormal. You are doing wrong use of technology made by others.

    Wally via email to Plugins

    Wally got the insta-ban because that one is off the wall weird and generally a good indication of trouble. I usually wouldn’t post the whole email but that one is pretty choice and hard to explain otherwise.

    After being banned, Wally said he was happy to leave, that ‘we’ were idiots, he wished that we would lose our jobs and have to beg so people would treat us badly. I got treated badly while I was being paid. Does that mean I win? He ended up saying this:

    May WordPress get a virus similar to Coronavirus and all of you die under debts and people like you who interfere with others lives beggars for people like me and in return I will not put a paise in your begging hands.

    Wally via email to Plugins

    Props for the capital P in WordPress.

    After jokingly calling this a soap-puppet, I figured it was done. But then…

    All For Ban, Ban For All

    Zorro replied to Wally’s email. You read that right. Zorro emailed a reply from his email address and so did Doug. Same email address. Zorro made more comments about God, Doug claimed he had friends in WordPress and I should watch my step.

    Be careful, you may be hurt harder than you expect and at places where you do not expect.

    Doug via email to Plugins

    While it is possible that Wally shared the email around, Occam’s Razor is pretty sharp here. They were all the same person. Three accounts, three separate plugins, a bunch of reviews. And the fact that they all replied in minutes is pretty damning.

    In the end, all three were banned, but only Zorro emailed the Password Reset folks asking why his account was disabled. He offered a bribe:

    I would like to make donation in your account if you restore my WordPress account and plugins.

    You may send me any guidelines.

    Once my plugin start generating income again I will be able to send you 50 dollars monthly for cooperation from your side.

    Zorro via email to Password Resets

    The reset folks said ‘Nope.’ and that should have been that.

    It’s Never Over

    The story doesn’t end there, and I have to backtrack.

    Previously, before they were banned, I wasn’t quite sure they were all the same person. Three friends making puppets together isn’t new, so I laid a trap. This does not make me a great person, I know, but it’s important to be sure. And my trap was pretty benign.

    Each account got a slightly different email about fake reviews. I’ve done this before with good results, because usually people slip up and reply with the wrong email. It’s harder than it looks to be note-perfect with multiple accounts, which is why it’s not worth the time. In this instance, it panned out perfectly as a fourth account, Soren, replied to Zorro’s email!

    Bingo. That’s what I needed, and I banned all four telling them why. I did not cc them on the same email just in case I was wrong. I didn’t want to leak private data. At that point, they all replied with pretty nasty stuff about gods and bathing (what the hell? I shower every day!).

    Enter Aaron. He submitted code that linked back to Zorro and Soren’s website. In fact, it linked back to one of Zorro’s plugins! I banned Aaron and repeated the end of the original ban email, which says not to make more accounts or WordPress.org will have to take stricter measures that could hurt others (IP bans etc).

    Aaron didn’t reply. Another person, Derek, did. If you’re keeping track, this is the 6th account, and Derek said that he didn’t know who Zorro was, but Aaron (the account he was replying for) worked upstairs for a separate company.

    Gif of David, from "Schitt's Creek" saying "What the actual f*ck?"

    Who The Hell Is Whom?

    At this point, we have three people who (purportedly) live together (Zorro, Doug, and Wally) and all their plugins cited Zorro’s website. We also have Soren, who replied to Zorro’s email, and Aaron who submitted another plugin linked back to Zorro. Finally we have Derek, who replied to Aaron’s email saying he didn’t work with Aaron.

    Why did Derek reply to an email sent to Aaron?

    This, my gentle readers, is why having multiple accounts is a shit-show and not worth it. You’re going to screw up and reply with the wrong ones. When you do, you will pay the price. It’s better to just be yourself and be honest. And preferably not an asshole.

    Derek’s email went on to cite some things from Zorro (about gods), Wally (bathing and viruses, again!), and Doug (threats). I did not reply, I filed the email as blocked and ignored it. Derek replied again with basically “you can’t kick me out, I’m leaving!” … Except we already had kicked him out.

    He added we sucked at communication and we were suckers and idiots he didn’t want to work with.

    Signed Zorro.

    From here on out, I will always use ‘Zorro’ for his name. I’m pretty sure everyone was Zorro anyway.

    Of Course He Kept On

    Normally if you tell folks you’re leaving, you actually … leave. Right? Zorro didn’t. Every day for half a month he made new accounts and submitted plugins. He was really stupid about it, too. I mean, they all had the same naming convention and if there’s one thing I’m really gifted at, it’s pattern recognition.

    I had just finished my first pass of my shell-script plugin checker, so I used this opportunity to write a complex set of checks for them, using Zorro’s ‘tells.’ This is why that work is complicated to be made public, it tracks why a plugin cannot be hosted, and outs the person as why. I don’t want the evil populace to know how I’m catching them. And catch I did.

    Finally, Zorro emailed with a new story (and new email). Zorro’s new story was that his ‘accounts’ were hacked.

    Our accounts were hacked. All the emails linked to company were of multiple students who come here to learn WordPress free of cost. We provide emails to them, so that we can use their published plugins as part of project so that we can monitize it.

    Zorro via email to Plugins

    That last sentence threw me for a loop. To monetize? They meant the plan was to funnel people to their company as a free-to-premium flow. Sure, a lot of people do that, but Zorro just said he intentionally used multiple accounts to own multiple plugins to funnel users to pay them. So you know, basic deception where multiple accounts are hiding who they are. Right. Not okay.

    We are never going to stop publishing plugins, we can change IP address, we can ask students to use their own network to publish plugins, use different emails. We can relocate to different location if we do not generate income here. You can not stop us from what we are doing.

    Zorro via email to Plugins

    This kind of rant continued (along with how evil we are, blah blah) when Zorro stepped up the impersonation from the Wally email:

    An email that reads "You are terminated from your job on WordPress and is not allowed to work here anymore. Regards, Matt Mullenweg."

    Again, props for using capital P, but yeah, totally. That’s how Matt would do it. I think he has my phone number actually … I know he has my address after that August surprise.

    It Kept Going

    From May to August, this shit kept going. Eventually I figured out the regex to catch and close the emails automatically, and I built out the scanner to catch ’em faster. Zorro sporadically popped up now and then, making a total of 17 separate accounts by the end of that year.

    Once in a while that year I would catch another email from “Matt” firing me, and it was always good for a chuckle.

  • Plugins: Always Get a Contract

    Plugins: Always Get a Contract

    Sometimes people do stupid things. In the case of Gary (not his real name), it was hiring someone without a contract. This led to a complaint that a developer had taken Gary’s proprietary code and released it in public.

    Gary explained he’d hired Frank (not his real name) to write a plugin for his company, and the agreement was it was not for resale. That’s pretty normal to hear. Gary went on to explain that Frank was from Pakistan (this will come back later) and he’d asked Frank to take down the plugin and Frank said no. Could we step in?

    Time to Dig In

    The answer to Gary was ‘maybe.’ I explained that, per the GPL, Frank was allowed to take and fork the code and release it for free. However, WordPress.org didn’t allow that if the source was a premium plugin. So first of all, was the infringing plugin actually hosted on WordPress.org? You see, Gary hadn’t named the plugin.

    Once Gary linked to the plugin, I took a look for any obvious evidence that it wasn’t Frank’s. Sometimes people credit the source and it’s easy to see if it’s a fork, and other times they forget to clean it up and remove mention of the source. In this case, I saw no evidence, but I did see GARY had a number of warnings on his account for (basically) being an asshole in the forums. Never a good sign.

    In fact, here’s what Gary posted in the forums against Frank:

    [Frank] will take your money and then leave you with a plugin with bugs and [functions] paid for that he doesn’t deliver.

    Gary in the forums

    That’s it. That’s the review. Nothing about the specific plugin.

    I then asked Gary if this was a premium (pay for) plugin. Gary said no (!) but it was a bespoke plugin with a contract provision to not distribute. I pointed out that meant the code wasn’t GPL, so we could remove it, and asked Gary for a copy of the code. I’m sure you won’t take the sucker bet about what the code was licensed, because it 100% said it was GPL.

    Oh and yes, I had to warn Gary that his account was on mod-watch due to that review, which was not a review of the plugin. It was an attack on the developer. Right or wrong, personal attacks have no place in a review of a plugin. If some developer really did kick you in the goolies you should go to a lawyer, not the forums, to complain.

    We understand that sometimes contracts and arrangements go south. This does not give you permission to make multiple accounts and to aggressively attack the developer in question. This is especially true when you are directly contacted and told to come talk to the forums team in Slack, and instead you attempt to contact them personally via [Social Media].

    You were provided with the correct conversational methods, of which this email is in fact one, and instead you flagrantly disrespected and disregarded the directions.

    We will of course still hear your claim and, if there is proof to it, close the plugin permanently. But that won’t make us unlock your account, since you behaved in a manner unbecoming to our community.

    Plugin Team to Gary

    This means it’s down to contract law, and I’m not a lawyer.

    Let’s See That Proof

    I decided to ask the simplest possible option. “Did Frank sign a contract, or was this a verbal deal?” Gary insisted Frank had signed a contract. And he provided ‘evidence.’

    His evidence was a group of undated and unorganized screenshots about their work from Skype. Each screenshot was ‘dated’ in the name (thank you Apple), but that wasn’t actually the order of the conversation. I spent an hour or so trying to get the order correct, and what I saw was Gary asking for a lot of changes in a short amount of time. A lot. Like every other comment from Gary was “and I need this change…”

    Frank would update Gary at the start and end of his (Frank’s) day. I thought that was pretty reasonable, since Frank was in Pakistan and Gary was somewhere in North America. And finally in those screenshots I found where it went south. There was an email from the end of the previous year (remember we’re in January) where Gary said Frank needed to close the plugin on WordPress.org because Gary owned it, not Frank.

    Rather politely, Frank replied that he had only made public the code Gary didn’t want. It took more digging in those undated Skype logs to figure out that Gary had asked for a bunch of features, changed his mind more than once, and Frank had, quite clearly in fact, asked if Frank could use the un-used code elsewhere.

    You know that Gary said yes. Of course he did.

    Fool Me Twice, Shame On You

    I wrote a reply to Gary explaining he’d actually agreed to let Frank share the code, and if Gary would send us his version, we would confirm the private code wasn’t there. My email included a screenshot to prove where Gary said that, just to cover my ass. Before I sent it, Gary sent me another story about how after this incident, he’d hired Frank a second time.

    Y’all, if you hate a developer, why would you hire them a second time? What logic is that?

    In the second incident, though, it got better. Gary had started this second “contract” at the same time he’d complained about the code not being removed from .org. Frank had started to accept the work, changed his mind, refunded Gary, and blocked Gary saying he didn’t want to work with Gary anymore. I felt that was quite reasonable of Frank, all things considered.

    Gary also, as one would expect, took umbrage that he was suspended and Frank wasn’t.

    The fact that you won’t reenable my account because of terrible customer service and rude mods is not something you should hold against me […].

    […]

    If you think I will go down silently, trust me. You have not yet met a monster like me before.

    Gary to Plugins

    I put pause on my initial reply to Gary and emailed Frank. I was honest and told Frank someone was making a claim he’d put code on .Org that violated a contract. I asked if there was a contract at all, and what had happened from Frank’s PoV, because I wanted both sides. Rather politely, Frank said there was only a verbal agreement, no actual contract, and that he decided he didn’t want to work with Gary because he was kind of a dick.

    I chastised him for working sans contract and pointed him to where he could get basic dev contracts that would protect him from things like this.

    It Doesn’t Look Good

    So here we are.

    1. Gary hired Frank to make a plugin
    2. Frank did so, after a lot of back and forth
    3. Gary changed his mind and asked for a feature to be removed
    4. Frank asked if he could put the removed feature up on .org
    5. Gary said yes
    6. Frank did so and linked to the plugin on .org (I think … it was truncated in the undated screenshots provided)
    7. Gary then asked Frank to make a second plugin (knowing the original was hosted on .org)
    8. Frank sent Gary the cost estimate
    9. Gary complained Frank put the first plugin in public
    10. Later on the day of the complaint, Frank refunded the down-payment
    11. Gary complained about the refund being a breach of contract
    12. Frank told Gary he would not work with him anymore and blocked Gary

    From the outside, that looks pretty reasonable, right? And both parties (Gary and Frank) told the exact same story! I love when they line up. Gary had even shared the screenshot that confirmed he told Frank that the unused code was FRANK’S to do with what he wanted. The only difference was Frank said there was no contract, and Gary swore there was.

    Now there’s a funny thing here. I still had no idea exactly which plugin this was! Frank had around 10 to his name, and three were from the December/January period. I had a guess about it, but I asked (for the fourth time) if Gary would please link to the plugin so I could be sure.

    I also asked Gary for a copy of the bespoke plugin to compare (again, this was a repeat ask), proof of a contract (again, a repeat ask), proof Gary had said the plugin was not to be shared (again, a repeat ask), and to please be patient as we’re all volunteers here (a repeat reminder). Oh and to stop telling Frank he was mentally ill, that wasn’t okay.

    Finally Gary linked to the code on WordPress.org. Gary also complained that he had a stellar history on .org (he did not) and I could see his public work history on a freelancing website that has a number for the name. That website, you may be amused to know, showed Gary had nothing but 1-star reviews. Gary claimed he’d conceptualized the plugin and named it (neither of those things are copyrightable to the best of my knowledge, especially since the name included someone else’s trademark).

    The email also came with a mammoth rant about Frank and Gary’s history. Gary was of the opinion that a developer who quit/canceled a contract partway through was ‘too fragile’ to be a developer. Then he went on to explain he’d dealt with a family member who had a mental break, and he thought he saw the signs in Frank. And it came with a lot more screenshots, none of which proved anything.

    Note: I have a tendency to stop talking to people when they get like Gary. It’s not because I’m fragile (as some people like to claim). It’s because when I find the other person so lacking in human empathy and so unwilling to compromise, I see absolutely zero point in continuing the conversation. If there’s no middle ground, and it’s only your way or nothing, you get nothing.

    I read the email and the screenshots and replied:

    Just so we’re clear here, you had no contract and no verbal agreement that he wouldn’t make the plugin publicly available?

    Me to Gary

    The rest of my email explained we needed to see something prior to the dust up of the plugin being hosted on .Org, that in any way shape or form indicated there was any agreement to not host this code on WordPress.org. Remember I had the evidence from GARY that he said it was okay. I wanted the evidence he claimed existed to prove he had said the opposite.

    I also pointed out Skype absolutely lets you export chat logs, and that would be a lot easier to read than the disorganized grabastic piece of shit screenshots he sent (I didn’t say it like that, I said it would make this process a lot faster).

    At this point, it had been 4 or 5 days of emails.

    Why Bother With Directions?

    Gary sent more low-quality screenshots, undated, unorganized, and hard to read. They looked like those fake screenshots people make of texts. That’s how bad it was. The screenshots, once I thought I had them in order, told a story of Gary bombarding Frank with messages at a time he knew Frank was offline (remember North America vs Pakistan). They all took place after Frank had put the plugin on .Org.

    At this point I still had no proof from Gary that he’d ever told Frank to not post the code up on .Org.

    In none of those screenshots is there mention of even “Make this plugin for us and only us.”

    That’s why I asked if you had a contract with him, other than the alleged verbal arrangement in Slack. Even just something that has you saying “This plugin will only be for us, right?” and him replying “Yes” in chat would do […].

    Me to Gary in email

    I also told Gary to, in the future, not be an idiot and get a goddamn contract. Which he should know as a freelancer himself.

    Gary replied that he’d had an actual verbal conversation on Skype. No one had a recording. So we were clearly back to the he-said/he-said world. I hate those. Gary also said if I didn’t pull the plugin, he’d get his lawyer involved. Again, Gary still had not sent me the code Frank wrote for him, so I still couldn’t even check if there was a GPL violation which, at this point, was the only reason I might have to pull Frank’s plugin.

    In fact, if Gary could have proven any of the following, then I likely would have pulled Frank’s plugin:

    • Frank had agreed to never share the code he wrote while working for Gary
    • Gary had asked Frank to not share the code prior to it being submitted to .Org
    • Frank had used code from a non-GPL source

    The whole ‘premium plugin’ reason didn’t really apply here. It maybe was code from a premium plugin but, since I’d never seen that plugin, I couldn’t be sure. Making it even murkier, Frank and Gary both explained the code Frank posted was not part of Gary’s, but Frank had started it to do an above-and-beyond aspect of Gary’s request. Who knew who owned what anymore.

    Gary sent more emails of screenshots (still no log, still no dates, still a pain in the ass to decipher) and swore there was ‘proof’ in there.

    Sure was. Proof that substantiated Frank’s claim. I’ve transcribed so you don’t have to suffer the shitty screenshots:

    Gary: When we’re done with this [plugin] and it works, we’ll put this [on WordPress.org] and release it as a free/pay option.

    Frank: Okay.

    Gary: Free I guess can be the [extra] code which you have created […] then paid can be this version.

    Chat Log provided by Gary

    Later on in those logs was a bit where Frank specified exactly what code would be premium. Frank even said he was specifying so they were both on the same page, and there was no misunderstandings. And Gary agreed to that proposal. Only the ‘extra’ code (which was the only code in Frank’s plugin on .Org) was allowed to be on .Org.

    Tough Nuts

    Gary had no evidence that, prior to the code being on .org, he had ever said that Frank wasn’t allowed to post it. In fact, Gary had provided evidence to the contrary! All of Gary’s ‘proof’ about the code never being on .org happened after Gary found out the code was on .Org. Tough nuts here, Gary, but unless we can prove something, we’re leaving the plugin up.

    Gary replied that ‘the screenshot’ he’d sent was from before the code was on .Org. He’d sent 7 screenshots in the previous email, none dated. His points:

    • He pitched the gig to Frank
    • Frank was overworked and said he could look later
    • When Frank had the time, they Skyped and hashed out the details
    • Frank tells Gary there were issues with the name, according to the WordPress Team
    • Frank sent the beta code to Gary
    • Gary and Frank worked out some changes
    • Gary then “realized” the code was on .Org and complained
    • Frank told Gary the code was limited, and contained none of Gary’s bespoke code
    • Frank told Gary (at some unspecified time) via voice-chat that none of Gary’s bespoke plugin would be public
    • After the breakdown in their work-relationship, Frank put the code up for sale on his own site

    If you’re looking at the fourth point and blinking a lot, me too. Who did Gary think this ‘WordPress Team’ was if not us? I was more-so blinking because Gary concluded by saying I should confirm I knew the conversations took place before Frank put the code on .Org.

    I could not confirm his claim on the timing because …

    • Many of the screenshots were clearly after the build of the plugin (the ones that have him swearing at Frank for releasing it)
    • None of the screenshots were dated so I cannot be sure about timeframes (I asked for the logs because of this)
    • I had no screenshot where Frank asks to have a Skype chat
    • I had proof Frank had told Gary there was a problem with the plugin name according to the WordPress team (aka the Plugin Review team)
    • Gary didn’t pay Frank until after the free version went up on .org (possibly after Gary knew the code was up, timing was unclear)
    • Frank promised none of the premium stuff would be in the .org plugin and Gary said he was okay with that
    • Frank denies any such Skype conversation took place that agreed nothing would be public
    • Work continued after this, with Gary not asking org to remove a plugin that he was aware of existing
    • After the money was refunded, Frank purportedly was selling the premium version on his own site (no one ever linked to where that might be)
    • Only then did Gary come to the plugin team
    • WordPress.org has no oversight as to what Frank does on his own site

    So Gary was asking for WordPress.org to remove the free plugin that actually he agreed was okay to make and give away, with code he didn’t want in his bespoke plugin. Code he had, per his own screenshots, very clearly agreed to have hosted on .Org.

    After the Battles

    In the end, Gary got nothing. He remains banned from WordPress.org since, after that, he made a couple hate-attack accounts to go after Frank. Frank ended up taking that plugin down because, as he said, he was tired of Gary’s abuse. He also claimed he’d learned his lesson about having a contract and statement of work before doing work.

    Gary never provided his copy of the code to validate the GPL issue. Gary never provided logs (with time/date stamps) that confirmed the order of events was what he said. Gary had no contract, only a verbal agreement, that Frank disputed.

    This was memorable simply because I’d really never had anyone show me a screenshot proving the exact opposite of what their claim was before.

    It was not the last time, but that’s a story for another day.