Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/check-dependencies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
dependency-check:
runs-on: ubuntu-latest
env:
USE_STAGE: 'false' # Whether to include the stage repository.
USE_STAGE: 'true' # Whether to include the stage repository.
SCRIPT_DEPENDENCY: hugegraph-server/hugegraph-dist/scripts/dependency
steps:
- name: Checkout source
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
# TODO: we need test & replace it to ubuntu-24.04 or ubuntu-latest
runs-on: ubuntu-20.04
env:
USE_STAGE: 'false' # Whether to include the stage repository.
USE_STAGE: 'true' # Whether to include the stage repository.
TRAVIS_DIR: hugegraph-server/hugegraph-dist/src/assembly/travis
REPORT_DIR: target/site/jacoco
BACKEND: ${{ matrix.BACKEND }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:
jobs:
analyze:
env:
USE_STAGE: 'false' # Whether to include the stage repository.
USE_STAGE: 'true' # Whether to include the stage repository.
name: Analyze
runs-on: ubuntu-latest
permissions:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/licence-checker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
check-license:
runs-on: ubuntu-latest
env:
USE_STAGE: 'false' # Whether to include the stage repository.
USE_STAGE: 'true' # Whether to include the stage repository.
steps:
- uses: actions/checkout@v4

Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ achieved through [Gremlin](https://tinkerpop.apache.org/gremlin.html)(a powerful

We can use `docker run -itd --name=graph -p 8080:8080 hugegraph/hugegraph` to quickly start an inner
HugeGraph server with `RocksDB` (in backgrounds) for **test/dev**.
You can visit [doc page](https://hugegraph.apache.org/docs/quickstart/hugegraph-server/#3-deploy) or the [README](hugegraph-server/hugegraph-dist/docker/READEME.md) for more details.
You can visit [doc page](https://hugegraph.apache.org/docs/quickstart/hugegraph-server/#3-deploy) or
the [README](hugegraph-server/hugegraph-dist/docker/READEME.md) for more details. ([Docker Compose](./hugegraph-server/hugegraph-dist/docker/example))

> Note:
>
Expand All @@ -58,12 +59,11 @@ The project [doc page](https://hugegraph.apache.org/docs/) contains more informa
and provides detailed documentation for users. (Structure / Usage / API / Configs...)

And here are links of other **HugeGraph** component/repositories:
1. [hugegraph-toolchain](https://github.com/apache/incubator-hugegraph-toolchain) (graph tools **[loader](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-loader)/[dashboard](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-hubble)/[tool](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-tools)/[client](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-client)**)
2. [hugegraph-computer](https://github.com/apache/incubator-hugegraph-computer) (integrated **graph computing** system)
3. [hugegraph-commons](https://github.com/apache/incubator-hugegraph-commons) (**common & rpc** libs)
4. [hugegraph-website](https://github.com/apache/incubator-hugegraph-doc) (**doc & website** code)


1. [hugegraph-toolchain](https://github.com/apache/hugegraph-toolchain) (graph tools **[loader](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-loader)/[dashboard](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-hubble)/[tool](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-tools)/[client](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-client)**)
2. [hugegraph-computer](https://github.com/apache/hugegraph-computer) (integrated **graph computing** system)
3. [hugegraph-commons](https://github.com/apache/hugegraph-commons) (**common & rpc** libs)
4. [hugegraph-website](https://github.com/apache/hugegraph-doc) (**doc & website** code)
5. [hugegraph-ai](https://github.com/apache/incubator-hugegraph-ai) (integrated **Graph AI/LLM/KG** system)

## License

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ public String login(@Context GraphManager manager, @PathParam("graph") String gr
@Status(Status.OK)
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON_WITH_CHARSET)
public void logout(@Context GraphManager manager,
@PathParam("graph") String graph,
public void logout(@Context GraphManager manager, @PathParam("graph") String graph,
@HeaderParam(HttpHeaders.AUTHORIZATION) String auth) {
E.checkArgument(StringUtils.isNotEmpty(auth),
"Request header Authorization must not be null");
Expand All @@ -105,10 +104,8 @@ public void logout(@Context GraphManager manager,
@Status(Status.OK)
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON_WITH_CHARSET)
public String verifyToken(@Context GraphManager manager,
@PathParam("graph") String graph,
@HeaderParam(HttpHeaders.AUTHORIZATION)
String token) {
public String verifyToken(@Context GraphManager manager, @PathParam("graph") String graph,
@HeaderParam(HttpHeaders.AUTHORIZATION) String token) {
E.checkArgument(StringUtils.isNotEmpty(token),
"Request header Authorization must not be null");
LOG.debug("Graph [{}] get user: {}", graph, token);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,7 @@ private boolean matchPermission(String required) {

if (LOG.isDebugEnabled()) {
LOG.debug("Verify permission {} {} for user '{}' with role {}",
requiredPerm.action().string(),
requiredPerm.resourceObject(),
requiredPerm.action().string(), requiredPerm.resourceObject(),
this.user.username(), this.user.role());
}

Expand All @@ -269,9 +268,8 @@ private boolean matchPermission(String required) {

if (!valid && LOG.isInfoEnabled() &&
!required.equals(HugeAuthenticator.USER_ADMIN)) {
LOG.info("User '{}' is denied to {} {}",
this.user.username(), requiredPerm.action().string(),
requiredPerm.resourceObject());
LOG.info("User '{}' is denied to {} {}", this.user.username(),
requiredPerm.action().string(), requiredPerm.resourceObject());
}
return valid;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@
public class GremlinQueryAPI extends API {

private static final Set<String> FORBIDDEN_REQUEST_EXCEPTIONS =
ImmutableSet.of("java.lang.SecurityException",
"jakarta.ws.rs.ForbiddenException");
ImmutableSet.of("java.lang.SecurityException", "jakarta.ws.rs.ForbiddenException");
private static final Set<String> BAD_REQUEST_EXCEPTIONS = ImmutableSet.of(
"java.lang.IllegalArgumentException",
"java.util.concurrent.TimeoutException",
Expand All @@ -56,6 +55,7 @@ public GremlinClient client() {
if (this.client != null) {
return this.client;
}

HugeConfig config = this.configProvider.get();
String url = config.get(ServerOptions.GREMLIN_SERVER_URL);
int timeout = config.get(ServerOptions.GREMLIN_SERVER_TIMEOUT) * 1000;
Expand Down Expand Up @@ -100,6 +100,7 @@ private static boolean matchBadRequestException(String exClass) {
if (exClass == null) {
return false;
}

if (BAD_REQUEST_EXCEPTIONS.contains(exClass)) {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,16 @@
import org.apache.hugegraph.traversal.optimize.HugeCountStepStrategy;
import org.apache.hugegraph.traversal.optimize.HugeGraphStepStrategy;
import org.apache.hugegraph.traversal.optimize.HugeVertexStepStrategy;
import org.apache.hugegraph.util.Log;
import org.apache.hugegraph.util.Reflection;
import org.apache.hugegraph.variables.HugeVariables;
import org.slf4j.Logger;

import com.google.common.collect.ImmutableSet;

public final class HugeFactoryAuthProxy {

private static final Logger LOG = Log.logger(HugeFactoryAuthProxy.class);
public static final String GRAPH_FACTORY =
"gremlin.graph=org.apache.hugegraph.auth.HugeFactoryAuthProxy";

Expand All @@ -90,7 +93,11 @@ public static synchronized HugeGraph open(Configuration config) {
return proxy;
}

// TODO: add some test to ensure the effect & partially move to HugeSecurityManager
private static void registerPrivateActions() {
// Sensitive classes (Be careful to add classes here due to JDK compatibility)
filterCriticalSystemClasses();

// Thread
Reflection.registerFieldsToFilter(java.lang.Thread.class, "name", "priority", "threadQ",
"eetop", "single_step", "daemon", "stillborn", "target",
Expand All @@ -106,7 +113,7 @@ private static void registerPrivateActions() {
"threadLocalRandomSecondarySeed");
Reflection.registerMethodsToFilter(java.lang.Thread.class, "exit",
"dispatchUncaughtException", "clone", "isInterrupted",
"registerNatives", "init", "init", "nextThreadNum",
"registerNatives", "init", "nextThreadNum",
"nextThreadID", "blockedOn", "start0", "isCCLOverridden",
"auditSubclass", "dumpThreads", "getThreads",
"processQueue", "setPriority0", "stop0", "suspend0",
Expand Down Expand Up @@ -477,6 +484,26 @@ private static void registerPrivateActions() {
//genRegisterPrivateActions();
}

public static void filterCriticalSystemClasses() {
// TODO: merge them in HugeSecurityManager after 1.5.0
Reflection.registerMethodsToFilter(Class.class, "forName", "newInstance");
Reflection.registerMethodsToFilter(ClassLoader.class, "loadClass", "newInstance");
Reflection.registerMethodsToFilter(Method.class, "invoke", "setAccessible");
Reflection.registerMethodsToFilter(Field.class, "set", "setAccessible");
Reflection.registerMethodsToFilter(java.lang.reflect.Constructor.class, "newInstance",
"setAccessible");
Reflection.registerMethodsToFilter(Runtime.class, "exec", "getRuntime");
Reflection.registerMethodsToFilter(ProcessBuilder.class, "command", "start",
"startPipeline");
Reflection.registerMethodsToFilter(loadClass("java.lang.ProcessImpl"), "forkAndExec",
"setAccessible", "start");

optionalMethodsToFilter("sun.invoke.util.BytecodeDescriptor", "parseMethod", "parseSig");
optionalMethodsToFilter("sun.reflect.misc.MethodUtil", "invoke");
optionalMethodsToFilter("jdk.internal.reflect.MethodAccessor", "invoke");
optionalMethodsToFilter("jdk.internal.reflect.NativeMethodAccessorImpl", "invoke");
}

@SuppressWarnings("unused")
private static void genRegisterPrivateActions() {
registerPrivateActions(Thread.class);
Expand Down Expand Up @@ -562,20 +589,18 @@ private static void registerPrivateActions(Class<?> clazz) {
}
}

private static boolean registerClass(Class<?> clazz,
List<String> fields,
List<String> methods) {
if (clazz.getName().startsWith("java") ||
fields.isEmpty() && methods.isEmpty()) {
return false;
private static void registerClass(Class<?> clazz, List<String> fields, List<String> methods) {
if (clazz.getName().startsWith("java") || fields.isEmpty() && methods.isEmpty()) {
return;
}

final String[] array = new String[fields.size()];
try {
Reflection.registerFieldsToFilter(clazz, fields.toArray(array));
Reflection.registerMethodsToFilter(clazz, methods.toArray(array));
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Filter already registered: class")) {
return false;
return;
}
throw e;
}
Expand All @@ -596,8 +621,6 @@ private static boolean registerClass(Class<?> clazz,
System.out.println(code);
// CHECKSTYLE:ON
}

return true;
}

private static Class<?> loadClass(String clazz) {
Expand All @@ -607,4 +630,17 @@ private static Class<?> loadClass(String clazz) {
throw new HugeException(e.getMessage(), e);
}
}

public static void optionalMethodsToFilter(String className, String... methodNames) {
Class<?> clazz = null;
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
// TODO: we just ignore the exception, change it after we drop Java8 support
LOG.warn("Skip register class {} to filter", className);
}
if (clazz != null) {
Reflection.registerMethodsToFilter(clazz, methodNames);
}
}
}
Loading