String values are not escaped by the GraphQlAstPrinter
Problem
The GraphQL support in API Security works by creating a GraphQL AST that is updated with mutated values. The AST is then turned into a GraphQL operation using the GraphQlAstPrinter
component. The GraphQlAstPrinter
is not escaping special characters in the string when handling StringValue
AST nodes. This results in mutated values escaping the string value, resulting in invalid GraphQL syntax.
In this example we see an XXE injection into the before
argument to the allThings
things query operation.
The quoting around "1.0" and "utf-8" is one level to shallow, and instead of setting the before
argument's value, instead we are
creating invalid GraphQL syntax. This is validated through the syntax error response.
Pipeline Job: https://gitlab.com/gitlab-org/security-products/tests/api-fuzzing-e2e/dast-generic/-/jobs/3042676030
Request:
"body": "{\"query\":\"query allThings {allThings(before: \\\"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?><!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xmlxxe SYSTEM \\\"file:///etc/passwd\\\">]><foo>&xmlxxe;</foo>\\\", after: \\\"hello\\\", first: 42, last: 42) {pageInfo {hasNextPage}}}\",\"variables\":null}"
Response:
"body": "{\"errors\":[{\"message\":\"Syntax Error GraphQL (1:52) Expected Name, found Float \\\"1.0\\\"\\n\\n1: query allThings {allThings(before: \\\"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?><!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xmlxxe SYSTEM \\\"file:///etc/passwd\\\">]><foo>&xmlxxe;</foo>\\\", after: \\\"hello\\\", first: 42, last: 42) {pageInfo {hasNextPage}}}\\n ^\\n\",\"locations\":[{\"line\":1,\"column\":52}]}]}"
Proposal
Modify the GraphQlAstPrinter
to quote string values when they are written out.
Existing code that doesn't string escape:
Config<StringValue>(c =>
{
c.Field(x => x.Value);
c.Print(f =>
{
var val = f.Arg(x => x.Value);
if (!string.IsNullOrWhiteSpace(val?.ToString()) && !val.ToString().StartsWith("\"", StringComparison.InvariantCulture))
{
val = $"\"{val}\"";
}
return val;
});
});
Tasks
-
Add test to prove bug -
Modify code to escape special characters like double-quote (") -
Verify all test are passing -
Release new version of API Security