GraphQL Debug Mode Enabled
已启用 GraphQL 调试模式
描述
GraphQL 调试模式(GraphQL Debug Mode)是一项功能,在启用时,会在响应中提供详细的错误消息、堆栈回溯以及额外的调试信息。虽然这在开发过程中非常有价值,但如果将其在生产环境中保持启用状态,则可能会暴露有关服务器内部结构和实现细节的敏感信息。
在 Django Graphene 中,调试模式通常由 Django 的 DEBUG 设置和在 Graphene 配置中包含 DjangoDebugMiddleware 来控制。
启用调试模式后,错误响应可能包括: - 详细的堆栈回溯 - 数据库查询信息(包括 SQL 查询) - 内部服务器路径和文件名 - 敏感的配置细节
在 Django Graphene 中启用调试模式的响应示例:
{
"errors": [
{
"message": "Cannot query field \"nonexistentField\" on type \"Query\".",
"locations": [
{
"line": 3,
"column": 3
}
],
"path": ["nonexistentField"]
}
],
"data": null,
"extensions": {
"debug": {
"sql": [
{
"sql": "SELECT \"auth_user\".\"id\", \"auth_user\".\"password\", \"auth_user\".\"last_login\", \"auth_user\".\"is_superuser\", \"auth_user\".\"username\", \"auth_user\".\"first_name\", \"auth_user\".\"last_name\", \"auth_user\".\"email\", \"auth_user\".\"is_staff\", \"auth_user\".\"is_active\", \"auth_user\".\"date_joined\" FROM \"auth_user\" WHERE \"auth_user\".\"id\" = %s LIMIT 21",
"time": "0.000",
"params": ["1"]
}
],
"python_version": "3.8.5",
"django_version": "3.1.3",
"graphene_version": "2.1.8",
"graphql_version": "3.0.0"
}
}
}
GraphQL 调试模式的安全影响: - 信息泄露:调试信息可能会揭示有关 GraphQL 服务器的结构、依赖项以及潜在漏洞的内部细节,攻击者可能会利用这些信息来策划更有针对性的攻击。 - 敏感数据暴露:堆栈回溯、错误消息,尤其是 SQL 查询,可能会无意中包含敏感信息,例如数据库结构、内部文件路径或环境变量。 - 更容易被利用:详细的错误消息和 SQL 查询可以通过就哪些方法有效或无效提供即时反馈,来帮助攻击者改进其恶意查询。 - 性能信息泄漏:为 SQL 查询提供的计时信息可能会被攻击者用于推断数据库结构或执行时序攻击(timing attacks)。
建议
为了降低与 GraphQL 调试模式相关的风险,请考虑以下建议:
-
在生产环境中禁用调试模式:确保在生产环境中禁用 GraphQL 调试模式。调试信息应仅在开发和测试环境中可用。
-
使用特定于环境的设置:实施特定于环境的配置以控制调试模式和错误的详细程度。
-
实施自定义错误处理:创建一个自定义的错误处理机制,在将错误消息发送给生产环境中的客户端之前对其进行清理,删除任何敏感信息,同时仍提供有用的反馈。
-
安全日志记录:实施安全的日志记录机制,以存储详细的错误信息供以后分析,而不是通过调试模式将其暴露。
在 Django Graphene 中控制调试模式的示例:
# settings.py
DEBUG = False # Set to True only in development
GRAPHENE = {
'MIDDLEWARE': [
'graphene_django.debug.DjangoDebugMiddleware',
] if DEBUG else []
}
# 自定义错误处理
from graphene_django.views import GraphQLView
from django.http import JsonResponse
from django.conf import settings
class CustomGraphQLView(GraphQLView):
@staticmethod
def format_error(error):
if settings.DEBUG:
return GraphQLView.format_error(error)
return {"message": "An error occurred"}
def execute_graphql_request(self, *args, **kwargs):
result = super().execute_graphql_request(*args, **kwargs)
if result.errors:
errors = [self.format_error(e) for e in result.errors]
return JsonResponse({"errors": errors})
return result
# 在 urls.py 中使用 CustomGraphQLView
此设置可确保仅在开发环境中提供详细的调试信息(包括 SQL 查询)。在生产环境中,错误会被清理以防止信息泄漏。
对于其他 GraphQL 服务器的实现,请参阅关于如何控制调试模式并实施安全错误处理的具体文档。
链接
标准
- PCI_STANDARDS:
- REQ_6_5
- REQ_11_3
- OWASP_MASVS_L2:
- MSTG_ARCH_9
- OWASP_ASVS_L3:
- V7_4_1
- SOC2_CONTROLS:
- CC_6_1
- CC_6_7
- CC_7_1
- HIPAA_CONTROLS:
- SECURITY212
- SECURITY213
- SECURITY255