当起点和终点都不存在时新插入无数条边的攻击

nebula 版本:nebula-graph-2.0.0.el7.x86_64.rpm

  • 部署方式(分布式 / 单机 / Docker / DBaaS):分布式 三节点
  • 是否为线上版本:N
  • 硬件信息
    • 磁盘( 推荐使用 SSD):SSD
    • CPU、内存信息 每台64核,512G(和其他应用公用,可用磁盘空间约1T)
  • 问题的具体描述
  • 相关的 meta / storage / graph info 日志信息

基于我现在的认识,想到一种攻击方式,在知道nebula数据库用户密码之后,然后向数据库中插入无数条不存在的点的边。这样数据库只能看到边的数量在无限增加,但是查询不到,而且无法删除。。最后数据库就无法使用了。

1赞

insert插入了数据,肯定能查到的,怎么会查不到啊。。。。:joy:

大神,该怎么查询呢??我是了几次都不行啊

如果知道边的起点或者终点的话,使用fetch。
如果不知道的话,可以创建index,然后rebuild index,然后使用match或者lookup

大神,您可以动手试试吗?
很简单,就用你们basketballplayer空间,现在假设我是攻击方,然后我在你的图空间里写入了下面的数据,你是防守方。
第一种期情况。需要在不影响生产环境的情况下,把这10条数据找到并删除。前提是您得假装不知道这些数据的内容,只知道数据多了10条。
第二种情况,需要在不影响生产环境的情况下,把这10条数据找到并删除。前提是您已经知道这些数据的内容,现在要删除他们。

该怎么做呢,麻烦您写一下查询语句。

INSERT EDGE follow(degree) VALUES "xplayer10" -> "xplayer20:(95);
INSERT EDGE follow(degree) VALUES "xplayer11" -> "xplayer21":(95);
INSERT EDGE follow(degree) VALUES "xplayer12" -> "xplayer22":(95);
INSERT EDGE follow(degree) VALUES "xplayer13" -> "xplayer23":(95);
INSERT EDGE follow(degree) VALUES "xplayer14" -> "xplayer24":(95);
INSERT EDGE follow(degree) VALUES "xplayer15" -> "xplayer25":(95);
INSERT EDGE follow(degree) VALUES "xplayer16" -> "xplayer26":(95);
INSERT EDGE follow(degree) VALUES "xplayer17" -> "xplayer27":(95);
INSERT EDGE follow(degree) VALUES "xplayer18" -> "xplayer28":(95);
INSERT EDGE follow(degree) VALUES "xplayer19" -> "xplayer29":(95);

@pandasheeps 您找到办法没有呢?如何通过查询语句来解决这个问题呢?

没有试,delete肯定没有问题的

//创建图空间
CREATE SPACE flinkSource2(partition_num=15, replica_factor=1, vid_type=fixed_string(30))
 CREATE TAG `player` ( `name` string NULL, `age` int64 NULL ) ;
 CREATE EDGE `friend` ( `degree` string NULL, `start` string NULL, `src` string NULL, `dst` string NULL ) 


//新增点
 INSERT VERTEX player(name,age) VALUES "18": ("Tom",20);
INSERT VERTEX player(name,age) VALUES "22": ("Crea",10);
INSERT VERTEX player(name,age) VALUES "20": ("Jime",32);
INSERT VERTEX player(name,age) VALUES "15": ("Bob",18);
INSERT VERTEX player(name,age) VALUES "17": ("Jena",20);
INSERT VERTEX player(name,age) VALUES "21": ("Jhon",76);
INSERT VERTEX player(name,age) VALUES "19": ("Viki",55);
INSERT VERTEX player(name,age) VALUES "16": ("Tina",19);

//新增边
INSERT EDGE friend(src,dst,degree,start) VALUES "Jime"->"John"@19: ("Jime","John","20.0","2017-04-01");
INSERT EDGE friend(src,dst,degree,start) VALUES "Bob"->"Lisa"@17: ("Bob","Lisa","20.0","2015-04-01");
INSERT EDGE friend(src,dst,degree,start) VALUES "Tim"->"Bob"@20: ("Tim","Bob","20.0","2020-04-01");
INSERT EDGE friend(src,dst,degree,start) VALUES "Tom"->"Lisa"@18: ("Tom","Lisa","20.0","2016-04-01");
INSERT EDGE friend(src,dst,degree,start) VALUES "nicole"->"Tom"@15: ("nicole","Tom","18.0","2019-05-01");
INSERT EDGE friend(src,dst,degree,start) VALUES "Tina"->"John"@16: ("Tina","John","19.0","2018-03-08");

//查看数据情况
(root@nebula) [flinkSource2]> show stats
+---------+------------+-------+
| Type    | Name       | Count |
+---------+------------+-------+
| "Tag"   | "player"   | 8     |
+---------+------------+-------+
| "Edge"  | "friend"   | 6     |
+---------+------------+-------+
| "Space" | "vertices" | 8     |
+---------+------------+-------+
| "Space" | "edges"    | 6     |
+---------+------------+-------+
Got 4 rows (time spent 785/1114 us)

//测试删除边  DELETE EDGE serve "player100" -> "team200"@0;

> delete EDGE friend  "Jime"->"John"@19
(root@nebula) [flinkSource2]> delete EDGE friend  "Jime"->"John"@19
Execution succeeded (time spent 1085/1484 us)

Thu, 10 Jun 2021 10:15:35 CST

(root@nebula) [flinkSource2]> submit job stats
+------------+
| New Job Id |
+------------+
| 1459       |
+------------+
Got 1 rows (time spent 2649/2968 us)

Thu, 10 Jun 2021 10:15:47 CST

(root@nebula) [flinkSource2]> show stats
+---------+------------+-------+
| Type    | Name       | Count |
+---------+------------+-------+
| "Tag"   | "player"   | 8     |
+---------+------------+-------+
| "Edge"  | "friend"   | 5     |
+---------+------------+-------+
| "Space" | "vertices" | 8     |
+---------+------------+-------+
| "Space" | "edges"    | 5     |
+---------+------------+-------+
Got 4 rows (time spent 776/1116 us)

Thu, 10 Jun 2021 10:15:50 CST

(root@nebula) [flinkSource2]> 


 重新试了一下。当知道边的数据时,是可以删除的。但是如何知道边的数据呢?

@pandasheeps
可能很简单。但是假设我生产环境数据就是这样,也没有datetime字段,但是必须要把这些脏数据找出来该怎么做呢。文档我至少看了三遍。也没有看到这种情况的描述

1赞

很简单啊,tag或者edge表增加一个datetime字段,插入的时候,插入datetime() 的结果。
然后建index,查看datetime字段值来找出数据,然后删除不就行了

通过storageClient 可以遍历所有的点和边。可以查询到点不存在的边。但是查询语句目前还不知道改如写。

/* Copyright (c) 2020 vesoft inc. All rights reserved.
 *
 * This source code is licensed under Apache 2.0 License,
 * attached with Common Clause Condition 1.0, found in the LICENSES directory.
 */

package com.vesoft.nebula.examples;

import com.vesoft.nebula.client.storage.StorageClient;
import com.vesoft.nebula.client.storage.data.EdgeTableRow;
import com.vesoft.nebula.client.storage.data.VertexRow;
import com.vesoft.nebula.client.storage.data.VertexTableRow;
import com.vesoft.nebula.client.storage.scan.ScanEdgeResult;
import com.vesoft.nebula.client.storage.scan.ScanEdgeResultIterator;
import com.vesoft.nebula.client.storage.scan.ScanVertexResult;
import com.vesoft.nebula.client.storage.scan.ScanVertexResultIterator;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class StorageClientExample {
    private static final Logger LOGGER = LoggerFactory.getLogger(StorageClientExample.class);

    public static void main(String[] args) {
        // input params are the metad's ip and port
        StorageClient client = new StorageClient("127.0.0.1", 9559);
        try {
            client.connect();
        } catch (Exception e) {
            LOGGER.error("storage client connect error, ", e);
            System.exit(1);
        }
        scanVertex(client);
        scanEdge(client);
    }

    /**
     * Vertex Person's property in Nebula Graph:
     * first_name, last_name, gender, birthday
     * Tom          Li        男       2010
     */
    public static void scanVertex(StorageClient client) {
        ScanVertexResultIterator iterator = client.scanVertex(
                "test",
                "person",
                Arrays.asList("name", "age"));

        while (iterator.hasNext()) {
            ScanVertexResult result = null;
            try {
                result = iterator.next();
            } catch (Exception e) {
                LOGGER.error("scan error, ", e);
                System.exit(1);
            }
            if (result.isEmpty()) {
                continue;
            }
            System.out.println(result.getPropNames());
            List<VertexRow> vertexRows = result.getVertices();
            for (VertexRow row : vertexRows) {
                if (result.getVertex(row.getVid()) != null) {
                    System.out.println("vid : " + result.getVertex(row.getVid()));
                }
            }
            System.out.println(result.getVidVertices());


            System.out.println("result vertex table view:");
            List<VertexTableRow> vertexTableRows = result.getVertexTableRows();
            for (VertexTableRow vertex : vertexTableRows) {
                try {
                    System.out.println("_vid: " + vertex.getVid().asString());
                    System.out.println(vertex.getValues());
                } catch (UnsupportedEncodingException e) {
                    LOGGER.error("decode String error, ", e);
                }
            }
            System.out.println(result.getVertices());
        }
    }

    /**
     * Edge Friend's property in Nebula Graph:
     * degree
     * 1.0
     */
    public static void scanEdge(StorageClient client) {
        ScanEdgeResultIterator iterator = client.scanEdge(
                "test",
                "like",
                Arrays.asList("likeness"));

        while (iterator.hasNext()) {
            ScanEdgeResult result = null;
            try {
                result = iterator.next();
            } catch (Exception e) {
                LOGGER.error("scan error, ", e);
                System.exit(1);
            }
            if (result.isEmpty()) {
                continue;
            }
            System.out.println(result.getPropNames());
            System.out.println(result.getEdges());

            System.out.println("result edge table view:");
            List<EdgeTableRow> edgeTableRows = result.getEdgeTableRows();
            for (EdgeTableRow edge : edgeTableRows) {
                try {
                    System.out.println("_src:" + edge.getSrcId().asString());
                    System.out.println("_dst:" + edge.getDstId().asString());
                } catch (UnsupportedEncodingException e) {
                    LOGGER.error("decode String error, ", e);
                }
                System.out.println("_rank:" + edge.getRank());
                System.out.println(edge.getValues());
            }
        }
    }
}

如何查询,点不存在的边?我的猜想是这样的,nebula在新增边的时候,没有验证边的点是否存在。建立边或者点的索引的时候也没有验证边的点是否存在?那么有没有工具去验证,或者找出点不存在的边的数据呢?大家可以参考下面的连接就可以造出上述问题的数据。

1赞

浙ICP备20010487号