84 comments

[ 4.1 ms ] story [ 158 ms ] thread
0.0.0.0 qeys.io
Or a CSP header server side. But still something the average client will miss, at least at first, and trip the alert.
> But still something the average client will miss, at least at first, and trip the alert

That's totally it, thanks for pointing that out!

That won't really work for the scenario they try to "protect" against.

When you copy some js files that include their license checking code to your server and them serve it to your clients, your clients need to block qeys.io, not you.

You can instruct clients to do that of course, but it's rather easy for one of them to forget and the copyright holder is noticed.

Still, blocking qeys.io by default on your system sounds like a good idea :)

if it's for internal use, you most likely have access to the DNS-server the clients are using, not an unlikely scenario when it comes to licensed code like this i would imagine.
You will still get caught because google will crawl your site which in turn will make a request to qeys.io and then I will get a notification with something along the lines of "Customer jlebrech is using an unlicensed version of your software on unlicensed-domain.com". The purpose of this software is to report the copyright infringement of the host, not the user.
I didn't think of this, you could still steal something that's designed for an intranet (those may cost thousands)
I am so confused.

> Besides, we strongly recommend to let our JavaScript file blend in with the rest of your application's JavaScript. Webpack, compress and uglify the best you can, to make the code responsible for validation as difficult as possible to find and break.

Ok, so this is a solution to detect (some of) the sites that use your JavaScript code without approval, not a solution to prevent them from doing it (since it can be easily blocked once you know to look for it).

I guess all you can do is blackball customers that stole your code and later need you to fix something later on.
Exactly. By detecting and letting you know what happened, you'll be able to take action. You know who you built the application for and will most likely still have their phone number which you can use to ask them what's going on.
Seems it would be as effective as cd key protection or DVD protection - meaning anyone doing the copying likely won't be affected and attempts to tighten the grip will probably hurt legitimate customers.
You're totally right. However, in the few cases that my software was copied, the pirates were far from skilled enough to dig into compiled JS and find out what was happening. At least, they would start with a simple copy-paste and try to run the copy. If it were to happen again now, I would be notified at that very moment and I can take action accordingly.
Similar to how cd key protection originally was limited to skilled crackers but as things like SecureRom became normal so did tools that automatically removed the protection from software.
I suspect what is more common is a legitimate company just making their life easy to create multiple instances and not pay the correct licence fees. They want convenience. If they want to modify the source code and hack around, then it's probably not going to solve that.
From the FAQ section:

> the thief

> the code they just stole

Uh. I know this is extremely widespread to call it so, but copyright infringement isn't "theft" or "stealing".

Well spotted, thanks. Changed it to pirate.
Perfect. Bookmarked and will get back to you when I'll purchase a boat. Would be a nasty surprise to the buccaneers.
Maybe instead of snark you can recommend what you actually believe to be valid?
I really thought that "piracy" comment was a tongue-in-cheek joke (so I had laughed and played along). I'm sorry if I had offended someone.

As for what it is - I believe I clearly wrote that it's called copyright infringement (or license violation, or unlicensed use, or unauthorized copying if you want different wording). And a person is violator, perpetrator, unauthorized user or something like that (I'm neither a lawyer, nor a native speaker, I bet one would be able to come with lots of correct terms)

Also, check this out: https://www.gnu.org/philosophy/words-to-avoid.en.html#Piracy and https://torrentfreak.com/mpaa-banned-from-using-piracy-and-t...

This is nice, but I would never put a piece of code on my property that breaks the user experience (after a few seconds) when a third party service is offline. It's even worse because it causes a highly correlated failure vector across all my products. Imagine your servers going down (for whatever reason) and _all_ my customers calling me because their websites are broken.

Additionally, defaulting to shutting down the app when it can't reach your servers breaks all sorts of offline features an app may have.

I would strongly suggest to default to doing nothing when the script can't contact your servers. Alternatively you let me configure an HTTP endpoint that will be pinged when it can't reach you so at least I am aware the service is disrupted.

Hi Ruphin, Frits from Qeys here. I highly appreciate your comment and I totally agree with what you're saying. Not being able to reach our servers should not break your app.

The small piece of code is designed to only invalidate and deny access when a valid response is returned from our servers.

That means that if our service is unreachable you won't be notified about invalid use, of course, but the app assumes the positive and allows everyone access until a valid "denied" response.

Did you experience the contrary, or was this simply not clear from what you read? In that case, I'll try and add that to the FAQ section.

Does this mean that they can access the site for free by blocking qeys.io?
From above, it would sound like it O.o
That solution might sound absurd, but what's the alternative? I implemented my own basic license validation server for an application I wrote, and I ended up doing the exact same thing.

My server may go down every now and then, I don't want to deny access to the application just because my 5$/month server is too busy at the moment..

Yes, it does. Qeys is not designed to deny user access to protected sections of an application, though.

The ideal use case is a web app (e.g. awesome dashboard) you built and is ran on premise on one of your clients' servers. Their dayjob isn't pirating software, so blocking qeys.io probably has not been on their to do list.

But yes, if qeys.io is blocked, no validation takes place.

They would have to instruct all their users to start blocking qeys.io. Looks like this isn't designed to be foolproof, but to deter most from cheating.
I don't think the primary purpose of qeys.io is to block users of the webapp. The purpose of qeys.io is to block customers (not users) from hosting the webapp without your permission.
Here's what I read from the FAQ:

In a very bad scenario where our service is slow, the worst thing that happens is a user being able to use the web app for a couple of seconds before it is denied access.

I understand now that you mean in case the website is an unauthorized copy the end user will be able to use it for a few seconds before it is disabled.

In that case I retract my previous comments, but I would suggest changing the wording in the FAQ here to be more clear. :)

Reminds me of a scenario which leads to "needless" abstractions being created in a project so the absolute on/off dependency on a third party becomes it's own micro-service that the rest of your app calls with an `if (server.isOnline) {do_stuff();}` which leads to massive confusion for developers later wondering if there was really a need for such abstraction or is a mid-level dev was engaged in resume-driven development...

Issues like what you've described -- whether real or perceived -- are the root cause of many code smells.

Boy, do I hate it when I encounter stuff like that. I always try to explain to people that being "online" is not a boolean flag: at most you know that your last request to your crappy heartbeat service have failed. That's it.

You can display a small hint on the UI ("It seems that there's a problem with your connection"), but only an idiot would block users from interacting with the app on grounds of "being offline".

Are you familiar with the video game industry? This tactic occurs frequently.
Minor typo on your front-page "deativate" rather than "deactivate".
Thanks, fixed it!
Also, lincences

  "Unlimited number of lincences"
"* Unlimited number of lincences"

Also, your privacy policy makes no mention of what data is included with validation requests, and what you do with that information. GDPR is still very fresh, and if my app is passing every URL data to a third party, that sounds like it could be a problem.

Thanks, fixed the typo.

I'll include a section in the privacy policy on what's sent in the request, which is just the application UUID and the licence key. Our service then uses the origin of the request to determine the domain.

> I'll include a section in the privacy policy on what's sent in the request, which is just the application UUID and the licence key.

And the complete URL of the originating page, as the parent commenter mentioned.

I just noticed this text in the FAQ:

> Whenever we receive a validation request and grant access, we create a fingerprint of the page from which the validation was requested. Then, when we deny access to a page which did not provide a (valid) application uuid, we try to match the fingerprint of that page with one of the ones we indexed. This means that in many cases, we will still be able to notify you about invalid use of your application.

Does this mean that your service is collecting not just URLs, but page contents as well?

What's even better is to have a backend that side a payload to the client when events are triggered, so no js is loaded in advance.
Was hoping they'd just have an api you could check against, maybe op could do that pretty easily since the frontend is already making a request.
Yes you can definitely do that. The /validate endpoint accepts the parameters application (for the application uuid) and the key (for licence key). You can program your way around that, but the one line solution then does not hold up.
I feel like i'm missing something obvious here. This is for "webapps" which have been "licensed". Who is running licensed webapps without some form of user account? Either a login or an API key, which can easily be turned off if the person stops paying. If i have that, why do i need this? If i don't have that, haven't i just totally fallen down on the job of controlling access to my system?

What am i missing here?

It's for on-premise deployments, where you don't have control over the deployment environment.
thanks @albertgoeswoof

"The small piece of code is designed to only invalidate and deny access when a valid response is returned from our servers." seems pretty easy to circumvent but... i guess you could make your app stop working if it fails to get a response within x days or whatever, but you'd have to use a compiled language to make that even remotely difficult to not circumvent too.

I think the primary purpose is the notifications, not the blocking. Even if they browse to the page once, see the block and disable it, you'll still know.
Their share meta tag is: <meta property="og:title" content="Start.ly — Agency One Page Parallax Template" />
Ouch. According to facebook debugger, this link has not yet been shared before, a good thing in this case. Fixed it, thanks.
So.. you copied someone's code? /s
Haha no definitely not, the landing page is bought legally from Themeforest ;)
> by the time the pirate realises that licence validation is in place, it's too late for them

> we strongly recommend to let our JavaScript file blend in with the rest of your application [..] to make the code responsible for validation as difficult as possible to find and break

This smells much more to security by obscurity than an actual licensing solution.

`[...]make the code responsible for validation as difficult as possible to find and break` ⌘+W

Seriously though, this seems like an convoluted way for small businesses to resolve trust issues with their clients.

I mean, if you really want to do this, why not make it incredibly simple and just ping a server with the domain names the web app is being requested from. Do it all silently and then let the IP owner decide what to do about it. Why shut the site down and risk embarrassing, and potential trust destroying, situations arise from false positives?

"Do it all silently and then let the IP owner decide what to do about it" sounds like a great idea and could be an application-specific setting. Added to my to-do list, thanks.
Why not just do `if(window.location.href !== 'http://our-site.com') { send_email(window.location.href + ' stole code'); }`?
I think this is for local deployments of web apps like a localhost site or Electron app. I could be wrong though.
would it be possible to steal a website's code, then tack on a service worker that intercepts requests to qeys?
Sure, but as other commenters have mentioned, if you were going to go to that trouble you could just remove the license check code.

I guess a service worker has the advantage of not having to dig through potentially obfuscated Javascript code. But it's not like that would be hard to do, given that Chrome's debugging tools record a stack trace for every XMLHttpRequest.

It would be nice to have some copy/pasteable snippets to integrate this with my stuff. It is unclear what I should do once I register an application and am presented with a list of keys.
Next to every key there is a button with a question mark "how to use", which presents a pop-up with a copy/pasteable snippet.
This breaks any existing js that sets window.onload if the qeys script is loaded after it. Usually it's better to do window.addEventListener('load', ...) so you don't overwrite anything.
From looking at the JavaScript snippet that is provided, it looks like I can get around the validation by simply creating a cookie who's contents is "validated=yes" before the qeys script is loaded.

EDIT: The part of the snippet in question:

    window.addEventListener('load', function(a){
        document.cookie.indexOf('validated=')<0&&v();
    });
I can confirm that this completely stops qeys from even sending a request on the page I'm testing it on.

However, any client side protection can be bypassed, especially if your adversary has write access to the code you're trying to protect.

Maybe as an additional protection, qeys should, say, 1 in 7 [0] times, send a request regardless of whether the cookie present.

[0] https://en.wikipedia.org/wiki/Morris_worm

You could indeed do that. I really like eat_veggies' suggestion, something I'll consider.
> The instant solution to worrying less about your web applications being copied by the clients you developed them for.

Is this a problem that happens often?

The problem of my clients actually copying my software: no. The problem of being worried about it: yes

On a serious note, it has happened to me a handful of times in many years. Not often, but enough times to want to be notified when it happens again.

This definitely seems like an interesting product, but if you're an anti-piracy company then maybe you shouldn't be using a pirated font. If you check the Product Sans CSS file you're including, you'll see there's a notice that the font is not open source.
Oh wow I had no idea. I simply bought the template from Themeforest, thinking everything would be in order. Anyway, the font has been changed, well spotted!
If you bought a template from Themeforest, you may have obtained a license for the font. If so, no need to change the font. If not, you'd be doing TF a kindness by letting them know.
It's Google's special brand font so I doubt they license it. However it is served from the same domain as Google Fonts so it's an easy mistake to make.
If you're looking for a replacement font for your tagline on the homepage, Montserrat isn't too different at the heavier weights. Nice to see Laravel Spark in the wild though.
Did you get the extended license?
Raise your prices.

I can't be alone in thinking that these prices are insanely low when considering the market. If you're selling to working programmers, $9.99 a month is a frivolity. I pay more than that for Netflix. For a business expense? Your $24.99 plan should be the entry point.

You should have a higher tier. A much higher tier, in fact, like $350. You're targeting agencies and studios at this point. It's still under the ~$500 that requires approval, but there are absolutely businesses out there that will just sign up for the highest tier they can process, because it's a status thing or "they may need it". You won't get many signups at this price, but even one will replace 35 signups at your current lowest tier. Heck, more, because higher-priced customers will churn less and require less support.

Consider dropping your free tier and just relying on your free trial. You're targeting businesses and working programmers. They have money, so a lack of money won't be the reason they choose not to use your product, only product/customer fit.

Thanks you for the interesting feedback. Pricing is something I find to be the most difficult part of offering a service. It surprised me that no-one else had mentioned anything about pricing so far, so I started to think that I found the "oh this looks reasonable" sweet spot. I'll see where everything is when this HN storm settles down and reconsider.
Totally agree on the higher tier, also because there are plenty of things you will value more just because it charges a higher price. For a freelancer or agency who needs this because they've been screwed over before, it might even make the service appear more trustworthy, that you're charging that much because you are offering security. A few hundred a year is nothing for a bit of peace of mind and some protection against a client skipping payment and running off with your code.

Anecdotally, a place I previously worked at raised all of its prices and tweaked the available plans (with some A/B testing involved) and internally it was incredibly controversial and made a lot of people unhappy as we were implementing it. When the testing period was over and all was said and done, few people complained about the price hikes and far more people either just accepted it or went for an upgrade.

I think it's very easy for a startup to completely underestimate the value it provides and assume that nobody would pay more if they had to. But maybe that's just a bias because you don't tend to hear about the companies that failed for charging too much. (Not that I would suggest you blindly follow this advice!)

Simply write free software (as in speech) ...
in my mind the only true way to protect against client software ripping is to put all of the protected IP on your service, and make service calls to it from the client application. If the code resides on their hardware... there aint really anything you can do to protect it.
<a href="www.mixxkart.com">Kirana in Gorakhpur</a>
Question: How about having the option of not blocking but only reporting?

Then you can put a use clause in your service agreement and bill your customers according to their use. They've signed that any additional use incurs a cost, but they don't think you know.

Definitely, monkeynotes had a similar suggestion so with your comment on top of that, this is definitely on my to do list.