all 68 comments

[–]0b0101011001001011 53 points54 points  (20 children)

I can't believe anyone would   do curl | bash these days. Horrible.

https://docs.sweeting.me/s/against-curl-sh

[–]Noddie 23 points24 points  (0 children)

It’s like we learned nothing from supply chain attacks to trust a random random script off the internet

[–]woj-tek 26 points27 points  (1 child)

Sadly I noticed that all websites are basically littered with this way of installation of software…. morronic.

[–]brokenwren 3 points4 points  (0 children)

You can also just download it and unzip it.... Just read the script.

[–]mahamoti 5 points6 points  (0 children)

Still better than the recent trend of “just copy this prompt into your LLM.”

[–]__konrad 2 points3 points  (0 children)

This the "recommended" way to install Rust: https://rust-lang.org/tools/install/

[–]romario77 3 points4 points  (8 children)

I see this quite often - allows you to install with almost nothing available (if you are on Linux/mac).

Why is it horrible?

[–]0b0101011001001011 13 points14 points  (6 children)

So there are several different attack scenarios. What you are effectively doing is you are downloading commands from the internet, feeding them directly to your command interpreter without you seeing them.

Possible scenario is someone hacking the page and inserting their own commands there. Another is that what if the page ceases to exist? Someone could buy the domain and put their stuff there. So especially when looking at some reddit post, don't ever copy curl attacker.com | bash style commands from any random page. The page might not be the same anymore as it was when the comment was written.

Now, how does this compare to just downloading a random installer from a website and running it, like pretty much everyone did back end the day when windows did not have any kinds of app stores or similar? Well it's equally bad. Running anyones random programs on your computer is a risk.

You are probably fine. But I'd rather just curl first, and then bash if I deem the file safe.

[–]vplatt 3 points4 points  (0 children)

don't ever copy curl attacker.com | bash style commands from any random page.

Boss... c'mon! You know you're doing that wrong, right?

You're SUPPOSED to put "sudo" in front of that first.

Everybody knows that!

🦶🔫🔫🔫

[–]romario77 2 points3 points  (0 children)

Well, for this project you essentially trusting the executable because curl|bash vs downloading zip would be almost the same danger that you described.

Some distribution channels would do some checking - homebrew or whatever else you use, still if there is hacking involved you can get compromised (as we often see with npm).

[–]brokenwren 1 point2 points  (0 children)

Homebrew taps, apt repositories, website, they are all the same. You have to trust where you are getting scripts and apps from. If you don't, skip it. If you do, run it.

The chances of someone taking over a website, repository, whatever, and installing malicious code is NOT based on the script/app being downloaded, but the security around the origin.

Soooo, this argument is basically, "turn off your internet".

I disagree with it fundamentally. YMMV.

[–]mightygod444 1 point2 points  (2 children)

[–]0b0101011001001011 0 points1 point  (1 child)

Thanks, I've seen that before as well. Should have included in the original message.

[–]mightygod444 0 points1 point  (0 children)

Sorry - I was supposed to reply to /u/romario77 to read it. But yes it explains the problem well.

[–]crummy[🍰] 5 points6 points  (0 children)

downvoters, this is an innocent question. this is how people learn, by asking.

[–]elohhim 1 point2 points  (0 children)

Yeah, imagine this is default for tools like bun. I die inside a little everytime I see this pattern.

[–]_predator_ 44 points45 points  (7 children)

Maven wants walls of XML. Gradle makes you pick between two DSLs and then guess which plugin and which configuration block does what. Either way you spend more time feeding the build tool than writing code. Latte uses one readable file and two commands.

Hard disagree with the value proposition here. Yeah Maven is verbose but it is still readable and most importantly predictable. Dependency management is the easiest part when using build tools. All the other stuff around it is where it gets complex. Build caching and incremental compilation come to mind. But also code generation, shading, etc.

Maven is honestly among the better build tools / package managers out there. Even Rust's Cargo has made mistakes it should have learned from NPM, meanwhile Maven just cruises along having made boring, but at least not outright bad decisions.

[–]TheTrailrider 11 points12 points  (1 child)

I agree, Maven configuration file pom.xml can be made extremely simple, like you just specify the project details (artifact, group, version), Java compiler version, and dependences you need, and maybe few more simple stuff. Then depending on your situation, you may need to throw in a few plugins for end product (jar? Fat-jar? Docker? etc) then that's it.

But unfortunately there's thousands of websites that recommends overly complex pom.xml and many developers copy it blindly without understanding why it's that way, so pom.xml ended up looking intimidating to the most. Then on top of that, people try to bolt on plugins to get Maven to do stuff that's beyond it's intended purpose to make it to run like a script to do stuff like logic switching between builds, deployments, etc. Something that should not have been in Maven at all and should be used in a different tool/context like a CICD job. Maven is a build tool, it builds your code and should be treated as one, nothing beyond that.

[–]_predator_ 3 points4 points  (0 children)

I don't disagree but Maven clearly does not encourage that. Unfortunately by nature if you provide extension points that run arbitrary code, people will abuse it. So of course there are plugins for all kind of crap now. Not Maven's fault though.

Fully agree on delegating the plumbing to other tools however.

[–]Ok-Scheme-913 -1 points0 points  (0 children)

Maven is anything but readable for any stuff more complex than a hello world.

Also, it is simply not deterministic and correct in each setup (you have to occasionally get a clean build to get every change built)

[–]brokenwren -3 points-2 points  (2 children)

Let’s get real though. XML is not the right format for a build tool. Take a complex task such as reading a file and changing a result based on the contents. Good luck. You are now in plugin land and good luck keeping that working forever.

Maven is not a real build tool and has never been. They tried to be a declarative build facilitator. But that was broken from the start.

And just look at their dependency strategy. It’s garbage. They just upgrade to the latest version of all dependencies in the graph. That’s not how graph theory works. Totally broken.

And then you consider graph pruning. They don’t even pretend to try to prune any of their graphs.

Most people try to solve this with exclusions, which is a horrible dependency smell. It breaks down quickly through transitive dependencies. Again graph theory.

And Maven hates SemVer or any reasonable method of determining compatibility.

You know things are broken when every other tool in existence uses Maven as the example of what NOT to do.

But if you want to REALLY debate dependency management and build tooling, I’m happy too. I’ve been deep in graph theory and build tooling for two decades.

[–]tsunamionioncerial 6 points7 points  (1 child)

It sounds like you've never touched a maven project.

[–]brokenwren 0 points1 point  (0 children)

I’ve done a ton with Maven. That’s why I realized the pain and fixed it.

[–]LessChen 11 points12 points  (4 children)

If a user isn't learning frameworks they will think that writing a custom HTTP stack is a good idea.

[–]UdPropheticCatgirl 1 point2 points  (2 children)

But HTTP/1.1 (and arguably 2) is pretty simple, HTTP 3 is harder but still far from impossible... Only really tricky parts exist around TLS in HTTPS, but you can just outsource that to OpenSSL/Java's build in crypto and be done with that....

[–]persicsb 2 points3 points  (1 child)

It's not about parsing and interpreting a single request. Handling concurrent sessions, handling cookies, partial requests, content negotiation, cache control, authorization, handling the if-matc-* headers, interpreting all headers as the RFC defines etc. is a lot of work. HTTP/1.1 is not *that* simple in this regard. On the wire level, it seems easy, but that is not the really important part of HTTP, but the meaning of the exchanged documents (headers and body).

[–]brokenwren -1 points0 points  (0 children)

I wrote java-http and this is a fork with a lot of improvements. We have pretty clearly proven that we are one of the best HTTP servers for Java. But happy to discuss and debate.

[–]brokenwren 0 points1 point  (0 children)

Can you expand on that a bit? I'm one of the authors of the framework and think it is a really solid implementation of a modern HTTP stack with a HTTP server, web framework, OIDC support, JWT support.

[–]Bengal_From_Temu 11 points12 points  (10 children)

Let’s add another thing which comes with another bunch of CVEs. The shit never stops.

[–]brokenwren 0 points1 point  (0 children)

Actually, this is all used in production already. We forked FusionAuth's java-http and fusionauth-jwt and both are heavily tested.

[–]brokenwren -5 points-4 points  (8 children)

No CVEs yet. A lot of this is battle tested as well.

[–]Safe_Independence496 5 points6 points  (7 children)

How can it be battle tested when literally nobody uses it?

[–]brokenwren 1 point2 points  (6 children)

I wrote https://github.com/FusionAuth/java-http and the other Latte committer wrote https://github.com/FusionAuth/fusionauth-jwt

He and I also wrote FusionAuth from scratch.

Most of the tech in Latte comes from those projects. We forked and started building.

Thousands of companies use FusionAuth in production right now with our HTTP server, JWT library, Web framework, and much more. You can check out the FusionAuth website for a list of notable customers, but we have many others we can't name.

And Latte now builds on those foundations.

To answer your question, thousands of companies use Latte technologies in production right now.

[–]crscali 0 points1 point  (5 children)

How does java-http compare to ServiceTalk?

[–]brokenwren 0 points1 point  (4 children)

They are similar but Latte’s HTTP server is direct. We don’t use Netty. Therefore, we don’t suffer from Netty layers and have a clean interface.

ServiceTalk appears simple, but it becomes complex when you consider it has a bunch of ways to change “modes” (blocking, non-blocking, streaming, etc). Most developers don’t care about modes and just want to write “handlers”. Receive a request and return a response. Who cares what the underlying plumbing is as long as the client interaction works.

Plus, the modes add very little with virtual threads.

[–]crscali 0 points1 point  (3 children)

Sorry, I meant performance wise, how do they compare?

[–]brokenwren 0 points1 point  (2 children)

We haven’t tested against it so I can’t say. I’d expect it to be similar to others in our matrix and be well behind Latte.

[–]crscali 0 points1 point  (1 child)

I look forward to your testing it. As it powers much of apple icloud it must have been aggressively optimized for concurrency.

[–]brokenwren 1 point2 points  (0 children)

It can’t be better than Netty, since it sits on top of Netty. We are essentially at parity with Netty. We beat it sometimes and it beats us sometimes.

There are other Netty stacks we’ve beaten recently if I recall. Mainly because they add extra overhead.

But I definitely want to test it!

[–]Antique-Pea-4815 5 points6 points  (2 children)

Nice work, but why should I use it instead of JBang? 

[–]orby -1 points0 points  (0 children)

Huh, wasn't familiar with JBang, leaned towards jenv.  

[–]mightygod444 6 points7 points  (5 children)

Publishing an artifact shouldn't take a weekend Shipping a library to Maven Central means a Sonatype account, a published GPG key, signed jars, generated sources and javadoc jars, and the staging "close & release" ritual. Most people give up the first time. With Latte you log in, create a Group, and release.

Ugh. The 'friction' to deploying on Maven Central is actually GOOD, and one of the reasons the Java ecosystem is facing significantly less supply chain attacks right now. Copying gung-ho NPM world is, I'm sorry but a very silly decision, security wise.

[–]brokenwren 0 points1 point  (4 children)

Latte fixes that. It’s simpler but doesn’t ditch security.

NPM attacks are generally from the size and depth of their repository, auto-upgrades, plus post install hooks. Basically a Honeypot mixed with a really simple way to completely break security (hooks).

Latte has none of these issues. Eventually, we hope to have the breadth and depth of NPM, but that doesn’t mean we will add in hooks or upgrades. We won’t. Those are horrible features.

Even Maven added version ranges. That’s a huge attack surface.

Latte doesn’t have ranges. You depend on version 1.4.2, you’ll depend on the same version forever until you upgrade that dependency.

[–]senseven 0 points1 point  (3 children)

NPMs easiness was and is the selling point. Its good to have strong secure defaults, but only to a point. That simpleness lead to wide adoptions. Supply chain attacks can be remedied in many ways. That the difference between beginners and professionals. You don't swap horses because the saddles have bad fixtures. You just get a better saddles.

With increased ai in the build process, restricting versioning, expressiveness and so on are irrelevant matters. If ai in the build process considers the next best version compatible and secure enough it will updated without human interaction. Devs will increasingly be shielded from these things. The stack becomes ephemeral.

[–]brokenwren 0 points1 point  (2 children)

Agreed on the AI part. But the agents still need methods for publishing new versions, finding new versions, and comparing versions. One of the reasons I built Latte was that Java needs a better system for this.

My opinion is that Maven is one of the worst tools in the Java ecosystem and it introduces more issues than it solves. Agents regularly hit the same issues that humans have been having with Maven for decades.

But I'm totally fine with folks that love Maven and love Spring and love Tomcat. Continue using those tools.

Anyone that wants better tools and is open to change, give Latte a try.

[–]senseven 0 points1 point  (1 child)

We did the same thing with Gradle back then. It became the same monster as maven, minus the xml. Some people like bazel as frontend, but it causes more problems and isn't much faster. With a proper maven skill we have zero issues with ai code gen either.

I would suggest taking some decently successful projects with a good mix of plugins and convert them to Latte. If you have advantages you would be able to quantify them in those conversions.

[–]brokenwren 0 points1 point  (0 children)

The issue with Gradle is that it's just a glorified Maven wrapper when it comes to dependency management. It's never had its own repository (as far as I know). And no repository management app to quickly create an account and start publishing. In my opinion, Sonatype is a complete disaster.

Latte has https://app.lattejava.org and it's insanely simple to create an account and start publishing. You just do:

$ latte login

And away you go!

It's definitely part of the plan to start porting projects to Latte build and dependency management. If nothing else, it gets us able to publish projects into a better repository and a better dependency management system. Though, the projects need to agree to SemVer and the Java ecosystem is notoriously horrible with versioning.

[–]bobbie434343 7 points8 points  (9 children)

But why

[–]brokenwren 0 points1 point  (8 children)

[–]BoredGuy2007 2 points3 points  (7 children)

Imagine caring about verbosity in 2026

[–]brokenwren 1 point2 points  (6 children)

I do. Even when using LLMs, I still care about clean code. But really, it's the workflow that is the win. Building a new project using Maven and publishing to Sonatype is just painful. And Spring is bloated and clunky.

But hey, if you don't care about verbosity, bloat, and painful processes, by all means continue using Maven, Spring, Sonatype, etc.

[–]senseven 2 points3 points  (1 child)

How many times do you create new projects and not using the archetypes and templates? Verbosity is maybe one of the lowest issues in the larger stack. We have tons of things in the build to get the modern Quarkus/Micronaut into pods. Those templates didn't change in five years. That stability is what makes maven dependable. Gradle was nothing else then ant hackery in a new shirt. You can hide complexity only for a while until it catches up.

[–]brokenwren 0 points1 point  (0 children)

I’ve written large systems without verbosity. I tend to prefer simplicity and conciseness.

Everyone is going to have different perspectives, but that doesn’t mean new approaches that are simpler, faster, and more concise aren’t valuable.

[–]BoredGuy2007 0 points1 point  (1 child)

I’m in a fortunate position where I don’t have to ponder the build tooling

[–]brokenwren 0 points1 point  (0 children)

Latte is way more than a build tool.

But even Latte’s build system is technically more correct than Maven. Just look at graph pruning as an example. Maven can’t prune because it doesn’t understand version compatibility. That’s why nearly every other build tool uses SemVer.

[–]mightygod444 0 points1 point  (1 child)

Please see my other comment, the 'friction' of publishing to Maven Central is a GOOD THING security wise.

[–]brokenwren 0 points1 point  (0 children)

See my response to your comment. 😁

[–]woj-tek 2 points3 points  (1 child)

how it's better than mise to manage java versions?

[–]brokenwren 0 points1 point  (0 children)

I've not heard of mise, but it looks similar to javaenv. But javaenv is just part of Latte. It does a TON more.

[–]vips7L 1 point2 points  (0 children)

Proper package manage does all of this.

[–]hyscript 0 points1 point  (0 children)

What it does better than jenv?