从 curl 调用 GraphQL 端点意外失败

Invoking GraphQL endpoints from curl failing unexpectedly

多年来我一直在使用 REST APIs(作为消费者和开发者)并且我才刚刚开始第一次使用 GraphQL API,特别是, BurpSuite's Enterprise GraphQL API。我喜欢它,但我确实遗漏了一些关键概念。

我正试图达到他们的 GetScan 端点:

curl -k -i -H "Content-Type: application/json" -H "Authorization: <MY_API_KEY>" -X GET -d '{ "query": "query GetScan ($id: ID!) { scan(id: $id) { id status agent { id name } site_application_logins { login_credentials { label username } recorded_logins { label } } audit_items { id issue_counts { total } number_of_requests } scan_configurations { id name } } }"}' 'https://mybsee.example.com/graphql/v1'

为了便于阅读,该 graphql 查询也是:

query GetScan ($id: ID!) {
  scan(id: $id) {
    id status
    agent { id name }
    site_application_logins {
      login_credentials { label username }
      recorded_logins { label }
    }
    audit_items {
      id
      issue_counts { total }
      number_of_requests
    }
    scan_configurations { id name }
  }
},
variables {
    $agent: "Firefox"
}
当我 运行 时,

以上 <MY_API_KEY> 具有实际价值(显然,我不能在此处 post )。与 URL 相同(我有一个预置版本的 BurpSuite 运行 关闭,比方说,mybsee.example.com)。

当我 运行 卷曲时,我得到以下输出:

About to execute: query GetScan ($id: ID!) { scan(id: $id) { id status agent { id name } site_application_logins { login_credentials { label username } recorded_logins { label } } audit_items { id issue_counts { total } number_of_requests } scan_configurations { id name } } }
HTTP/2 200 
date: Wed, 20 Oct 2021 23:33:50 GMT
x-frame-options: DENY
<lots of response headers omitted>

{"errors":[{"message":"Unexpected exception occurred. Check logs for more details.","extensions":{"code":77}}]}

我无权访问服务器日志,因此我试图排除客户端的问题(我对 GetScan 的错误调用)。任何人看起来有什么不对吗?我是否应该向查询中的任何字段注入值,例如 idstatus 等?如果是这样,我如何(具体地)更改查询以使其有效?我也不确定是否需要将 "query" JSON 字段名称附加到实际查询中。

感谢您提供的所有帮助。

更新

我确实意识到这不是一个 完全 可回答的问题,因为 BurpSuite API 很不幸是专有的,您无法从中获得 API 密钥他们除非您购买产品或通过大量的 rigamarole 获得免费试用许可证。

但更重要的是,我不是在这里找人给我钓鱼,我希望有人能教我如何钓鱼。事实上,除了这个之外,我还需要集成更多的 GraphQL 端点,但如果有人能告诉我构建一个查询的正确方法,我可以从那里获取它。

curl -k -i -H "Content-Type: application/json" -H "Authorization: Bearer <API_TOKEN>" -X POST -d "{ \"query\": \"$string\"}" '<API_URL>'

你几乎做对了所有事情。只需将 HTTP 方法更改为 POST 而不是 GET。 GET 将尝试获取整个页面,另一方面 POST 将与 GraphQL API.

交互

尽管如此,在 GraphQL serving over HTTP page 中声明 GET 方法也应在某些限制下处理查询。请参阅链接以获取更多信息。

同时考虑访问其他使我做出此决定的网页;
Introduction to GraphQL on GitHub
Making GraphQL Requests using HTTP Methods
Burp Suite Enterprise GraphQL forum discussion with the same Error code of yours

最安全的方法是使用 jq 为您的查询及其参数生成正确转义的 JSON。

构建一个函数来自动化:

# usage: gqlQuery http://ENDPOINT/graphql "$query" arg1=val1 arg2=val2 ...
gqlQuery() {
  local endpoint query postBody
  local -a jqArgs=( )
  endpoint=; shift || return
  query=; shift || return
  while (( $# )); do
    case  in

      # the variable name "query" is used for passing in, well, the query
      query=*)  echo "ERROR: variable name query is reserved" >&2; return 1;;

      # 'foo=JSON:["bar", "baz"]' passes ["bar", "baz"] as a list, not a string
      *=JSON:*) jqArgs+=( --argjson "${1%%=*}" "${1#*=}" ) ;;

      # without JSON:, everything gets passed as a string to the child
      *=*)      jqArgs+=( --arg "${1%%=*}" "${1#*=}" ) ;;

      # arguments without a = are not recognized
      *)        echo "ERROR: Argument  not well-formed" >&2; return 1;;
    esac
    shift
  done
  postBody=$(jq -nc \
    --arg query "$query" \
    "${jqArgs[@]}" \
    '{ "query": $query, "variables": ($ARGS.named | del(.query)) }'
  ) || return
  curl --fail -XPOST \
    -H 'Content-Type: application/json' \
    -d "$postBody" "$endpoint"
}

...您可以使用这样的函数:

getScanQuery='query GetScan ($id: ID!) { scan(id: $id) { id status agent { id name } site_application_logins { login_credentials { label username } recorded_logins { label } } audit_items { id issue_counts { total } number_of_requests } scan_configurations { id name } } }'
myUrl=https://mybsee.example.com/graphql/v1
scanIdToRetrieve=1000 # replace with whatever is appropriate

result=$(gqlQuery "$myUrl" "$getScanQuery" id="$scanIdToRetrieve")