限制 AWS Cognito 用户池的请求源 javascript api

Restricting request origin for AWS Cognito User Pools javascript api

我担心 AWS Cognito 用户池 Javascript API 似乎并不关心来自哪个网站的请求(您只需要使用 API用户池 ID 和客户端 ID,可以在我的 javascript 来源中轻松获得)。

我担心另一个网站可能会劫持我的用户群,可能会诱使用户注册吗?

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

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

所以,我考虑了很长时间并决定:

Yes it's ok to have those digits on your front end.

当然 - 原因如下。

第一个:

问题:

Am I right to be concerned that another site could hijack my user pool, potentially tricking users into signing up to it?

回复:

If I were to take your UserPoolID and ClientID - could I "hijack" to your application?

答案:

Not exactly...maybe kinda sorta but why...

您为客户提供的 "tenancy" 或 "permission" 级别完全取决于您和您的 IAM 角色。 假设我们不考虑我的第二个更相关的原因,但是-(来源检查)

如果我窃取您的访问密钥并滥用您的 app/brand/whatever,我只是在吸引客户访问您的网站。我无法访问您的客户列表、数据、日志、记录等。如果您将经过身份验证的用户权限设置为不允许。 锁定您对客户列表、矿池信息、数据等的 "Admin Level" 权限

示例(添加到您的 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"部分。 锁定你的 "User Level" 权限

示例:

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

作为一个明显的经验法则 - 仅向用户授予他们需要的权限。锁定您可能锁定的所有废话并使用策略模拟器。 结论一:

You can lock down all the things that would expose your client base and make it pointless for someone to 'hyjack' your site. Counter argument:

Ya, but what IF

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


第二:

问题:

The pre-authentication Lambda payload doesn't seem to include any request origin data, so I guess that isn't the way to do it.

回复:

Hmm.

答案:

Yes it does include request origin data - IF one sets it up.

问题:

I'm concerned that the AWS Cognito User Pools Javascript API doesn't seem to care which website requests are coming from

答案:

For this - you're correct. If you are using static served files with user pools triggers - there is little done to check origin.

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

前言:

设置为设置:

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


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网关
  2. 转到触发事件
  3. 单击您的方法并进入 Integration Request
  4. 部分
  5. 在底部您会看到 Body Mapping Templates
  6. 添加一个新的并放入application/json
  7. 您应该会看到示例模板如下:

这是 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 条件 - 阻止来自其他来源的所有请求。