Команды оболочки, сгенерированные jq, не работают правильно - PullRequest
0 голосов
/ 21 марта 2020

Я пытаюсь выполнить команду postgres в сценарии bash, но я не знаю, почему она не работает.

Проблема в том, что мне нужно прочитать данные из JSON файл. Для этого я использую библиотеку jq и создаю предложение, но psql выдает только ошибки.

file. json

{
  "databases": [
    "db1",
    "db2"
  ],
  "logins": [
    {
      "username": "user1",
      "password": "pwd1"
    },
    {
      "username": "user2",
      "password": "pwd2"
    }
  ],
  "rights": [
    {
      "username": "user1",
      "database": "db1",
      "grant": "ALL PRIVILEGES"
    },
    {
      "username": "user2",
      "database": "db2",
      "grant": "ALL PRIVILEGES"
    }
  ]
}

init. sh

# rights

mapfile -t arr < <(jq -M -r '.rights[] | "psql -d 'template1' -U 'postgres' -c GRANT \"" +  .grant + "\" ON DATABASE \"" + .database + "\" TO \"" + .username + "\";"' $CONFIG_PATH)

for a in "${arr[@]}"; $a; done

ошибка

psql: warning: extra command-line argument ""ALL" ignored
psql: warning: extra command-line argument "PRIVILEGES"" ignored
psql: warning: extra command-line argument "ON" ignored
psql: warning: extra command-line argument "DATABASE" ignored
psql: warning: extra command-line argument ""db1"" ignored
psql: warning: extra command-line argument "TO" ignored
psql: warning: extra command-line argument ""user1";" ignored
ERROR:  syntax error at end of input
LINE 1: GRANT
             ^

Я пробовал это по-разному, но все они терпят неудачу: (

Кто-нибудь знает, как это сделать? Большое спасибо!

1 Ответ

3 голосов
/ 21 марта 2020

Исходный код имел серьезные уязвимости безопасности. Как указано ниже, мы уязвимы только для инъекции SQL, больше не для инъекции оболочки; и больше не пытаетесь запустить data как код в оболочке:

sql=$(jq -r '
  .rights[] |
  "GRANT \"\(.grant)\" ON DATABASE \"\(.database)\" TO \"\(.username)\";"' \
  <"$config_path"
)
psql -d template1 -U postgres -c "$sql"

Если вы действительно хотите использовать jq для генерации команд оболочки, вы может сделать это, но для этого нужно использовать примитив jq @sh; и затем для анализа результата как кода, а не данных требуется eval:

eval "$(jq -r '
  .rights[] |
  [ "psql", "-d", "template1", "-U", "postgres",
    "-c", "GRANT \"\(.grant)\" ON DATABASE \"\(.database)\" TO \"\(.username)\";"
  ] | @sh' \
  <"$config_path"
)"
...