feel invigorated by being on the bleeding edge. Consider us thrill
seekers.
it’s the reason you’re here. Perhaps you believe, like we do, that bugs
are best squashed before deploying to prod.
security testing tools do not work well with modern development
paradigms. We’ve built functionality to ensure that modern developers
can run security tests simply, including CI integrations, scanning REST
API backed applications, and more.
the black hole for GraphQL security testing.We just released GraphQL
scanning support to ensure that you can ship secure GraphQL APIs.
demo, let’s do a quick overview of the GraphQL specification. This is a
unique space with an interesting set of challenges.
posed by its current state of scan-ability, please feel free to skip
ahead to How it Works for a demo and walkthrough.
Do you even Graph(QL)?
you’ve probably seen GraphQL implementations in the wild. If your
business is inline with, or already one of the 3,026 star adopters reported in the GraphQL Landscape, then you’re probably already building and deploying a GraphQL API in production today.
broken implementations. Considering most of these apps are likely to
lack proper testing we suddenly have some serious concerns.
adjusted. This change presents a potential breeding ground for unchecked vulnerabilities on new and existing web apps.
So… it’s like, graphs and stuff, right?
trees and leaves in a directed, acyclical or cyclical fashion, etc, ad infinitum… recursively, and on and on.
outlined the capacity for engineers to represent data in pretty much any complex structure desired (or maybe not desired). Anything goes as long as the implementation is within the confines of the specification and
meets a few key criteria.
city on dark summer evenings and draw the blinds, turn down the lights,
and listen very carefully, you may just catch the sound of the faint grumblings emitted by backend engineers all over as they beg for mercy from the agony of rearchitecting their RESTful service into the promised land The Graph.
written essay about graph theory and the GraphQL API, but that would never be nearly as informative as what’s already available at GraphQL so let’s fast forward to what this all means for the security bottom-line.
Interest in Introspection
attacker no doubt, will employ in our endeavors to discover and audit
routes is one of introspection.
definitions of types, fields, custom types, primitives, directives,
subscriptions and other operations which we can query.
available routes throughout the app. It then proceeds to generate
queries which include fields and dependencies, expected input values,
and available parameters to use as variable arguments. We provide the
required input types, unwrapped custom types, scalars, enums, lists and
so on and insert test values wherever possible.
options such as making GET vs POST requests, setting recursion depth on
introspection, and setting control over the method of how queries are generated. The latter being configurable for either batch form compost of all fields and types, or individual requests with each field and required type sent one-by-one.
The Faces May Change, but Security Bugs Remain the Same
parameter in GraphQL. Remote code injections are possible here, as they have been from the beginning of web applications, and they aren’t going away any time soon.
applications.
How it Works: Walk through with a Sample App
git clone https://github.com/stackhawk/vuln-graphql-api.git
SERVER_PORT=3000
docker-compose up
HAWK_API_KEY
that links to your account. If this is missing, simply generate a new key in the Account UI and populate that file.app:
graphQL: true
graphQLConf: # Optional
schemaPath: /graphql
source ~/.hawk/hawk.rc
docker run -e API_KEY=${HAWK_API_KEY} --rm -v $(pwd):/hawk:rw -it stackhawk/hawkscan:latest
We can see in the output of our scan that we’ve found two high severity
bugs in this vulnerable GraphQL app. One for SQL Injection and another for Remote Code Execution.
you have StackHawk running tests on every PR, then you know these bugs
will never see the light of prod.
{"query":"mutation
superSecretPrivateMutation($command:String ) {
superSecretPrivateMutation(command:$command) { stdout stderr }
}","variables":{"command":"KaaaKaww!&cat /etc/passwd&"}}
{"data":{"superSecretPrivateMutation":{"stdout":"
root:x:0:0
:root:/root:/bin/bash\nbin:x:1:1:bin:/bin:/sbin/n
root:x:0:0
:root:/root:/bin/bash\nbin:x:1:1:bin:/bin:/sbin/nologin\ndaemon:x:2:2:daemon:/sbin:/sbin/nologin\nadm:x:3:4:adm:/var/adm:/sbin/nologin\nlp:x:4:7:lp:/var/spool/lpd:/sbin/nologin\nsync:x:5:0:sync:/sbin:/bin/sync\nshutdown:x:6:0:shutdown:/sbin:/sbin/shutdown\nhalt:x:7:0:halt:/sbin:/sbin/halt\nmail:x:8:12:mail:/var/spool/mail:/sbin/nologin\noperator:x:11:0:operator:/root:/sbin/nologin\ngames:x:12:100:games:/usr/games:/sbin/nologin\nftp:x:14:50:FTP
User:/var/ftp:/sbin/nologin\nnobody:x:65534:65534:Kernel Overflow
User:/:/sbin/nologin\ndbus:x:81:81:System message
bus:/:/sbin/nologin\nsystemd-coredump:x:999:997:systemd Core
Dumper:/:/sbin/nologin\nsystemd-resolve:x:193:193:systemd
Resolver:/:/sbin/nologin\napp:x:1000:1000::/home/app:/bin/bash\n","stderr":"/bin/sh:
KaaaKaww!: command not found\n"}}}