mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-21 03:45:26 +00:00
112 lines
3.2 KiB
Go
112 lines
3.2 KiB
Go
|
|
package dataformat
|
||
|
|
|
||
|
|
import (
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"github.com/stretchr/testify/require"
|
||
|
|
)
|
||
|
|
|
||
|
|
const (
|
||
|
|
graphqlQueryWithInlineArgs = `{
|
||
|
|
"query": "\n query {\n jobs(jobType: \"front-end\") {\n id\n name\n type\n description\n }\n }\n "
|
||
|
|
}`
|
||
|
|
|
||
|
|
graphqlQueryWithVariables = `{
|
||
|
|
"query": "mutation ImportPaste ($host: String!, $port: Int!, $path: String!, $scheme: String!) {\n importPaste(host: $host, port: $port, path: $path, scheme: $scheme) {\n result\n }\n }",
|
||
|
|
"variables": {
|
||
|
|
"host": "example.com",
|
||
|
|
"port": 80,
|
||
|
|
"path": "/robots.txt",
|
||
|
|
"scheme": "http"
|
||
|
|
}
|
||
|
|
}`
|
||
|
|
)
|
||
|
|
|
||
|
|
func Test_GraphQL_IsGraphQL(t *testing.T) {
|
||
|
|
graphql := NewGraphql()
|
||
|
|
require.True(
|
||
|
|
t,
|
||
|
|
graphql.IsType(graphqlQueryWithInlineArgs),
|
||
|
|
"expected query to be detected as graphql",
|
||
|
|
)
|
||
|
|
require.False(
|
||
|
|
t,
|
||
|
|
graphql.IsType("not a graphql query"),
|
||
|
|
"expected query to not be detected as graphql",
|
||
|
|
)
|
||
|
|
require.False(
|
||
|
|
t,
|
||
|
|
graphql.IsType(`{"query": "not a graphql query"}`),
|
||
|
|
"expected query to not be detected as graphql",
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
func Test_GraphQL_DecodeEncode_InlineArgs(t *testing.T) {
|
||
|
|
decodeQueryGetKV := func(query string) (KV, map[string]interface{}, *Graphql) {
|
||
|
|
graphql := NewGraphql()
|
||
|
|
|
||
|
|
decoded, err := graphql.Decode(query)
|
||
|
|
require.Nil(t, err, "could not decode graphql query")
|
||
|
|
|
||
|
|
keyValues := make(map[string]interface{})
|
||
|
|
decoded.Iterate(func(key string, value interface{}) bool {
|
||
|
|
if strings.HasPrefix(key, "#_") {
|
||
|
|
return true
|
||
|
|
}
|
||
|
|
keyValues[key] = value
|
||
|
|
return true
|
||
|
|
})
|
||
|
|
return decoded, keyValues, graphql
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test decoding and encoding
|
||
|
|
t.Run("inline args with variables", func(t *testing.T) {
|
||
|
|
decoded, keyValues, graphql := decodeQueryGetKV(graphqlQueryWithVariables)
|
||
|
|
require.Equal(t, map[string]interface{}{
|
||
|
|
"host": "example.com",
|
||
|
|
"port": float64(80),
|
||
|
|
"path": "/robots.txt",
|
||
|
|
"scheme": "http",
|
||
|
|
}, keyValues)
|
||
|
|
|
||
|
|
decoded.Set("path", "/robots.txt; cat /etc/passwd")
|
||
|
|
|
||
|
|
// Test encoding
|
||
|
|
encoded, err := graphql.Encode(decoded)
|
||
|
|
require.Nil(t, err, "could not encode graphql query")
|
||
|
|
|
||
|
|
_, newKeyValues, _ := decodeQueryGetKV(encoded)
|
||
|
|
require.Equal(t, "/robots.txt; cat /etc/passwd", newKeyValues["path"])
|
||
|
|
|
||
|
|
// Try to write non-string paths as well
|
||
|
|
t.Run("non-string paths", func(t *testing.T) {
|
||
|
|
decoded.Set("port", "80; cat /etc/passwd")
|
||
|
|
encoded, err = graphql.Encode(decoded)
|
||
|
|
require.Nil(t, err, "could not encode graphql query")
|
||
|
|
|
||
|
|
_, newKeyValues, _ = decodeQueryGetKV(encoded)
|
||
|
|
require.Equal(t, "80; cat /etc/passwd", newKeyValues["port"])
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("inline args", func(t *testing.T) {
|
||
|
|
decoded, keyValues, graphql := decodeQueryGetKV(graphqlQueryWithInlineArgs)
|
||
|
|
require.Equal(t, map[string]interface{}{
|
||
|
|
"jobType": "front-end",
|
||
|
|
}, keyValues)
|
||
|
|
|
||
|
|
decoded.Set("jobType", "canary")
|
||
|
|
|
||
|
|
// Test encoding
|
||
|
|
encoded, err := graphql.Encode(decoded)
|
||
|
|
require.Nil(t, err, "could not encode graphql query")
|
||
|
|
|
||
|
|
_, newKeyValues, _ := decodeQueryGetKV(encoded)
|
||
|
|
require.Equal(t, map[string]interface{}{
|
||
|
|
"jobType": "canary",
|
||
|
|
}, newKeyValues)
|
||
|
|
})
|
||
|
|
|
||
|
|
}
|