HNHacker News
TopNewBestAskShowJobs

leafo

2,249 karma · joined August 28, 2010

check out MoonScript: http://moonscript.org
submissionscomments
leafo··on Luarocks.org remote code execution exploit
> I'll send you an e-mail from my address and I'll ask Vhyrro to forward the original emails to you again.

Much appreciated

> Messaging or tagging you there about an unpatched RCE would have effectively been a public zero-day disclosure, which we strictly wanted to avoid.

No one is saying that, huh? Are we following the same timeline? At this point you have emails out to me a Hisham. You aren't hearing back from us, it's been a while. The issue seems pretty bad. Any way of nudging either of us to check, "Hey, something important about LuaRocks, check your email" in a dm, or a message to anyone else related to LuaRocks. There's a million ways to get my attention without publicly disclosing the issue. Dang, even you could have sent an email.

> That, too, would have been a public disclosure.

I wasn't suggesting you publicly disclose. I'm trying to understand how you understood what was at stake. You have your own community of users with rocks.nvim consuming files through luarocks.org that would potentially be installing malware. I also asked you "Did you stop using LuaRocks?" I'm trying to assess if you just didn't see it as that severe of an issue.

Look, I fully accept your defense of "We did what was in SECURITY.md. Not our fault that the emails were never delivered. Anything else is outside our responsibility. " If you're just some random security researcher, I accept it. My argument is that you aren't a rando and you're more tied to the ecosystem, and have more responsibility. But maybe you disagree.

> Rather than going back and forth on motives, how about we focus on establishing a clearer direct line of communication for the future?

Yes, thank you! I've been waiting for email from anyone at this point. I tried to get info from Vhyrro way before this HN thread but got ignored https://github.com/vhyrro/luarocks-rce-proof-of-concept/issu...

> Since I did not conduct the research myself, I am not in a position to comment on the technical details of it.

You have enough intimate details of the situation to participate in a multi-day conversation with me on behalf of Vhyrro's work but conveniently don't know anything else? Were you a politician in another life? :)

I will follow up with your email, thanks

Sorry for all the snark, I hope you can at least empathize a little with my situation.

leafo··on Luarocks.org remote code execution exploit
Just wanted to follow up and say that Hisham confirmed with me he didn't receive any contact from Vhyrro. Feel free to have Vhyrro forward the emails again so I can find out why all their attempts to report the issue disappeared into both of our spam folders. You are building something very relevant to LuaRocks.org, you should have a direct line of contact with me.

> Apart from that, we couldn't find any alternative way of reaching you.

I'll just be blunt, I find this very hard to believe.

I want to take a moment to express why I feel the way I do. If you were a random security researcher, then great. You tried to contact me, the emails got lost along the way. There isn't much you can do. But from what I can see, you're a member of the Lua community who actively uses LuaRocks.

Did you stop using LuaRocks while you were aware of this issue? Did you instruct other people not to use it within rocks.nvim? For all you knew, every module on the site could have been replaced with malware infecting anyone installing any package. The severity of this was a "drop everything and panic" scenario, not an "I asked a group chat, oh well."

When you say something like, "Apart from that, we couldn't find any alternative way of reaching you," it makes me scratch my head. I am grateful you tried to contact me, but statements like that make it hard for me to give you the benefit of the doubt regarding your attempts to contact me.

And that doesn't event address the parts you glossed over in your account of the situation, specifically the actual exploitation on the production server without clearly stating that from the get-go.

leafo··on Luarocks.org remote code execution exploit
Yes, I did thorough scan of my email, with Vhyrro's email, name and other keywords related to luarocks. Nothing was found. I asked Hisham to take a look for an email as well.
leafo··on Luarocks.org remote code execution exploit
> Vhyrro found your Gmail address and sent you an email on August 7th:

I just searched my email and found nothing. Do you have subject line, sender address or receipt or anything that would help me find the emails that were sent?

> found your personal Matrix handle. That's when Vhyrro DM'd you on Matrix.

I don't use Matrix. There's a gitter.im for Luarocks that's effectively dead. I last was there in January 2026 asking if the server was alive but never returned. I logged into gitter right now to check and I was able to find a DM request from August 20th, I wouldn't have seen this under any normal circumstances though

Well, thanks for sharing you attempted to contact me at least.

leafo··on Luarocks.org remote code execution exploit
In my opinion, this is a terrible display of "ethical" reporting.

For context, I built and run the luarocks.org website. It's very easy to see I run the website, and find my contact information. I appreciate that they eventually shared the exploit but...

* They sat on this vulnerability for over a month, likely trying to figure out how to fully exploit it, instead of reporting it. (I would imagine their ai agent upon seeing the `loadstring` issue told them "go tell the maintainer immediately", which they ignored)

* They finally reported it through an intermediate, CISA.gov, and never contacted me directly. When CISA eventually reached out to me, it took multiple days for me to get approved to view the report.

* When I got access to the report I stayed up all night doing deep investigation of logs, all packages and doing the server rebuild. I published the security bulletin on the luarocks.org website (https://luarocks.org/security-incident-september-2026) as soon as the server was rebuilt. They saw it and had time to write up this entire dramatized blog post but still haven't contacted me. (I asked for a follow-up through CISA, but I don't know how long those exchanges take.)

* The vulnerability was exploited on production luarocks.org during that time by them, and they failed to mention any production testing in any of their reports, both in the blog post and in the CISA.gov report.

* They position themselves as members of the Lua community, running alternative Lua runtimes and a new Lua package manager, yet they sat on a very critical issue that affected much of the Lua community for an extended period of time.

* Update: they replied to me on CISA, acknowledging that they exercised the exploit on the production server. (This is still not disclosed anywhere) They said they only did a "sleep" test, but our server logs contradict their attempts based on the accounts they revealed to be as part of their testing.

I get it, you found an exploit and you want credit for your hacking skills, but this whole exchange has really rubbed me the wrong way. Since they haven't told me what malicious code they ran on the production server, or verified what accounts they used to exploit the sever on production, it wastes my time when I'm doing forensics to analyze the extent of what happened to make the appropriate decisions incident response.

In the current era of LLM coding, anyone can vibe code a new Luarocks in Rust (or whatever is popular) over a weekend. I think that establishing trust is more important than ever, and this interaction just makes me question the maintainers of Lux. Their own self-interest appears to be above whatever they are trying to do for the Lua community at large.

leafo··on Mastercard deflects blame for NSFW games being taken down
Throughout this our only contacts have been representatives at Stripe and PayPal. They indicated that they got a notice and kicked off their own audit.

As far as I'm aware, the Collective Shout letter caused a "formal card network inquiry" to originate from both Mastercard and Visa. I did not have access to the actual inquiry, but my assumption is that it wasn't "we see this content, take it down" and more like "we saw this letter, look into whats going on before we do our own investigation and fine you"

leafo··on Itch.io Taken Down by Funko
Interesting, this morning I got a response from a staff member of the parent company that owns iwantmyname saying they didn't get my response with regards to the abuse notification they sent and that's why they took the domain down.
leafo··on Itch.io Taken Down by Funko
Unfortunately the domain has a hold placed on it by the registrar, so I believe transferring is disabled. I also wouldn't want to risk doing a transfer at an hour when their staff aren't available to help with the current issue.
leafo··on Itch.io Taken Down by Funko
I'm the one running itch.io, so here's some more context for you:

From what I can tell, some person made a fan page for an existing Funko Pop video game (Funko Fusion), with links to the official site and screenshots of the game. The BrandShield software is probably instructed to eradicate all "unauthorized" use of their trademark, so they sent reports independently to our host and registrar claiming there was "fraud and phishing" going on, likely to cause escalation instead of doing the expected DMCA/cease-and-desist. Because of this, I honestly think they're the malicious actor in all of this. Their website, if you care: https://www.brandshield.com/

About 5 or 6 days ago, I received these reports on our host (Linode) and from our registrar (iwantmyname). I expressed my disappointment in my responses to both of them but told them I had removed the page and disabled the account. Linode confirmed and closed the case. iwantmyname never responded. This evening, I got a downtime alert, and while debugging, I noticed that the domain status had been set to "serverHold" on iwantmyname's domain panel. We have no other abuse reports from iwantmyname other than this one. I'm assuming no one on their end "closed" the ticket, so it went into an automatic system to disable the domain after some number of days.

I've been trying to get in touch with them via their abuse and support emails, but no response likely due to the time of day, so I decided to "escalate" the issue myself on social media.

leafo··on Ask HN: Anyone learned art (drawing, caricature etc.) as an adult?
I've been trying for a few years now, trying to get something made most days. I actually made a website to track my progress by giving me a place to upload and get a GitHub like calendar streak: https://streak.club/s/8/daily-art-club

Here's my profile with my art: https://streak.club/u/leafo Currently in a gouache phase, but I have done sketching, figure drawing, watercolor, digital painting over the years

Here's the my figure drawing: https://streak.club/u/leafo/tag/figure-drawing

leafo··on Lapis: A Web Framework for Lua
Lapis is very dependent on the server backend it is running in, generally OpenResty.

Last I investigated, the ergonomics of the websockets API in OpenResty didn't really seem like a good candidate for building websocket based applications. As an example, there's no trivial way to keep track of all connected clients and broadcast a message to them without overly complicated solutions. It's not trivial to listen to events from different asynchronous sources at the same time. (probably other things too but I don't remember right now) OpenResty/Nginx is not a general purpose event loop. The fact that it's primarily an HTTP webserver is evident in the design of the interfaces that are made available.

That said, there's nothing stopping you from and utilizing the `ngx` APIs directly, there are just a few considerations to be made with database connection pooling, but generally you can `require` any Lapis module and use it anywhere in Lua code. For websockets in OpenResty look here: https://github.com/openresty/lua-resty-websocket

The reason the issue is still open is not because I'm not interested in adding it, but because I didn't feel Lapis could provide a useful abstraction at this time.

leafo··on Lapis: A Web Framework for Lua
I suppose I haven't really fully considered this use case, but...

There's no requirement to put your entire app in a location / {} block. You can freely use as many location blocks as you want, and those that you want to be rendered by Lapis can call serve to the app as normal.

eg.

location = /exact-match { content_by_lua 'require("lapis").serve("app")'; }

location /directory-match { content_by_lua 'require("lapis").serve("app")'; }

Keep in mind pattern matching will still happen in the app: You will need to define the routes handled by Lapis within the definition of the Lapis app. Why is it done this way? Primarily, for named routes. Typically you want to be able to generate the URL of a resource within your app's code, so by having routes defined in Lua you can easily reference those. Secondly, easy parameter parsing and the parameter validation.

> It's got some nice utilities that we use, but we ended up just using regular location {} routes each with their own content_by_lua code block and none of the lapis routing/handler stuff.

Although it's very possible to pick and choose what components to use, keep in mind that the `serve` function does some important work with connection pooling. If you are using any query related functionality outside of a dispatch it will open and close connections per request, which is not ideal for performance.

leafo··on Ask HN: How do I get into art?
Not exactly clear from your post if you're interested in making art or just appreciating it. I feel like making art is definitely a good way to learn how to appreciate it, as you will uncover how hard making art is and you will train your eyes to spot details. You'll learn to see signs of quality and cool techniques that will enable you to appreciate more works.

I'm a programmer trying to become a better artist, specifically with drawing. I've seen all kinds of strategies about how to do that, but the one suggestion I've seen that is repeated by everyone is do the thing regularly. (Note that I specifically didn't say 'practice' regularly, since often practice and leisurely drawing/painting/etc. are disjoint. You're in this for the long term so you don't want to burn out by losing sight of what about it brings you joy)

I actually run a small daily art club online on a website I made called Streak Club. If you're interested in having a little space to keep track of your progress then I'd recommend giving it a shot: https://streak.club/s/8/daily-art-club

leafo··on A small Stripe fraud story
I'm curious, you folks probably make money off of fraud right? You probably have negotiated whatever dispute fee you pay processors directly well below the $15 you pass on to sellers, pocketing the difference.

So I'm guessing that Radar's price was set with this in mind, you ran the regression to set a price to ensure revenue does not decrease by having better fraud detection. Hence the super expensive price. If this wasn't the case, Radar probably would be free.

Probably creates a really bizarre incentive. You don't want to deal with obvious scams that hurt processing reputation, but you probably also want to make your built in fraud detection just crappy enough to ensure you capitalize on that revenue.

leafo··on A Facebook crawler was making 7M requests per day to my stupid website
Same thing has happened to me: https://twitter.com/moonscript/status/1124888489298808834

The network address range falls under Facebook's ownership, so I don't think it's someone spoofing. I do think it's very possible someone found a way to trigger crawl requests in large quantity. Alternatively, I would not be surprised it's just a bug on facebook's end.

leafo··on Strike: A web-based, 1-bit paint tool
The developer is aware and they're going to make it so the project doesn't depend on localStorage being available to run the project: https://twitter.com/_morphous/status/1256465513611436034

In the meantime, you'll have to grant access

leafo··on Writing a DSL in Lua (2015)
Hey, I'm the author of this blog post. Thanks for posting it whoever did.

I wrote this a long time ago, it's mostly targeted at Lua 5.1 but more recent versions of Lua approach function environments differently, so keep that in mind.

I've written & worked with quite a few HTML generation DSLs at this point. I put them into two groups:

1. Nested object return: the object is converted into HTML after executing the template

2. Evaluate and write to buffer: no return values, each "tag" is a function call that generates code in a background buffer (nested html typically accomplished by blocks or inline functions)

Approach 1 is what was used in this blog post. Approach 2 is what I ended up using for my web framework: https://leafo.net/lapis/reference/html_generation.html

Approach 1 is used by React. Approach 2 I first came across in a library called Erector: http://erector.github.io/erector/

I prefer approach 2. It lets you use your programming language constructs to do things conditionally, in loops, or whatever else your language provides.

I find that with approach 1 you tend to try to bend the language to convert everything into an expression that can be returned into the nested object you're building. The example I have off the top of my head is how React devs will write some pretty nasty ternary operator expressions just to write some HTML conditionally directly inside of a JSX chunk. (The alternative would be pulling things out into temporary variables, which just creates a lot of noise)

As a fun aside for how far you can take things, for my implementation of approach 2 in my web framework, I ended up writing a syntax transformer that could pre-render static HTML chunks to plain sting that can be appended to the output buffer. Essentially removing those function calls and any HTML escaping that would be necessary during evaluation time of the template.

leafo··on MoonScript: Dynamic scripting language that compiles into Lua
Not really, all of my time is going into my company so I'm not really thinking about big picture stuff with MoonScript.

Some things I would like to eventually finish though:

* JavaScript output backend https://github.com/leafo/moonscript-javascript-compiler

* Replacing the AST transfomer with something written in tableshape: https://github.com/leafo/tableshape

* Experimenting with writing an lpeg alternative that works more like a parser generator, experimented here https://github.com/leafo/moonparse

* Formalizing the syntax transformation pipeline (this would be how things like macros could be implemented)

If you have ideas feel free to open issues on the github. I may not be able to reply immediately but at least they are written down somewhere. Thanks

leafo··on MoonScript: Dynamic scripting language that compiles into Lua
There is no MoonScript VM, if you use the "execute moonscript" function provided by the moonscript library it internally compiles the moon code to lua, loads the lua code, then runs the lua code.

This means that MoonScript compiled ahead of time will have the same exact result as running it on the fly.

leafo··on MoonScript: Dynamic scripting language that compiles into Lua
My strategy is typically store MoonScript in separate files, then have build process that generates Lua and bundles that inside of whatever else. I wouldn't typically put it in a C file, but I might have the build system generate a hex encoded string as a header file. (This is actually how I build the MoonScript source into a single exe for Windows builds)

I recommend doing the MoonScript compile time at program build time to avoid any unnecessary compilation during runtime.

leafo··on MoonScript: Dynamic scripting language that compiles into Lua
> class attributes are mutable and shared across all instances

an OOP module from Lua is likely going to work the same way. Most class based languages would behave the same (Python, Javascript are examples I can think of)

A "class attribute" is a value stored on the object that represents the class. This is a prototypical language, so all instances of a class share the same prototype associated with the class.

Regarding immutability, you could use metatable tricks or a library to enforce immutability on a Lua table. That's not something the language provides.

> to give an instance its own state you gotta define attributes in the constructor

So I believe the reason why you're making this distinction is because the prototypical inheritance and the explicit section that talks about this in the documentation. MoonScript lets you have any value be part of the prototype, not just methods/functions.

So I guess I'm writing all this to say that it's not weird, it's just the nature of prototype-based languages. I specifically call out this case in the docs to help people not get stuck.

leafo··on MoonScript: Dynamic scripting language that compiles into Lua
Disclaimer: I'm the author of MoonScript

> Yes, the class stuff in MS is plain wrong

There's nothing wrong about it, I'm sorry you don't like it! I'm happy that you have your own ideas but to go around saying it's wrong isn't very cool. The system was very intentionally designed. Now that's it's been 9 years and I've written 100s of thousands of lines of MoonScript, the class has proved to be very reliable. It compiles to simple concepts that are easy to reason about when working with both large and small code bases.

> The thing is, the prototypal, copy-on-write nature of Lua object orientation

This line is confusing to me. There is nothing about lua that is fundamentally copy-on-write. That would have to be a choice the developer makes, but it would be hard to enforce with language primitives unless you're hiding data within meta-tables

I think you're getting hung up on details that have nothing to do with MoonScript: if you want a different language then use a different language. Don't go around saying it's wrong because it's not the language you want.

leafo··on MoonScript: Dynamic scripting language that compiles into Lua
Thanks for your enthusiasm, but I just wanted to clarify that I'm still leading the development of the project. I'm happy to see other people's ideas about how the language could be different, but I'm going to be very conservative about any accepted changes. I have a lot of code running in production in MoonScript that I have no plans to rewrite, so I have no plans to make breaking changes to the language. I feel it has reached a level of stability with the syntax that I'm mostly happy with. I encourage you to try out other stuff with your fork though. Hope that explains.

For others, the discord linked above is the official one, so feel free to stop by.

leafo··on MoonScript: Dynamic scripting language that compiles into Lua
Hey all, thanks to whoever posted this.

I'm the creator of MoonScript. I code in MoonScript daily, it's an integral part of many of my projects, including the company I run. It's something I launched a very long time ago, it's been featured on HN quite a few times now!

I feel a little bad for threads like this: if you look at the github or the website, it hasn't seen any significant updates in quite some time. The reality is, though, it's reached a level of stability where I don't need to worry about it and I can work on using it to build other things. Although I have many ideas to fundamentally change it, introduce new operators, paradigms, etc., at the end of the day I value more that is has stayed pretty consistent. I have 100s of thousands of lines of MoonScript running in production environments. I'm more interested in refining the tooling & squashing bugs. I'm considering just bumping the version to 1.0 so people don't get confused about the viability of using it. If it's something you think fits your needs then go for it. I will continue to support it indefinitely because of how integrated it is into many of my projects.

Tell me if you have any questions, thanks!

leafo··on Moonjit – Fork of LuaJIT to Continue Development
There's a patch for LuaJIT that increases the limit. It comes pre-applied with the LuaJIT that installs with openresty. https://github.com/openresty/lua-nginx-module/issues/1019
leafo··on Ask HN: What have you done to improve your desk ergonomics?
I ditched regular desk chairs for an Ikea Poäng many years ago. But then one day I realized that the Poäng was giving me lower back pain, so I ditched it. Now I sit on the footstool that came with the Poäng. (for the past 4 years now, I'll do cross-leg, squat, any kind of sit you could do on a floor)

My keyboard is an ErgoDox EZ with the lightest key-switches I could find (bought them separate, soldered them on), and my mouse is placed in the middle. I'm happy with other keyboards though, my general keyboard requirements are:

* ortholinear

* as many modifier keys on the inside as possible (eg CTRL/SUPER/SHIFT for pointer and thumb, instead of using pinky)

* split layout

I use a 3M adjustable keyboard tray (atk91le) screwed into my desk so I can easily adjust position for whatever posture I'm in.

If you sit too long without moving you will hurt, so I make a point to switch up how I sit, or get up from my desk frequently. I really like the footstool as a chair because it's like an elevated floor, there are many ways to sit on it.

If my lower back is tired (no backrest on a footstool), I have a Nada Chair that I'll sometimes strap into.

I have scoliosis, so I think I've had to deal with lower back pain much more than the average person my age.

leafo··on A patent lawsuit against GNOME
Serial patent troll: https://arstechnica.com/tech-policy/2017/04/garmin-sued-in-e...
leafo··on Cool but obscure X11 tools
This is a great program, essentially PaintTool SAI recreated for Linux
leafo··on Cloudflare Raises $150M and Adds to Board of Directors
Yes, if you use too much bandwidth a business rep will reach out to you and tell you that you must upgrade to a per gb plan to continue using their service. In my case, I think I was at about 40TB a month
leafo··on Itch.io – Marketplace for Indie Games
how is it broken? (I do know our search results page isn't ideal, but if you search a tag there's a link that takes yo to that relevant page)
Page 1 of 4Next →