controversies-of-science / react-worldviewer-app

(WIP) => { The Controversies of Science App. Currently includes controversy search and a swiping interface for structuring the crowdsourcing of information on controversies. }
https://www.controversiesofscience.com
1 stars 0 forks source link

Add security to all endpoints #106

Open worldviewer opened 7 years ago

worldviewer commented 7 years ago

I'm going to hold off on doing this until I've attended the AWS security seminar.

worldviewer commented 7 years ago

Videos:

Articles:

worldviewer commented 7 years ago

Instructions for securing API gateway endpoints (3 steps?):

(1) Create IAM policies that restrict access to API endpoints. How would I modify this?

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "execute-api:Invoke",
            "Effect": "Allow",
            "Resource": "arn:aws:execute-api:*:*:ff5h9tpwfh/*"
        },
        {
            "Action": "execute-api:Invoke",
            "Effect": "Deny",
            "Resource": "arn:aws:execute-api:*:*:ff5h9tpwfh/*/POST/locations/*"
        }
    ]
}

(2) Add authorizor to API gateway endpoint resources; if I am using the Serverless framework, I need to specify this in the serverless.yaml for each route that needs to be secured because the GUI inputs would get overwritten, right?

authorizer: aws_iam ?

(3) On the frontend, follow directions at http://serverless-stack.com/chapters/connect-to-api-gateway-with-iam-auth.html

  1. Authenticate against our User Pool and acquire a user token.
  2. With the user token get temporary IAM credentials from our Identity Pool.
  3. Use the IAM credentials to sign our API request with Signature Version 4.
worldviewer commented 7 years ago

I believe that (1) and (2) are now done.

worldviewer commented 7 years ago

(3) is done and it's now fetching from the API, although I now have some sort of a truncation of my dynamodb.scan() results -- which may be explained here?

worldviewer commented 7 years ago

It looks like the LastEvaluatedKey attribute indicates pagination ...

{ Items:
   [ { slug: 'the-trouble-with-sands-color' },
     { slug: 'bertrand-russells-10-commandments-of-teaching' },
     { slug: 'hindsight-bias-in-science' },
     { slug: 'innovations-long-tail' },
     { slug: 'quasi-neutrality' },
     { slug: 'platos-reveal' },
     { slug: 'the-safe-space' },
     { slug: 'rote-memorization-vs-meaningful-learning' },
     { slug: 'the-bug-in-sciences-machine' },
     { slug: 'the-debate-over-the-science-futures-market' },
     { slug: 'velikovskys-chronology' },
     { slug: 'the-cherry-picking-of-radiocarbon-dates' },
     { slug: 'the-speed-of-gravity' },
     { slug: 'dendrochronology' },
     { slug: 'anthony-peratt' },
     { slug: 'the-extinction-of-the-mammoths' },
     { slug: 'the-collapse-of-the-roman-civilization-as-a-lesson-for-the-scientific-community' },
     { slug: 'zombie-science' },
     { slug: 'exploration-vs-exploitation' },
     { slug: 'the-history-of-peer-review' },
     { slug: 'the-petroglyphs-as-records-of-cosmic-events' },
     { slug: 'electric-discharge-machining' },
     { slug: 'uniformitarianism-vs-catastrophism' },
     { slug: 'nuclear-half-life-modification-technology' },
     { slug: 'the-college-experience' },
     { slug: 'why-evolution-is-not-what-you-think-the-ebner-effect' },
     { slug: 'the-decline-in-conceptual-revolutions' },
     { slug: 'the-anti-pattern-of-settled-science' },
     { slug: 'the-problematic-weight-of-the-dinosaurs' },
     { slug: 'the-third-story' },
     { slug: 'the-unknown-graduate-student' },
     { slug: 'turning-data-into-insight' },
     { slug: 'the-connector' },
     { slug: 'what-gives-venus-its-feminine-attribute' },
     { slug: 'the-changing-radioactive-decay-rate' },
     { slug: 'the-dark-energy-fudge-factor' },
     { slug: 'the-map-is-not-the-territory' },
     { slug: 'sciences-gatekeeping-problem' },
     { slug: 'science-as-a-golum' },
     { slug: 'the-institute-for-venture-science-process' },
     { slug: 'the-positivists-vs-the-constructivists' },
     { slug: 'dingles-paradox' } ],
  Count: 42,
  ScannedCount: 42,
  LastEvaluatedKey: { slug: 'dingles-paradox' } }
worldviewer commented 7 years ago

Here are the policy statements that worked for restricting access to the API:

        {
            "Action": "execute-api:Invoke",
            "Effect": "Allow",
            "Resource": "arn:aws:execute-api:us-west-1:*:wu7nsd6i3a/GET/*"
        },
        {
            "Action": "execute-api:Invoke",
            "Effect": "Allow",
            "Resource": "arn:aws:execute-api:us-west-1:*:1xh0wwfkjf/GET/*"
        }

Restricting access to the S3 bucket on the basis of authenticated and unauthenticated users is proving to be far more difficult. The instructions are here.

Here is the policy I've got at the moment for both the authenticated and unauthenticated users:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "mobileanalytics:PutEvents",
                "cognito-sync:*",
                "cognito-identity:*"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": "cloudfront:*",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets",
                "s3:GetBucketLocation"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::controversy-cards-images"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::controversy-cards-images/*"
        },
        {
            "Action": "execute-api:Invoke",
            "Effect": "Allow",
            "Resource": "arn:aws:execute-api:us-west-1:*:wu7nsd6i3a/GET/*"
        },
        {
            "Action": "execute-api:Invoke",
            "Effect": "Allow",
            "Resource": "arn:aws:execute-api:us-west-1:*:1xh0wwfkjf/GET/*"
        }
    ]
}

Here's the policy on the S3 bucket:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::controversy-cards-images",
                "arn:aws:s3:::controversy-cards-images/*"
            ],
            "Condition": {
                "StringNotLike": {
                    "aws:userId": [
                        "AROAJYKBZMU5NOFS2U24K:*",
                        "AROAJPXWQHBEYC2MG6V6C:*",
                        "915249704669",
                        "AIDAJQAP4OIUWPSKGGDNU"
                    ]
                }
            }
        }
    ]
}

Three of those numbers at the end have to be generated with CLI commands:

AROAJYKBZMU5NOFS2U24K: "An assumed-role’s aws:userId value" (observe that there are two similar numbers: one is for authenticated and the other is for unauthenticated)

aws iam get-role --role-name Cognito_ControversiesofScienceIdentityPoolAuth_Role --profile serverless

AIDAJQAP4OIUWPSKGGDNU: Your IAM admin's unique ID (there is a risk that you may be locked out of administration of this role if you don't set this)

aws iam get-user --user-name controversy --profile serverless

The middle number corresponds to the root. It's another safety to avoid getting locked out of the administration of this role.