Leçon 21 : Ne pas divulguer les identifiants lors de la connexion aux services
Cette requête GraphQL récupère les identifiants depuis une valeur d'environnement, et évite qu'ils soient affichés dans la réponse ou les journaux, évitant ainsi les risques de sécurité :
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}"
}
})
}Voici une explication du fonctionnement de cette requête.
Comment les identifiants pourraient être divulgués
Nous devons souvent fournir des identifiants lors de la connexion à des services externes. Par exemple, l'API REST de GitHub nécessite un jeton d'accès pour les endpoints où les données sont privées ou modifiées :
query {
_sendJSONObjectItemHTTPRequest(input:{
url: "https://api.github.com/repos/GatoGraphQL/GatoGraphQL",
method: PATCH,
options: {
auth: {
password: "{ GITHUB_ACCESS_TOKEN }"
},
body: "{\"has_wiki\":false}"
}
})
}Nous devons être prudents et éviter d'exposer nos identifiants :
- Dans la requête GraphQL : Les identifiants ne doivent jamais être intégrés dans le code source, car ils seront en texte clair, créant un risque de sécurité
- Dans la réponse GraphQL : Si le champ se connectant au service produit une erreur, un message d'erreur sera ajouté dans la réponse GraphQL sous l'entrée
errors; ce message pourrait afficher le nom du champ qui a échoué avec ses arguments, affichant ainsi les identifiants - Dans les journaux du serveur : Si les identifiants sont accédés via une variable, et que cette variable est fournie comme paramètre URL, elle pourrait alors être enregistrée dans les journaux du serveur web
Requête GraphQL qui évite de divulguer les identifiants
Cette requête GraphQL transmet les identifiants à l'API de GitHub tout en évitant de les divulguer :
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}"
}
})
}C'est parce que :
- Les identifiants sont récupérés depuis une variable d'environnement
GITHUB_ACCESS_TOKEN, ils n'ont donc pas besoin d'être intégrés dans le code source - Le champ
githubAccessTokenest supprimé avec@remove, il n'est donc pas affiché dans la réponse - L'entrée
_sendJSONObjectItemHTTPRequest(auth:)référence la variable dynamique$__githubAccessToken, donc si le champ produit une erreur, c'est la chaîne littérale"$__githubAccessToken"qui sera affichée dans le message d'erreur (et non sa valeur)
Pour illustrer ce dernier point, fournir l'URL d'un dépôt inexistant "leoloso/NonExisting" à l'API de GitHub génère une erreur, et nous obtenons cette réponse (remarquez auth: {password: $__githubAccessToken} dans le message d'erreur) :
{
"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
}
}