使用Python在桌面应用程序中安全分发OAuth 2.0 client_secret [英] Safely distribute OAuth 2.0 client_secret in desktop applications in Python

查看:101
本文介绍了使用Python在桌面应用程序中安全分发OAuth 2.0 client_secret的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找有关如何设计和创建自己的桌面应用程序(或 https://github.com/googlesamples/oauth-apps-for-windows (用C#编码,但无论如何设计都应该相同).

I was looking for some best practices sample code about how to design and create my own desktop app (or installed app) in Python requiring OAuth 2.0 Authorization flow to Google, and found this repository provided by Google : https://github.com/googlesamples/oauth-apps-for-windows (coded in C#, but anyway the design should be the same).

深入研究代码时,我很惊讶地看到client_secret明确地直接嵌入到了源代码中(请在此处查看: https://github.com/googlesamples/oauth-apps-for-windows/blob/e79f1575b5457617 /OAuthConsoleApp/OAuthConsoleApp/Program.cs#L47 ).

When diving into the code, I was surprised to see that the client_secret was directly embedded, in clear, into the source code (take a look here : https://github.com/googlesamples/oauth-apps-for-windows/blob/e79f1575b5858c5f617d29f2435a93996e4248c5/OAuthConsoleApp/OAuthConsoleApp/Program.cs#L47).

我在有关已安装的应用程序"的Google Developers文档中找到了这个:

通过Google API控制台创建客户端ID时,请指定这是已安装的应用程序,然后选择Android,Chrome,iOS或其他"作为应用程序类型.该过程将产生一个客户端ID,在某些情况下会产生客户端密码,您将其嵌入到应用程序的源代码中. (在这种情况下,显然不会将客户机密视为机密.)

此外,我不知道为什么Android或iOS应用程序在控制台生成的OAuth客户端ID中不包含此client_secret,而其他本机应用程序(台式机)应该包含.

Also, I don't know why Android or iOS applications does not include this client_secret in the OAuth Client ID generated from the console, and other native applications (desktop) should.

在许多网站上,我还发现应将客户机密保存为机密……,正如其名称所暗示的那样.

And I have also found in many websites that the client secret should be kept ... secret, as its name implies.

我已经阅读了本机应用程序的不同RFC(我认为是最可靠的来源),并发现这很有用:

I have read the different RFCs for native apps (most reliable source I believe) and found this useful :

https://tools.ietf. org/html/draft-ietf-oauth-native-apps-12#appendix-A :

  1. 不假定本机应用程序客户端可以保守秘密.如果机密分发到同一本机应用程序的多个安装中,则不应将其视为机密.请参阅第8.5节.

但是我想确保我理解正确.

But I'd like to be sure I understand correctly.

因此,从Google API控制台生成其他"应用程序类型的OAuth客户端ID后,可以直接将客户端密码嵌入我的应用程序中吗?这样做真的没有安全问题吗?这样的帖子:如果攻击者可以做什么他获得了应用程序的client_secret吗?谈到安全问题,所以我有点迷失了.

So, after generating the OAuth Client Id for "other" application type from the Google API Console, is it ok to embed the client secret directly in my app? Is there really no security issues by doing this? This SO post : What the attacker could do if he obtains application's client_secret? talks about security issues, so I'm a little bit lost.

使用 google-auth-oauthlib 可以避免从头开始实施OAuth协议,我安全地分发以下代码(****值不会明显混淆):

Using google-auth-oauthlib to avoid implementing OAuth protocol from scratch, can I distribute safely the following code (**** values will not be obfuscated obviously) :

from google_auth_oauthlib import flow

# generated from Google API Console ("other" application)
client_config = {
  "installed": {
    "client_id": "****.apps.googleusercontent.com",
    "client_secret": "****", # is it safe?
    "project_id": "****",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "redirect_uris": [
      "urn:ietf:wg:oauth:2.0:oob"
    ]
  }
}

scopes = ['https://www.googleapis.com/auth/books'] # example
appflow = flow.InstalledAppFlow.from_client_config(client_config, scopes=scopes)
appflow.run_console()
credentials = appflow.credentials

# some code requesting Google APIs for the required scopes

如果恶意用户找到了client_secret,他该怎么办?

If a malicious user found the client_secret, what can he do with this?

推荐答案

当公共客户端(例如,本机和单页应用程序)请求访问令牌时,会带来一些其他的安全问题,仅授权代码流无法缓解这些问题.这是因为:

When public clients (e.g., native and single-page applications) request Access Tokens, some additional security concerns are posed that are not mitigated by the Authorization Code Flow alone. This is because:

本机应用程序
无法安全地存储客户端密钥.对该应用程序进行反编译将显示客户端机密",该客户端机密已绑定到该应用程序,并且对于所有用户和设备都是相同的. 可能会利用自定义URL方案来捕获重定向(例如MyApp://),从而潜在地允许恶意应用程序从您的授权服务器接收授权代码.

Native apps
Cannot securely store a Client Secret. Decompiling the app will reveal the Client Secret, which is bound to the app and is the same for all users and devices. May make use of a custom URL scheme to capture redirects (e.g., MyApp://) potentially allowing malicious applications to receive an Authorization Code from your Authorization Server.

单页应用程序
无法安全存储客户端机密,因为浏览器可以使用它们的全部来源.

Single-page apps
Cannot securely store a Client Secret because their entire source is available to the browser.

为减轻这种情况,OAuth 2.0提供了一个版本的授权代码流,该版本使用了代码交换证明密钥(PKCE)(在OAuth 2.0 RFC 7636中定义).

To mitigate this, OAuth 2.0 provides a version of the Authorization Code Flow which makes use of a Proof Key for Code Exchange (PKCE) (defined in OAuth 2.0 RFC 7636).

增强了PKCE的授权代码流引入了由调用应用程序创建的秘密,该秘密可以由授权服务器进行验证.这个秘密称为代码验证程序.此外,调用应用程序会创建称为代码挑战的代码验证程序的转换值,并通过HTTPS发送此值以检索授权代码.这样,恶意攻击者只能拦截授权代码,并且如果没有代码验证程序,他们就不能将其交换为令牌.

The PKCE-enhanced Authorization Code Flow introduces a secret created by the calling application that can be verified by the authorization server; this secret is called the Code Verifier. Additionally, the calling app creates a transform value of the Code Verifier called the Code Challenge and sends this value over HTTPS to retrieve an Authorization Code. This way, a malicious attacker can only intercept the Authorization Code, and they cannot exchange it for a token without the Code Verifier.

进一步阅读: https://auth0.com/docs/flows/概念/auth-code-pkce

这篇关于使用Python在桌面应用程序中安全分发OAuth 2.0 client_secret的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆