keygen-sh / keygen-api

Keygen is a fair source software licensing and distribution API built with Ruby on Rails. For developers, by developers.
https://keygen.sh
Other
699 stars 40 forks source link

How to prevent replay attacks? #836

Closed Halecoder closed 1 month ago

Halecoder commented 1 month ago

First of all thanks for your open source examples, I borrowed the code from the two libraries below and tested it in the electron project

  1. https://github.com/keygen-sh/example-node-response-signature-verification
  2. https://github.com/keygen-sh/example-electron-license-activation

I used the response signature, when I activated the product with the license, I got the header and content of the response through the packet capture, then I suspended the license in KeyGen Cloud, opened the packet capture tool, re-validated the request, and it passed

Nel: {"report_to":"heroku-nel","max_age":3600,"success_fraction":0.005,"failure_fraction":0.05,"response_headers":["Via"]}
Connection: close
Cache-Control: no-store
Content-Security-Policy: default-src 'none'; report-uri /-/csp-reports; report-to csp-reports;
Content-Type: application/json; charset=utf-8
Date: Sat, 04 May 2024 15:41:08 GMT
Digest: sha-256=8Faaa/FohjQwc36rk2wHyodhIv6G1EQhEONZ0g3mkQY=
Keygen-Account: a470355c-c6fe-4635-b58d-****
Keygen-Bearer: 
Keygen-Date: Sat, 04 May 2024 15:41:08 GMT
Keygen-Digest: sha-256=8Faaa/FohjQwc36rk2wHyodhIv6G1EQhEONZ0g3mkQY=
Keygen-Edition: EE
Keygen-Environment: 
Keygen-License: id="645993cd-e5f4-40e4-8a43-b35cefd04a8d", iss="2023-03-15 20:03:03 UTC", exp=""
Keygen-Mode: multiplayer
Keygen-Revision: 27bebe8aa84bd298eeb8d7017dd43248de3f282d
Keygen-Signature: keyid="a470355c-c6fe-4635-b58d-0d341583d651", algorithm="ed25519", signature="vJwH0ZKk+vuJGJG3HOEmkNX16ZV2ui1UWQnkUG/8UYE9ZDecKPGGND6t1tWCT888Sh9XCRabHhH5+3XGzDd9Cg==", headers="(request-target) host date digest"
Keygen-Token: 
Keygen-Version: 1.5
Referrer-Policy: strict-origin-when-cross-origin
Report-To: { "group": "csp-reports", "max_age": 10886400, "endpoints": [{ "url": "https://api.keygen.sh/-/csp-reports" }] }
Strict-Transport-Security: max-age=63072000; includeSubDomains
Vary: Origin
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: none
X-Powered-By: Ruby, Rails, and a lot of coffee. (And the occasional Islay.)
X-Ratelimit-Count: 1
X-Ratelimit-Limit: 60
X-Ratelimit-Remaining: 59
X-Ratelimit-Reset: 1714837290
X-Ratelimit-Window: 30s
X-Request-Id: 2d7b71a1-f61f-4da7-baa3-3fbfef12361f
X-Xss-Protection: 0
Via: 1.1 vegur
Content-Length: 2456

I also read the documentation, keygen is an excellent product, it also mentions the description of replay attacks, and I saw a sentence:

 If the signature is valid, but the response date is older than 5 minutes, we recommend rejecting the response (granted the local time is synchronized using NTP).

so how do I prevent replay attacks next? how to verify the time problem (including preventing the client from modifying the time by itself), or does the keygen server have relevant functions?

ezekg commented 1 month ago

Please do not use GitHub issues for support or questions. We have a forum, a Discord, and email for support. GitHub should only be used for issues and feature requests.

Regardless, after verifying the signature of the response, which includes verifying the integrity of the Date header (i.e. it can't be changed without invalidating the signature), you can assert the Date header is within e.g. 5 minutes from the current system time, otherwise reject it as too old. This is something you'll need to do within your own application code. It isn't something we can do for you as an API provider.

As for clock tampering, we have a few tips on that here. Without full control of the system, it's not possible to fully prevent clock tampering 100%.