【问题标题】:Restricting request origin for AWS Cognito User Pools javascript api限制 AWS Cognito 用户池 javascript api 的请求来源
【发布时间】:2023-03-09 00:43:01
【问题描述】:

我担心 AWS Cognito 用户池 Javascript API 似乎并不关心来自哪个网站的请求(您使用 API 所需的只是用户池 ID 和客户端 ID,它们在我的 javascript 源代码)。

我是否担心其他网站可能会劫持我的用户池,从而可能诱骗用户注册?

如果这是一个有效的问题,有什么方法可以防止这种情况发生吗?预身份验证 Lambda 有效负载似乎不包含任何请求源数据,所以我想这不是这样做的方法。

如果这不是我需要关心的事情,为什么会这样?

【问题讨论】:

    标签: javascript node.js amazon-web-services aws-lambda amazon-cognito


    【解决方案1】:

    所以,我深思熟虑并决定这样做:

    是的,可以在前端使用这些数字。

    当然——原因如下。

    第一

    问题:

    我是否担心其他网站可能会劫持我的用户池,从而可能诱骗用户注册?

    回复:

    如果我要拿走你的UserPoolIDClientID - 我可以“劫持”你的应用程序吗?

    答案:

    完全是...也许有点像,但是为什么...

    您给予客户的“租用”或“许可”级别完全取决于您和您的 IAM 角色。 假设我们还没有考虑我的第二个也是更相关的原因 - (来源检查)

    如果我窃取了您的访问密钥并滥用了您的应用/品牌/其他任何东西,我只是在将客户吸引到您的网站。我无法访问您的客户列表、数据、日志、记录等。如果您将经过身份验证的用户权限设置为不允许。 锁定您对客户列表、池信息、数据等的“管理员级别”权限。

    示例(添加到您的Statement 部分):

    {
        "Effect": "Deny",
        "Action": [
            "cognito-identity:CreateIdentityPool",
            "cognito-identity:DeleteIdentityPool",
            "cognito-identity:DeleteIdentities",
            "cognito-identity:DescribeIdentity",
            "cognito-identity:DescribeIdentityPool",
            "cognito-identity:GetIdentityPoolRoles",
            "cognito-identity:ListIdentities",
            "cognito-identity:ListIdentityPools",
            "cognito-identity:LookupDeveloperIdentity",
            "cognito-identity:MergeDeveloperIdentities",
            "cognito-identity:SetIdentityPoolRoles",
            "cognito-identity:UnlinkDeveloperIdentity",
            "cognito-identity:UpdateIdentityPool"
        ],
        "Resource": [
            "arn:aws:cognito-identity:us-east-1:ACCOUNT_DIGITS:identitypool/us-east-1:PoolID_NUMBERS"
        ]
    }
    

    或者恰恰相反:

    {
        "Effect": "Allow",
        "Action": [
            "cognito-identity:GetOpenIdTokenForDeveloperIdentity"
        ],
        "Resource": "arn:aws:cognito-identity:us-east-1:ACCOUNT_DIGITS:identitypool/us-east-1:NUMBERS-NUMBERS-PoolID"
    }
    

    只需要"cognito-identity:GetOpenIdTokenForDeveloperIdentity" 部分。 锁定您的“用户级别”权限

    例子:

    {
        "Effect": "Allow",
        "Action": [ "s3:PutObject", "s3:GetObject" ],
        "Resource": [
            "arn:aws:s3:::[bucket]/[folder]/${cognito-identity.amazonaws.com:sub}/*"
        ]
    }
    

    作为一个明显的经验法则 - 只授予用户他们需要的权限。锁定所有可能锁定的垃圾并使用策略模拟器。 理由一的结论:

    您可以锁定所有会暴露您的客户群的事情,并让某人“劫持”您的网站变得毫无意义。 反驳论点:

    是的,但是 如果

    Here is a doc that might help for IAM stuff And some more


    第二

    问题:

    预身份验证 Lambda 有效负载似乎不包含任何请求源数据,所以我想这不是这样做的方法。

    回复:

    嗯。

    答案:

    是的,它确实包含请求来源数据 - 如果设置它。

    问题:

    我担心 AWS Cognito 用户池 Javascript API 似乎并不关心来自哪个网站的请求

    答案:

    为此 - 你是对的。如果您使用带有用户池触发器的静态服务文件 - 几乎不需要检查来源。

    所以 - 如果您真的想要 - 您可以使用 API Gateway 到 Lambda 来设置所有这些。 这将从客户端删除与用户池的直接交互并将其放在后端。

    前言:

    设置设置:

    1. 进入用户池并设置池
    2. 添加认知身份池
    3. 进入 Lambda 并将函数与 API 网关触发事件挂钩
    4. 输入您的代码 - 这是一个“登录”示例:


    const
        AWS      = require( 'aws-sdk' ),
        UserPool = new AWS.CognitoIdentityServiceProvider();
    
    exports.handler = ( event, context, callback ) => {
        console.log( event );
        const params = {
            AuthFlow: 'CUSTOM_AUTH',
            ClientId: 'numbers',
            AuthParameters: {
                USERNAME: event.email,
                PASSWORD: event.password
            }
        };
    
        UserPool.initiateAuth( params, ( err, data ) => {
            callback( err, data );
        } );
    };
    

    在上面 - 是的,你可以做到:

    UserPool.initiateAuth( params, callback );
    

    代替:

    UserPool.initiateAuth( params, ( err, data ) => {
        callback( err, data );
    } );
    

    但这会引发奇怪的错误 - GitHub 上已经存在一个关于它的问题。

    1. 从 API Gateway 转到触发事件
    2. 点击您的方法并进入Integration Request部分
    3. 在底部你会看到Body Mapping Templates
    4. 添加一个新的并输入application/json
    5. 您应该会看到以下示例模板:

    这是Apache Template Velocity Language - 不同于其他映射模板事物使用的JSONScheme 语言:

    #set($allParams = $input.params())
    {
        "body-json" : $input.json('$'),
        "params" : {
            #foreach($type in $allParams.keySet())
                #set($params = $allParams.get($type))
                "$type" : {
                    #foreach($paramName in $params.keySet())
                        "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
                        #if($foreach.hasNext),#end
                    #end
                }
            #if($foreach.hasNext),#end
            #end
        },
        "stage-variables" : {
            #foreach($key in $stageVariables.keySet())
            "$key" : "$util.escapeJavaScript($stageVariables.get($key))"
            #if($foreach.hasNext),#end
            #end
        },
        "context" : {
            "account-id" : "$context.identity.accountId",
            "api-id" : "$context.apiId",
            "api-key" : "$context.identity.apiKey",
            "authorizer-principal-id" : "$context.authorizer.principalId",
            "caller" : "$context.identity.caller",
            "cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider",
            "cognito-authentication-type" : "$context.identity.cognitoAuthenticationType",
            "cognito-identity-id" : "$context.identity.cognitoIdentityId",
            "cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId",
            "http-method" : "$context.httpMethod",
            "stage" : "$context.stage",
            "source-ip" : "$context.identity.sourceIp",
            "user" : "$context.identity.user",
            "user-agent" : "$context.identity.userAgent",
            "user-arn" : "$context.identity.userArn",
            "request-id" : "$context.requestId",
            "resource-id" : "$context.resourceId",
            "resource-path" : "$context.resourcePath"
        }
    }
    

    有了这个,你可以得到source-ip,认知信息等。

    此方法锁定源的安全方法。您可以通过在 Lambda 中执行 if 检查来检查来源,也可以使用 IAM 条件 - 阻止来自其他来源的所有请求。

    【讨论】:

    • 感谢您的周到回答。很高兴看到它可以在必要时被锁定。
    • 你明白了!我知道这并不完全是您在前端寻找的东西,但它肯定说明了类似的解决方案。看到他们没有在预授权触发器和其他东西中传递原始信息,我真的很惊讶
    猜你喜欢
    • 2020-04-22
    • 2016-12-18
    • 2018-11-28
    • 2018-09-06
    • 2020-06-14
    • 1970-01-01
    • 2019-03-29
    • 2018-01-31
    • 2018-11-07
    相关资源
    最近更新 更多