Skip to content

Commit 423ede0

Browse files
authored
fix: optimize code and update risky deps (#2918)
1 parent 2432603 commit 423ede0

File tree

12 files changed

+73
-216
lines changed

12 files changed

+73
-216
lines changed

hugegraph-server/hugegraph-core/pom.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<jraft.version>1.3.11</jraft.version>
3333
<ohc.version>0.7.4</ohc.version>
3434
<jna.version>5.12.1</jna.version>
35-
<lz4.version>1.8.0</lz4.version>
35+
<lz4.version>1.8.1</lz4.version>
3636
<mmseg4j-core.version>1.10.0</mmseg4j-core.version>
3737
<jcseg.version>2.6.2</jcseg.version>
3838
<hanlp.version>portable-1.8.3</hanlp.version>
@@ -197,6 +197,8 @@
197197
<artifactId>commons-compress</artifactId>
198198
<version>${commons-compress.version}</version>
199199
</dependency>
200+
<!-- LZ4 version update from 1.8.0 to 1.8.1. For details on the specific changes, please refer to:
201+
https://sites.google.com/sonatype.com/vulnerabilities/cve-2025-12183 -->
200202
<dependency>
201203
<groupId>org.lz4</groupId>
202204
<artifactId>lz4-java</artifactId>

hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/StandardAuthManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,7 @@ public HugeUser matchUser(String name, String password) {
580580
}
581581

582582
if (StringEncoding.checkPassword(password, user.password())) {
583+
// TODO: rehash password if bcrypt work factor is lower than expected
583584
this.pwdCache.update(user.id(), password);
584585
return user;
585586
}

hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/StandardAuthManagerV2.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,7 @@ public HugeUser matchUser(String name, String password) {
947947
}
948948

949949
if (StringEncoding.checkPassword(password, user.password())) {
950+
// TODO: rehash password if bcrypt work factor is lower than expected
950951
this.pwdCache.update(user.id(), password);
951952
return user;
952953
}

hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/CompressUtil.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,26 @@ public static void decompressTar(String sourceFile, String outputDir,
160160

161161
private static Path zipSlipProtect(ArchiveEntry entry, Path targetDir)
162162
throws IOException {
163-
Path targetDirResolved = targetDir.resolve(entry.getName());
163+
return zipSlipProtect(entry.getName(), targetDir);
164+
}
165+
166+
private static Path zipSlipProtect(ZipEntry entry, Path targetDir)
167+
throws IOException {
168+
return zipSlipProtect(entry.getName(), targetDir);
169+
}
170+
171+
private static Path zipSlipProtect(String entryName, Path targetDir)
172+
throws IOException {
173+
174+
Path targetDirResolved = targetDir.resolve(entryName);
175+
164176
/*
165177
* Make sure normalized file still has targetDir as its prefix,
166178
* else throws exception
167179
*/
168180
Path normalizePath = targetDirResolved.normalize();
169181
if (!normalizePath.startsWith(targetDir.normalize())) {
170-
throw new IOException(String.format("Bad entry: %s",
171-
entry.getName()));
182+
throw new IOException(String.format("Bad entry: %s", entryName));
172183
}
173184
return normalizePath;
174185
}
@@ -220,9 +231,8 @@ public static void decompressZip(String sourceFile, String outputDir,
220231
ZipInputStream zis = new ZipInputStream(bis)) {
221232
ZipEntry entry;
222233
while ((entry = zis.getNextEntry()) != null) {
223-
String fileName = entry.getName();
224-
File entryFile = new File(Paths.get(outputDir, fileName)
225-
.toString());
234+
Path entryPath = zipSlipProtect(entry, Paths.get(outputDir));
235+
File entryFile = new File(entryPath.toString());
226236
FileUtils.forceMkdir(entryFile.getParentFile());
227237
try (FileOutputStream fos = new FileOutputStream(entryFile);
228238
BufferedOutputStream bos = new BufferedOutputStream(fos)) {

hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/StringEncoding.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public final class StringEncoding {
3636
private static final byte[] BYTES_EMPTY = new byte[0];
3737
private static final String STRING_EMPTY = "";
3838
private static final int BLOCK_SIZE = 4096;
39+
private static final int BCRYPT_WORK_FACTOR = 10;
3940

4041
static {
4142
final String ALG = "SHA-256";
@@ -140,7 +141,9 @@ public static String decompress(byte[] value, float bufferRatio) {
140141
}
141142

142143
public static String hashPassword(String password) {
143-
return BCrypt.hashpw(password, BCrypt.gensalt(4));
144+
// OWASP suggests 10 as a minimum and 12–14 for production;
145+
// workFactor 12 is not used by default due to its 200+ ms cost.
146+
return BCrypt.hashpw(password, BCrypt.gensalt(BCRYPT_WORK_FACTOR));
144147
}
145148

146149
public static boolean checkPassword(String candidatePassword, String dbPassword) {

hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/StringEncodingTest.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.hugegraph.util.Bytes;
2424
import org.apache.hugegraph.util.StringEncoding;
2525
import org.junit.Test;
26+
import org.mindrot.jbcrypt.BCrypt;
2627

2728
public class StringEncodingTest {
2829

@@ -180,4 +181,41 @@ public void testReadAsciiString() {
180181
buf = Bytes.fromHex("80");
181182
Assert.assertEquals("", StringEncoding.readAsciiString(buf, 0));
182183
}
184+
185+
@Test
186+
public void testCheckPasswordSupportsOldAndNewCost() {
187+
String testPassword = "test123!@#";
188+
189+
// Test old work factor (4)
190+
String oldPassword = BCrypt.hashpw(testPassword, BCrypt.gensalt(4));
191+
Assert.assertTrue(StringEncoding.checkPassword(testPassword, oldPassword));
192+
Assert.assertFalse(StringEncoding.checkPassword("wrong", oldPassword));
193+
194+
// Test new work factor (10)
195+
String newPassword = BCrypt.hashpw(testPassword, BCrypt.gensalt(10));
196+
Assert.assertTrue(StringEncoding.checkPassword(testPassword, newPassword));
197+
Assert.assertFalse(StringEncoding.checkPassword("wrong", newPassword));
198+
199+
// Test that hashPassword uses the new cost factor
200+
String hashedPassword = StringEncoding.hashPassword(testPassword);
201+
Assert.assertTrue("Hash should contain work factor 10",
202+
hashedPassword.matches("^\\$2[aby]\\$10\\$.*")
203+
);
204+
205+
// Compare computational cost between work factor 4 and 10
206+
long start4 = System.nanoTime();
207+
StringEncoding.checkPassword(testPassword, oldPassword);
208+
long elapsed4 = System.nanoTime() - start4;
209+
210+
long start10 = System.nanoTime();
211+
StringEncoding.checkPassword(testPassword, hashedPassword);
212+
long elapsed10 = System.nanoTime() - start10;
213+
214+
// BCrypt cost difference: (10-4) = 6 => theoretical ~2^6 = 64x
215+
Assert.assertTrue(
216+
"Work factor 10 should be significantly slower than work factor 4 " +
217+
"(expected exponential cost increase)",
218+
elapsed10 >= elapsed4 * 32
219+
);
220+
}
183221
}

hugegraph-struct/pom.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,12 @@
108108
<artifactId>fastutil</artifactId>
109109
<version>8.1.0</version>
110110
</dependency>
111+
<!-- LZ4 version update from 1.7.1 to 1.8.1. For details on the specific changes, please refer to:
112+
https://sites.google.com/sonatype.com/vulnerabilities/cve-2025-12183 -->
111113
<dependency>
112114
<groupId>org.lz4</groupId>
113115
<artifactId>lz4-java</artifactId>
114-
<version>1.7.1</version>
116+
<version>1.8.1</version>
115117
</dependency>
116118
<dependency>
117119
<groupId>org.apache.commons</groupId>

hugegraph-struct/src/main/java/org/apache/hugegraph/util/StringEncoding.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ public final class StringEncoding {
5656
private static final byte[] BYTES_EMPTY = new byte[0];
5757
private static final int BLOCK_SIZE = 4096;
5858

59+
private static final int BCRYPT_WORK_FACTOR = 10;
60+
5961
static {
6062
final String ALG = "SHA-256";
6163
try {
@@ -165,7 +167,9 @@ public static String decompress(byte[] value, float bufferRatio) {
165167
}
166168

167169
public static String hashPassword(String password) {
168-
return BCrypt.hashpw(password, BCrypt.gensalt(4));
170+
// OWASP suggests 10 as a minimum and 12–14 for production;
171+
// workFactor 12 is not used by default due to its 200+ ms cost.
172+
return BCrypt.hashpw(password, BCrypt.gensalt(BCRYPT_WORK_FACTOR));
169173
}
170174

171175
public static boolean checkPassword(String candidatePassword,

install-dist/release-docs/LICENSE

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -649,8 +649,7 @@ The text of each license is also included in licenses/LICENSE-[project].txt.
649649
https://central.sonatype.com/artifact/org.lionsoul/jcseg-core/2.2.0 -> Apache 2.0
650650
https://central.sonatype.com/artifact/org.lionsoul/jcseg-core/2.6.2 -> Apache 2.0
651651
https://central.sonatype.com/artifact/org.lz4/lz4-java/1.4.0 -> Apache 2.0
652-
https://central.sonatype.com/artifact/org.lz4/lz4-java/1.7.1 -> Apache 2.0
653-
https://central.sonatype.com/artifact/org.lz4/lz4-java/1.8.0 -> Apache 2.0
652+
https://central.sonatype.com/artifact/org.lz4/lz4-java/1.8.1 -> Apache 2.0
654653
https://central.sonatype.com/artifact/org.nlpcn/nlp-lang/1.7.7 -> Apache 2.0
655654
https://central.sonatype.com/artifact/org.objenesis/objenesis/2.6 -> Apache 2.0
656655
https://central.sonatype.com/artifact/org.objenesis/objenesis/3.2 -> Apache 2.0

install-dist/release-docs/licenses/LICENSE-lz4-java-1.8.0.txt

Lines changed: 0 additions & 202 deletions
This file was deleted.

0 commit comments

Comments
 (0)