Lezione 21: Non divulgare le credenziali durante la connessione ai servizi
Questa query GraphQL recupera le credenziali da un valore di ambiente, e ne evita la stampa nella risposta o nei log, evitando così rischi per la sicurezza:
query {
githubAccessToken: _env(name: "GITHUB_ACCESS_TOKEN")
@remove
_sendJSONObjectItemHTTPRequest(input:{
url: "https://api.github.com/repos/GatoGraphQL/GatoGraphQL",
method: PATCH,
options: {
auth: {
password: $__githubAccessToken
},
body: "{\"has_wiki\":false}"
}
})
}Di seguito è riportata una spiegazione del funzionamento di questa query.
Come potrebbero essere divulgate le credenziali
Spesso è necessario fornire credenziali quando ci si connette a servizi esterni. Ad esempio, l'API REST di GitHub richiede un token di accesso per gli endpoint in cui i dati sono privati o vengono modificati:
query {
_sendJSONObjectItemHTTPRequest(input:{
url: "https://api.github.com/repos/GatoGraphQL/GatoGraphQL",
method: PATCH,
options: {
auth: {
password: "{ GITHUB_ACCESS_TOKEN }"
},
body: "{\"has_wiki\":false}"
}
})
}Dobbiamo fare attenzione ed evitare di esporre le nostre credenziali:
- Nella query GraphQL: Le credenziali non devono mai essere incorporate nel codice sorgente, poiché sarebbero in testo normale, creando un rischio per la sicurezza
- Nella risposta GraphQL: Se il campo che si connette al servizio produce un errore, nella risposta GraphQL verrà aggiunto un messaggio di errore sotto la voce
errors; questo messaggio potrebbe stampare il nome del campo che ha fallito insieme ai suoi argomenti, stampando così le credenziali - Nei log del server: Se le credenziali vengono accedute tramite una variabile, e questa variabile viene fornita come parametro URL, potrebbe essere registrata nei log del server web
Query GraphQL che evita la divulgazione delle credenziali
Questa query GraphQL trasmette le credenziali all'API di GitHub evitando di divulgarle:
query {
githubAccessToken: _env(name: "GITHUB_ACCESS_TOKEN")
@remove
_sendJSONObjectItemHTTPRequest(input:{
url: "https://api.github.com/repos/GatoGraphQL/GatoGraphQL",
method: PATCH,
options: {
auth: {
password: $__githubAccessToken
},
body: "{\"has_wiki\":false}"
}
})
}Questo perché:
- Le credenziali vengono recuperate da una variabile di ambiente
GITHUB_ACCESS_TOKEN, quindi non è necessario incorporarle nel codice sorgente - Il campo
githubAccessTokenviene rimosso con@remove, quindi non viene stampato nella risposta - L'input
_sendJSONObjectItemHTTPRequest(auth:)fa riferimento alla variabile dinamica$__githubAccessToken, quindi se il campo produce un errore, è la stringa letterale"$__githubAccessToken"che verrà stampata nel messaggio di errore (non il suo valore)
Per dimostrare quest'ultimo punto, fornire all'API di GitHub l'URL di un repository inesistente "leoloso/NonExisting" genera un errore, e otteniamo questa risposta (si noti auth: {password: $__githubAccessToken} nel messaggio di errore):
{
"errors": [
{
"message": "Client error: `PATCH https://api.github.com/repos/leoloso/NonExisting` resulted in a `404 Not Found` response:\n{\"message\":\"Not Found\",\"documentation_url\":\"https://docs.github.com/rest/repos/repos#update-a-repository\"}\n",
"locations": [
{
"line": 21,
"column": 3
}
],
"extensions": {
"path": [
"_sendJSONObjectItemHTTPRequest(input: {url: \"https://api.github.com/repos/leoloso/NonExisting\", method: PATCH, options: {auth: {password: $__githubAccessToken}, body: \"{\"has_wiki\":false}\"}})",
"query { ... }"
],
"type": "QueryRoot",
"field": "_sendJSONObjectItemHTTPRequest(input: {url: \"https://api.github.com/repos/leoloso/NonExisting\", method: PATCH, options: {auth: {password: $__githubAccessToken}, body: \"{\"has_wiki\":false}\"}})",
"id": "root",
"code": "PoP/ComponentModel@e1"
}
}
],
"data": {
"_sendJSONObjectItemHTTPRequest": null
}
}