OpenCTI-Platform / opencti

Open Cyber Threat Intelligence Platform
https://opencti.io
Other
6.5k stars 956 forks source link

Issue with StackHawk/Hawk Scan CLI 4.1.0/4.2.0 Authenticated GraphQL Introspection #8613

Open gritty-Kitty opened 1 month ago

gritty-Kitty commented 1 month ago

Prerequisites

Description

Can GraphQL Introspection be enabled without having to be authenticated? https://docs.opencti.io/5.8.X/deployment/configuration/ See app:graphql:playground:force_disabled_introspection.

What does, "Introspection is allowed to auth users but can be disabled in needed" mean in Deployment Configuration details page?

Appears to imply that authentication can be disabled for GraphQL Introspection.

Can authentication be disabled for performing StackHawk Dynamic Application Security Threat (DAST) scans against /graphql?

We have attempted various authentication methods against our master account credentials and token, but all fail. Hoping to disable authentication requirement to complete DAST scan and then disable GraphQL Introspection.

Thank you.

Further... https://github.com/OpenCTI-Platform/opencti/issues/8322

Environment

  1. OS (where OpenCTI server runs): { e.g. Mac OS 10, Windows 10, Ubuntu 16.4, etc. } Ubuntu 22.04 LTS Docker 26.1.4 Portainer 2.21.2

  2. OpenCTI version: { e.g. OpenCTI 1.0.2 } v6.1.12

  3. OpenCTI client: { e.g. frontend or python }

StackHawk HawkScan CLI 4.1.0

  1. Other environment details:

Reproducible Steps

Steps to create the smallest reproducible scenario:

  1. { e.g. Run ... }
  2. { e.g. Click ... }
  3. { e.g. Error ... }

Additional information

richard-julien commented 1 month ago

There is no available option to open introspection to unauthenticated user for now. Thats need to be added in the code. Honestly its a bit strange to be forced to do that, StackHawk is not able to execute call with a bearer?

gritty-Kitty commented 1 month ago

Attempted to use the token assigned to the global admin account, but was receiving Server 500 messages. I will provision a new account in OpenCTI for StackHawk and revisit the configuration.

Thank you for confirming and your Team's dedication. Appreciated.

richard-julien commented 1 month ago

Its possible to use the admin token through bearer authentication. (classic authorization header with "bearer \<token>")

gritty-Kitty commented 1 month ago

(removed previous comment with failing StackHawk authentication yaml after testing)

We are able to use Postman 11.14 Lightweight API Client with the GraphQL Request Type and the Bearer Token of the OpenCTI Global Administrator to pull information from OpenCTI.

Therefore, our StackHawk configuration needs to be adjusted to provide a Bearer Token for authentication to perform GraphGL Introspection.

Will attempt to correct stackhawk.yml and post final success here for reference.

Thank you for the hint towards using a Bearer Token!

gritty-Kitty commented 1 month ago

Partial Success.

HawkScan (StackHawk) CLI v4.1.0 and v4.2.0 work with the following stackhawk.yml against Hawk CLI. Update { } values as required. Posted here for posterity.

# stackhawk.yml
app:
  applicationId: {StackHawk Application Project GUID} # (required)
  env: Production # (required)
  host: https://openctix.mydomain.com # (required)
  autoPolicy: true
  autoInputVectors: true
  graphqlConf: 
    enabled: true
    schemaPath: /graphql # OR...
#    filePath: introspectionSchema.json
    operation: ALL # Types: ALL, QUERY, MUTATION
    requestMethod: POST # Types: POST, GET
  authentication:
    external:
      values:
        - type: TOKEN
          tokenType: Bearer
          value:
            name: Authorization
            val: {OpenCTI Token from Global Account}
    loggedInIndicator: "HTTP.*2[0-9][0-9]\\s*O[kK](\\s*)|HTTP.*3[0-9][0-9].*"
    loggedOutIndicator: ".*AUTH_REQUIRED.*"
    testPath:
      type: BODY
      path: /graphql
      success: ".*6.1.12.*" # OpenCTI Version for GraphQL Test Query
      requestMethod: POST
      requestBody: '{"query": "query About { about { version }}"}'
      requestHeaders: 
        Accept-Encoding: "application/json"
        Content-Type: "application/json"

Unfortunately, Stackhawk is not able to properly parse the json produced by the GraphQL Introspection routine. They have reviewed the JSON Schema and they believe it is an error in the parsing of the schema and not a problem with the scanner, and suggested to try commenting out offending sections of the schema and/or post a message to the OpenCTI forum for further feedback.

Used Postman to pull the introspectionSchema.json. Running HawkScan directly against /graphql or pointing to the "adjusted" introspectionSchema.json based on the instructions in the URL below have the same error results below.

https://help.stackhawk.com/en/articles/6487322-how-to-generate-a-graphql-schema-file-for-use-by-hawkscan

GraphQL Configuration Error: invalid schema:
[filters!.filterGroups!] forms an unsatisfiable cycle

The only reference I could find in the introspectionSchema.json for "filterGroups" was on line 671.

image

gritty-Kitty commented 1 month ago

This was the query posted to Postman to create the introspectionSchema.json. Query was formatted into a JSON blob in the body of POST to /graphql after authenticating with the authorization bearer token of the OpenCTI Global Administrator.

query IntrospectionQuery {
  __schema {
    queryType {
      name
    }
    mutationType {
      name
    }
    subscriptionType {
      name
    }
    types {
      ...FullType
    }
    directives {
      name
      description
      args {
        ...InputValue
      }
    }
  }
}
fragment FullType on __Type {
  kind
  name
  description
  fields(includeDeprecated: true) {
    name
    description
    args {
      ...InputValue
    }
    type {
      ...TypeRef
    }
    isDeprecated
    deprecationReason
  }
  inputFields {
    ...InputValue
  }
  interfaces {
    ...TypeRef
  }
  enumValues(includeDeprecated: true) {
    name
    description
    isDeprecated
    deprecationReason
  }
  possibleTypes {
    ...TypeRef
  }
}
fragment InputValue on __InputValue {
  name
  description
  type {
    ...TypeRef
  }
  defaultValue
}
fragment TypeRef on __Type {
  kind
  name
  ofType {
    kind
    name
    ofType {
      kind
      name
      ofType {
        kind
        name
        ofType {
          kind
          name
          ofType {
            kind
            name
            ofType {
              kind
              name
              ofType {
                kind
                name
              }
            }
          }
        }
      }
    }
  }
}

Reformatted as JSON...

{"query":"query IntrospectionQuery { __schema { queryType { name } mutationType { name } subscriptionType { name } types { ...FullType } directives { name description args { ...InputValue } } } } fragment FullType on __Type { kind name description fields(includeDeprecated: true) { name description args { ...InputValue } type { ...TypeRef } isDeprecated deprecationReason } inputFields { ...InputValue } interfaces { ...TypeRef } enumValues(includeDeprecated: true) { name description isDeprecated deprecationReason } possibleTypes { ...TypeRef } } fragment InputValue on __InputValue { name description type { ...TypeRef } defaultValue } fragment TypeRef on __Type { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name } } } } } } } } "}