确保请求站点可能欺骗 Google OpenID 详细信息

发布于 2024-12-26 12:33:11 字数 2494 浏览 0 评论 0原文

我可能错过了一些非常愚蠢的东西,并在 Google 联合登录 文档,但是 Google OpenID 登录对于请求站点来说实际上是安全的吗?请求站点如何知道详细信息来自 Google,而不仅仅是来自在 URL 中输入查询字符串参数的人?

为了说明这一点,我正在 PHP 中实现一个基本的 OpenID 登录序列,返回的似乎只是 URL 中的一堆查询字符串参数,我可以使用它们来获取 OpenID 详细信息,这非常有效。问题是,如果我只是手动在地址栏中输入这些内容而没有实际使用 Google 登录,我的请求站点如何知道其中的区别?

首先,请求详细信息的表单:

<form method='post' action='https://www.google.com/accounts/o8/ud'>

    <input type='hidden' name='openid.return_to' value='http://www.example/com/logged-in' />

    <input type='hidden' name='openid.mode' value='checkid_setup' />
    <input type='hidden' name='openid.ns' value='http://specs.openid.net/auth/2.0' />
    <input type='hidden' name='openid.claimed_id' value='http://specs.openid.net/auth/2.0/identifier_select' />
    <input type='hidden' name='openid.identity' value='http://specs.openid.net/auth/2.0/identifier_select' />

    <input type='hidden' name='openid.ns.ax' value='http://openid.net/srv/ax/1.0' />
    <input type='hidden' name='openid.ax.mode' value='fetch_request' />
    <input type='hidden' name='openid.ax.required' value='email,firstname,lastname' />
    <input type='hidden' name='openid.ax.type.email' value='http://axschema.org/contact/email' />
    <input type='hidden' name='openid.ax.type.firstname' value='http://axschema.org/namePerson/first' />
    <input type='hidden' name='openid.ax.type.lastname' value='http://axschema.org/namePerson/last' />

    <input type='submit' value='Login With Google Account' />

</form>

...效果很好,将我带回到请求站点 http://www.example.com/logged-in 并带有一大堆 URL 参数,如下图所示(来自 PHP print_r 调用):

Array
(
    [openid_ns] => http://specs.openid.net/auth/2.0
    [openid_mode] => id_res
    [openid_return_to] => http://www.example.com/logged-in
    [openid_ext1_type_firstname] => http://axschema.org/namePerson/first
    [openid_ext1_value_firstname] => {user's first name}
    [openid_ext1_type_email] => http://axschema.org/contact/email
    [openid_ext1_value_email] => {user's e-mail address}
    [openid_ext1_type_lastname] => http://axschema.org/namePerson/last
    [openid_ext1_value_lastname] => {user's last name}
)

...这很棒,但我怎么知道这实际上是一个合法的请求,而不是有人在地址中输入上述参数酒吧?

感谢您的任何帮助,如果已经有人问过这个问题(找不到任何副本!)以及如果我遗漏了一些明显的东西,我深表歉意!

I'm probably missing something really silly, and missed it in the Google Federated Login documentation, but how is the Google OpenID login actually secure for the requesting site? How does the requesting site know the details are coming from Google and not just someone typing in query string parameters into the URL?

To illustrate, I'm implementing a basic OpenID login sequence in PHP, and all that seems to be returned is a bunch of query string parameters in the URL that I can use to get the OpenID details, which works great. The problem is, if I just typed those into the address bar manually without actually logging in with Google, how would my requesting site know the difference?

First, the form requesting the details:

<form method='post' action='https://www.google.com/accounts/o8/ud'>

    <input type='hidden' name='openid.return_to' value='http://www.example/com/logged-in' />

    <input type='hidden' name='openid.mode' value='checkid_setup' />
    <input type='hidden' name='openid.ns' value='http://specs.openid.net/auth/2.0' />
    <input type='hidden' name='openid.claimed_id' value='http://specs.openid.net/auth/2.0/identifier_select' />
    <input type='hidden' name='openid.identity' value='http://specs.openid.net/auth/2.0/identifier_select' />

    <input type='hidden' name='openid.ns.ax' value='http://openid.net/srv/ax/1.0' />
    <input type='hidden' name='openid.ax.mode' value='fetch_request' />
    <input type='hidden' name='openid.ax.required' value='email,firstname,lastname' />
    <input type='hidden' name='openid.ax.type.email' value='http://axschema.org/contact/email' />
    <input type='hidden' name='openid.ax.type.firstname' value='http://axschema.org/namePerson/first' />
    <input type='hidden' name='openid.ax.type.lastname' value='http://axschema.org/namePerson/last' />

    <input type='submit' value='Login With Google Account' />

</form>

...which works great, sending me back to the requesting site at http://www.example.com/logged-in with a whole bunch of URL parameters, illustrated below (from a PHP print_r call):

Array
(
    [openid_ns] => http://specs.openid.net/auth/2.0
    [openid_mode] => id_res
    [openid_return_to] => http://www.example.com/logged-in
    [openid_ext1_type_firstname] => http://axschema.org/namePerson/first
    [openid_ext1_value_firstname] => {user's first name}
    [openid_ext1_type_email] => http://axschema.org/contact/email
    [openid_ext1_value_email] => {user's e-mail address}
    [openid_ext1_type_lastname] => http://axschema.org/namePerson/last
    [openid_ext1_value_lastname] => {user's last name}
)

...which is awesome, but how do I know that this is in fact a legitimate request, and not someone typing in the above parameters into the address bar?

Thanks for any help, apologies if this has been asked already (couldn't find any replicas!) and if I'm missing something obvious!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦幻之岛 2025-01-02 12:33:11

无需了解太多细节(如果需要详细信息,请阅读 OpenID 规范),OpenID 协议为此提供了保障措施。您收到的断言已签名且可验证,并且 ID 的命名空间方式存在限制,以防止提供者欺骗彼此的 ID。如果您使用的是已建立的库(例如 php-openid 就可以),您不必太担心这一点,因为它通常会在幕后处理。如果您正在尝试推出自己的实现......那么,请不要......

也就是说,协议中没有涵盖一些内容。例如,虽然属性在响应中进行了签名,但除非您信任特定的提供者,否则您不能假设它们是准确的。某些应用程序将检查做出断言的提供商的 URL/主机名(在验证响应后),并将执行正确电子邮件验证的已知身份提供商列入白名单。如果您需要经过验证的电子邮件,这样做可以带来更好的用户体验。但是,如果断言来自未知的身份提供商,则不要假设电子邮件地址实际上属于用户,除非您自己验证所有权。

Without going into too many details (read the OpenID spec if you need the gory details) the OpenID protocol has safeguards in place for this. The assertions you receive back are signed and verifiable, and there are limitations in how IDs are namespaced to prevent providers from spoofing each other's IDs. If you're using an established library (e.g. php-openid is fine) you shouldn't have to worry too much about this as it's usually taken care of underneath the covers. If you're trying to roll your own implementation....well, just don't...

That said, there are some things that aren't covered in the protocol. For example, while attributes are signed in the response, you can't assume they're accurate unless you trust the particular provider. Some apps will check the URL/hostname of the provider that made the assertion (after verifying the response) and whitelist known identity providers that do proper email verification. If you need a verified email, doing this makes for a better UX. But if the assertion is from an unknown identity provider don't assume the email address actually belongs to the user unless you verify possession yourself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文