Closed KevinWang15 closed 1 month ago
This could be a viable fix:
Subject: [PATCH] feat: use JWT for downloadhash
---
Index: app/Repositories/TorrentRepository.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/app/Repositories/TorrentRepository.php b/app/Repositories/TorrentRepository.php
--- a/app/Repositories/TorrentRepository.php (revision 8bcbf407edcb4d5d3a1efa8bb7482297aa61721e)
+++ b/app/Repositories/TorrentRepository.php (revision 0ea18fd247db3122f6ae1825ba047b6a868c320c)
@@ -36,6 +36,8 @@
use Nexus\Database\NexusDB;
use Nexus\Imdb\Imdb;
use Rhilip\Bencode\Bencode;
+use Firebase\JWT\JWT;
+use Firebase\JWT\Key;
class TorrentRepository extends BaseRepository
{
@@ -334,13 +336,22 @@
public function encryptDownHash($id, $user): string
{
$key = $this->getEncryptDownHashKey($user);
- return (new Hashids($key))->encode($id);
+ $payload = [
+ 'id' => $id,
+ 'exp' => time() + 3600
+ ];
+ return JWT::encode($payload, $key, 'HS256');
}
public function decryptDownHash($downHash, $user)
{
$key = $this->getEncryptDownHashKey($user);
- return (new Hashids($key))->decode($downHash);
+ try {
+ $decoded = JWT::decode($downHash, new Key($key, 'HS256'));
+ return [$decoded->id];
+ } catch (\Exception $e) {
+ throw new \InvalidArgumentException("Invalid down hash: " . $e->getMessage());
+ }
}
private function getEncryptDownHashKey($user)
Thanks for your help.
I discovered a severe security vulnerability that allows attackers to steal passkeys from any user. This issue is caused by the "downhash" being too short and easily guessable, due to the implementation of the hashids project.
Attack Details
The attack exploits the vulnerability in the download URL structure:
The
[short_hash]
part is extremely short (1-3 characters) and can be brute-forced quickly. Once a valid combination is found, the attacker can extract the user's passkey from the response.Proof of Concept
I've created a simple Node.js script that demonstrates this attack. It systematically tries all possible combinations for the
[short_hash]
part until it finds a valid one. Once successful, it can then be used to extract the user's passkey.The script was able to find a valid combination in seconds:
Using this URL, I was able to extract a user's passkey:
Impact
This vulnerability has severe consequences:
uidToAttack = 1
means the root admin).Recommended Fix
Discontinue the use of hashids for this security-critical task. Hashids is not designed for cryptographic security and should not be used for protecting sensitive information.
Implement a secure digital signature method instead. Some recommended approaches include:
Ensure the new method produces signatures that are sufficiently long (at least 32 bytes) to prevent brute-force attacks.