mirror of
https://github.com/FoggedLens/deflock.git
synced 2026-07-14 15:57:20 +02:00
fix GraphQL query injection in /sponsors/github
The username query param was interpolated directly into the GitHub GraphQL
query string (user(login: "${username}")) sent with the server token, and
the route only validated it as a string, so a value containing a quote could
break out of the string literal and alter the query document. Impact depends
on the token's scope; at minimum it allows tampering with the query structure.
Two changes:
- Pass the username as a $login GraphQL variable so it can never alter the
query document (the actual fix).
- Validate username against GitHub's username format at the route as
defense-in-depth, rejecting malformed input before it reaches the API.
Adds a regression test for the query builder (bun test). No change in
returned data for valid usernames.
This commit is contained in:
committed by
Jeremy Knows
parent
235f4ce87c
commit
3eceedb9c6
@@ -17,10 +17,18 @@ export type Sponsor = Static<typeof SponsorSchema>;
|
||||
|
||||
export const SponsorsResponseSchema = Type.Array(SponsorSchema);
|
||||
|
||||
// Pass the username as a GraphQL variable rather than interpolating it into the
|
||||
// query string, so a value containing quotes or other GraphQL syntax cannot
|
||||
// break out of the string literal and alter the query.
|
||||
export const buildSponsorsQuery = (username: string): { query: string; variables: { login: string } } => ({
|
||||
query: `query($login: String!) { user(login: $login) { sponsorshipsAsMaintainer(first: 100) { nodes { sponsor { login name avatarUrl url } } } } }`,
|
||||
variables: { login: username },
|
||||
});
|
||||
|
||||
export class GithubClient {
|
||||
async getSponsors(username: string): Promise<Sponsor[]> {
|
||||
const query = `query { user(login: "${username}") { sponsorshipsAsMaintainer(first: 100) { nodes { sponsor { login name avatarUrl url } } } } }`;
|
||||
const body = JSON.stringify({ query, variables: '' });
|
||||
const { query, variables } = buildSponsorsQuery(username);
|
||||
const body = JSON.stringify({ query, variables });
|
||||
const response = await fetch(graphQLEndpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
|
||||
Reference in New Issue
Block a user