At a minimum, this should be password protected by default.
One of the security lessons from the late 1990s and early 2000s is that things like this quickly get hacked. Many developers forget that a service where all security is handled client-side are easy targets for hacking.
Furthermore: In a lot of cases, people will ship prototypes and run their stuff on top of them long after they have outgrown a critical component.
I have tried to write a universal backend... It's possible, but you really have to work in a permissions model from the beginning. What you'll find is that basic read/write/own enables very basic functionality. Unfortunately, to do anything complicated, you will need to write server-side queries that verify that the user is allowed to do what they are trying to do.
And JWT's don't solve authentication which was the actual problem people were looking to solve. For a prototyping server authn==authz is more than fine.
> And JWT's don't solve authentication which was the actual problem people were looking to solve. For a prototyping server authn==authz is more than fine.
Re-read the OP
> Unfortunately, to do anything complicated, you will need to write server-side queries that verify that the user is allowed to do what they are trying to do.
this is authorization, not authentication. Your assertion is false at first place.
Your comment makes no sense by the way. You'd have the exact same issue with another authorization scheme, the credentials need to come from somewhere.
There no such thing as "prototyping servers" in the wild. Only blatantly unsecure open source servers.
A very basic REST service for JSON data - enough for prototyping and MVPs!
Features:
no need to set up a database, all data is managed automagically*
REST paradigm CRUD for multiple entities/namespaces
schema validation
search using jq like syntax
CORS enabled
easy to deploy as container
But for other strings built with sprintf, yes I am saying don't use %v unless for debugging, it's just one more avenue where you might be surprised by input, even if you're not building strings for sql. For example, someone might do this with user supplied data:
myoutput := fmt.Sprintf("user:%v",userID)
and if userID is a string like "foo" it'll end up in their string and they won't get what they expect. So better to just put another guardrail on there and insist that the param is an integer or whatever you expect by using %d which will only accept an int - this means you have to convert it to an integer first.
Many vulnerabilities are caused by data not being in the format people expect (not just sqli).
It should sanitize / quote arguments for you and protect against SQL injection. Note that this doesn't mean all data sanitization is performed, just the basic '; do my stuff here; -- type of things.
Using the db Exec / Query / Query row is the same amount of code and effort the fmt.Sprintf statements. Even in quick-and-dirty mock-ups, it's a good idea to not cut corners there.
There's nothing as permanent as a temporary solution. There's been countless SQL injection vulnerabilities exploited over the past decades with the "I'll fix it later" mindset.
Start with prepared statements by default, they are not more work than formatting strings.
> You're right of course, but I think the idea of this software is that the user (and, by extension, their input) are trusted.
No, you should enforce the most basic security practices even if the users are "trusted". Somebody might put that on the internet for a demo for client and get hacked in no time, because the code is opened to SQL injection. This isn't acceptable. There are minimum security standards every project should follow.
And since none of the minimum security standards are implemented in that project, I would not recommend using it until they are.
>>Now that it's been posted to HN you might see malicious actors.
This needs to be an HN fN Masterclass by @Dang....
We should have regular visibility into /how/ HN is used by malicious actors.... HN has enough pedigree to get some insight from some of the top security folks... and it would be REALLY good to know how HN is being harvested in this space.
currently there are two implementation for the database "behind": in memory or with postgres, both with zero config (except for starting an instance of postgres, in the second case!).
it can be easily extended to use files as persistence, good idea :)
regarding the pre-population, you can just make a quick script with curl that will add some data after you run the service. any thought?
FYI, there is a name clash with Caffeine, a Mac OS menu bar app that keeps the screen awake: https://intelliscapesolutions.com/apps/caffeine . But I guess this is expected with a name like this, and the scopes of the projects are clearly different, so this should be relatively harmless.
Hah! I'm not sure my MVP has ever had error handling beyond "Something went wrong.". That's something for a real production app, not the minimum possible product.
I realize this is just for prototyping but it looks like it just spits sprintf SQL strings into the database.
While not a security risk if done locally, why not just use a where string builder to generate the $ values and a variadic as the input? It's about the same amount of work.
I could have used something similar recently, but that persisted to disk as json. I ended up just storing a wad of JSON on disk and memory, loading and saving as needed. Will only ever be 1M or so and only 2 users.
Shameless plug: along the same lines, but for rapid web UI prototyping cases where you don't want to waste time with setting up a server, I built a tiny tool called REM[0] a few years ago.
It never actually stores data on the server (it echos it into a cookie instead), so the dataset is only ever visible to you, no auth or service keys required.
We tried to do this back in 2016 with BrightWork. We got a lot of traction, but it came on the heels of Parse being shutdown by Facebook after acquiring them for a ton of money.
The lesson I learned from that experience is that there is still a tremendous amount of distrust in platforms that make it easy to stand up something quickly. Even prototyping.
Even if you make it easy for users to export their code from your platform you will still run into scalability questions (i.e. what happens if someone builds the next Flappy Bird on your platform?).
All that aside, this is great! Congrats on launching Caffeine. :)
Correct. The json data type is less performant and stores the data more or less as lightly indexed text. jsonb optimizes the storage format and allows for more JSON operations, such as extracting individual keys.
For this product, if the super-generic API doesn't offer/require a need to do complex operations, though, json may be adequate to lookup items by id and present them.
This is bizarre. I spent a good 5+ min looking over the README and documentation site, and couldn’t find out what that project is other than “a backend that runs on Nodejs.” Yeah ok but what is it? Why am I interested? I’m not looking to be sold, just for it to tell me what it’s for. I have some assumptions based on how I got linked there, but this is surprising to me.
In a nutshell a place for your web page or mobile app to store and retrieve data. There is some auth, business logic / security stuff but not as much as you get in an MVC web app. Let’s you build apps where a lot of the work happens on the front end and the back end is basically a place to save to disk.
Parse was a startup but they shut down and open sourced their code.
Cool project!
Personally I've been using apiary or Snowboard for Backend prototyping since they allow for a design first approach and typically end up with quite good Dokumentation and Testing infrastructure. But having a real interactive back end like caffeine provides is also very intriguing!
This awesome! Our product supports json as a backend in a very simple way in order to feed data to HTML templates (https://www.stack55.com) and I was thinking of doing something very similar to what you have done.
You know, naming is one of the two really hard problems in CS. But there is apparently a hack which is to open dictionary on random page and point your finger on random word.
My next application is going to be called Toreutics which is going to break this word for every person that actually uses it.
Kinda like breaking the word Meta. Which I suppose is actually aimed at making things difficult to search for.
This is useful. But you can achieve the same results in just a few more steps with Hasura or Supabase and end up with something that is close to production ready.
Yeah, I would probably go hasura if I needed this, but I can see the appeal of something that is a single component you can self host and self understand. Hasura is rock solid, but I will never read through it‘s haskell source or understand how it constructs those extra-clever postgres queries.
If I read it right, you don‘t need to configure any schema to use this? You can just POST a user and it will create that type? If it‘s true, that‘s a real step above hasura/supabase for rapid prototyping.
I wish devs would stop naming EVERYTHING after common english words; it makes stuff 10 times harder to troubleshoot unless you already rank high on the search results.
I guess HN would be the best place to bring this up in a psa topic but I doubt it'll have any long-term influence...
One of the security lessons from the late 1990s and early 2000s is that things like this quickly get hacked. Many developers forget that a service where all security is handled client-side are easy targets for hacking.
Furthermore: In a lot of cases, people will ship prototypes and run their stuff on top of them long after they have outgrown a critical component.
I have tried to write a universal backend... It's possible, but you really have to work in a permissions model from the beginning. What you'll find is that basic read/write/own enables very basic functionality. Unfortunately, to do anything complicated, you will need to write server-side queries that verify that the user is allowed to do what they are trying to do.