Comments (17)
Many thanks! Somehow the fact that the CSP was being injected from a visible parm escaped me, and removing the header and updating CFN does indeed remove the failure.
Of course now we need to learn enough about CSP to deploy the correct headers rather than none at all, which is just how things go!
I notice that the update took a very long time (probably a combination of the CFront deploying to all regions and edge invalidation) and, more to interest, when the stack finally showed UPDATE_COMPLETE a number of individual events continue to show as as UPDATE_IN_PROGRESS, for example (HttpHeadersHandlerCodeUpdate, CheckAuthHandlerCodeUpdate) etc. as well as the event on the stack as a whole (CloudFrontDistribution). That's probably a CFN issue, but thought I'd call it out.
You're quite right, I should add to the documentation. At this stage all I have useful to say is how to deploy your own app 'on top of' the full deploy, but even that is probably worth putting in the README, along with your advice on removing CSP headers. Ideally other useful doc might include:
- A better description of how to deploy a preexisting app, probably using the
CreateCloudFrontDistribution
parameter that suppresses the bucket and distribution creation - A way to use a real domain name, should I ever figure it out
- Perhaps some naming customization. Although it looks to me like, for example with the S3 bucket name, any attempt to customize collides with a widely-used and existing BucketName reference.
I'd like to see the project become a piece of boilerplate for folks who just want to put some decent authentication in front of a SPA - and see it is close. I've tried a number of other published approaches, which all have not worked, probably because of bitrot.
Again, thanks!
from cloudfront-authorization-at-edge.
Hi @rpattcorner . When you deploy the stack you can pass in the HTTP headers as a stack parameter. Among the HTTP headers are the CSP headers, that you can alter (or remove). If you've already deployed the stack, you can redeploy it while specifying a new version for the HTTP headers parameter, the redeploy will then work as an update for your stack.
E.g. if you wanna just remove the CSP header for now:
sam deploy \
--template-file packaged.yaml \
--stack-name "${YOUR_STACK_NAME}" \
--capabilities CAPABILITY_IAM \
--parameter-overrides Version=$(date +%s) HttpHeaders='{"Strict-Transport-Security":"max-age=31536000; includeSubdomains; preload","Referrer-Policy":"same-origin","X-XSS-Protection":"1; mode=block","X-Frame-Options":"DENY","X-Content-Type-Options":"nosniff"}' \
--region us-east-1
Let me know if that helps.
More docs would be great, I agree with you totally! Is it something maybe you wanna help out with, as you are going through "taking the deployed solution to the next step" now?
from cloudfront-authorization-at-edge.
Sounds good. Let's keep this issue open until you've finished your setup, and ran into all the hurdles on your way. Then we can discuss what to add to the docs.
from cloudfront-authorization-at-edge.
OK ... I have an update on the README that documents the CSP mod which is trivial, but I can send a PR for just that bit any time if you want. Next comes doc on trying to deploy on an existing bucket. Then ... maybe someday ... manual work we've carried out creating a Cognito Identity Pool so our app can access an AWS Role. I have the manual steps, but the new serverless build framework is new to me, so may take some time.
I'm getting doubts about Cognito based on this post but for now it's what we're using ... because you did and your app provides so much value!
FUD is ubiquitous but it sounds like the writer had a fair number of concrete instances.
from cloudfront-authorization-at-edge.
Sure send me that PR on the CSP mod doc please. The smaller the PR's the better.
Regarding deploying to an existing bucket: that's also something I want to make possible in the deployment itself (#20 )
On Cognito: yes it has rough edges - but if you know what you're doing (/have good examples to follow) then you should be good.
from cloudfront-authorization-at-edge.
Some progress on controlling the s3 bucket based on the reuse-auth-only.yaml
example but the headers issue rears its head again.
The essence of the question I'm seeing is:
How can we use the
reuse-auth-template
pattern and override a parameter in the underlying SAM application. Specifically the HttpHeaders in this case, but other cases probably exist
From what I can see the reuse-auth-only.yaml
template leaves the Lambdas strictly alone, but to accomodate css we need to inject the http headers (without CSP in my case), just as the full deploy does. I'll experiment some, using the full template as a guide, but guidance on how to do so would be very welcome.
What I'm specifically seeing is:
- As an FYI, the
reuse-auth-only.yaml
is a little misleading in that it looks like it has a complete CloudFront example in it, but in fact does not, as the OAI is missing. - More to the point, once I've modded that template and deployed, external links to stylesheets are failing. My guess is this is the old CSP http header issue, and that's the area I'm looking for direction in
My goal is to produce a version of reuse-auth-only.yaml
that will actually run a (SPA mode) deployment while specifying the CDN and S3 artifacts.
The problem seems to be this:
- The strategy of
reuse-auth-only
is based on not messing with building from source, but rather incorporating default behaviors, but - In this case I need to modify a default behaviour, specifically supplying a set of (CSP-less for now) headers to the HttpHeadersHandler.
- Doing the obvious thing -- inserting the same kind of code modification stanzas the full template uses -- fails for lack of a proper CodeUri, e.g. src/... won't do with the simpler
reuse-auth-only
pattern.
It looks like that kind of code modification is present in the full up template, but that it requires a custom cloudformation resource to alter the HttpHeaders lambda's configuration.txt. Is this correct? If so, do you have any suggestions on how to enhance the reuse-only.yaml
to enable the custom resource functionality? If not, other ideas?
So, doing this:
Resources:
LambdaEdgeExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- edgelambda.amazonaws.com
- lambda.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
HttpHeadersHandler:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/lambda-edge/http-headers/
Handler: bundle.handler
Runtime: nodejs12.x
Role: !GetAtt LambdaEdgeExecutionRole.Arn
Timeout: 5
... more resources...
yields this deploy fail:
'CodeUri' is not a valid S3 Uri of the form 's3://bucket/key' with optional versionId query parameter..
In the full up template the Handler's CodeUri points to src/..., which makes sense as you're building in SAM.
Do you suppose there is a way in the reuse-auth-only
template there is a way to reference the CodeUri of the default HttpHeadersHandler that is being built behind the scenes as part of the nested stack, so we can pass the proper headers in? Per earlier note I suspect this requires enabling the custom resource in the CFN, or forking, building a SAM and modifying source, which I'd prefer to avoid.
I was stuck awhile because modifying configuration.json had no effect on the deployed app, until I discovered that you have to refresh the trigger, which is nearly invisible in the GUI. But doing so unblocks the desired CSS, so the question comes down to an economical way to enable the reuse
template to modify the published configuration.json like its big brother does ...
from cloudfront-authorization-at-edge.
@ottokruse OK, been quite some time since I've looked at nested stacks and custom resources and much has changed.
I think I understand the pattern shown in the main template, where a custom resource hits a special lambda that modifies others of the lambdas based on params, which is what I want. But I'm missing a detail that will probably be obvious.
I'm wanting (per above) to modify the HttpHandler for a custom configuration for CSP, but within my own stack that consumes the app.
So, I see the app exports the CodeUpdateHandler as well as the HttpHeadersHandler, and I want to do something like this:
LambdaEdgeProtection:
Type: AWS::Serverless::Application
Properties:
Location:
ApplicationId: arn:aws:serverlessrepo:us-east-1:520945424137:applications/cloudfront-authorization-at-edge
SemanticVersion: 1.1.0
Parameters:
CreateCloudFrontDistribution: "false"
# AlternateDomainNames: egt-labs.com
HttpHeadersHandlerCodeUpdate:
Type: Custom::LambdaCodeUpdate
Properties:
ServiceToken: !GetAtt LambdaEdgeProtection.Outputs.CodeUpdateHandler
LambdaFunction: !GetAtt LambdaEdgeProtection.Outputs.HttpHeadersHandler
Version: !Ref Version
Configuration: !Ref HttpHeaders
Which I'd hoped would use the ServiceToken addtress to invoke the CodeUpdateHandler lambda, telling it to update the HttpHeadersHandler.
But there's some kind of permissions problem. Which you'd think would not be an issue since I'm asking the import of the app to update itself. I get the access denied exception below (account number redacted).
Can you see where I've gone wrong?
Failed to create resource. AccessDeniedException: User: arn:aws:sts::999999999999:assumed-role/jmpr-cupdate-1a-LambdaEdg-LambdaCodeUpdateHandlerR-J6DG2NJSDKDZ/jmpr-cupdate-1a-LambdaEdge-LambdaCodeUpdateHandler-LPKE2OLZ02K4 is not authorized to perform: lambda:GetFunction on resource: arn:aws:lambda:us-east-1:999999999999:function:jmpr-cupdate-1a-LambdaEdgeProte-HttpHeadersHandler-10JN8QX4GCAUE:1 at Object.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:51:27) at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/rest_json.js:55:8) at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20) at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10) at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14) at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10) at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:1
from cloudfront-authorization-at-edge.
My goal is to produce a version of reuse-auth-only.yaml that will actually run a (SPA mode) deployment while specifying the CDN and S3 artifacts.
Awesome.
About the HTTP headers, can you not do it like this?:
LambdaEdgeProtection:
Type: AWS::Serverless::Application
Properties:
Location:
ApplicationId: arn:aws:serverlessrepo:us-east-1:520945424137:applications/cloudfront-authorization-at-edge
SemanticVersion: 1.1.0
Parameters:
CreateCloudFrontDistribution: "false"
# AlternateDomainNames: egt-labs.com
HttpHeaders: yourstuffhere
Can you see where I've gone wrong?
If you go the custom resource route (which I hope you do not have to) you need to give the Lambda handler of your custom resource permission to read and update the Lambda you want it to update. Did you do that?
from cloudfront-authorization-at-edge.
Ah, so close and yet so far. Never occurred to me to pass the HttpHeaders directly to the app. That seems to be accepted by CFN.
So we get a full CFN run, and inspection shows that the HttpHeaders lambda has the correct configuration.json. Yet on run I see:
503 ERROR
The request could not be satisfied.
The Lambda function associated with the CloudFront distribution is invalid or doesn't have the required permissions. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
Generated by cloudfront (CloudFront)
Request ID: c_PxcPfB_juqg2TVppHbTWsbcsUW3jOQULtO6N0EJT7hJMoa42TVdw==
Which is like nothing I ever saw, and incredibly vague. Any hints?
If I have to go back to the (clumsier) custom resource and adjust permissions, it sounds like you're saying I need to give the HttpHeadersHandlerCodeUpdate:
resource above the permission to modify the actual HttpHeadersHandler
in the nested stack. Did you mean in a similar manner to the snippet below from the full template?
LambdaCodeUpdateHandler:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/cfn-custom-resources/lambda-code-update/
Handler: index.handler
Runtime: nodejs12.x
Policies:
- Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- lambda:GetFunction
- lambda:UpdateFunctionCode
Resource:
- !GetAtt ParseAuthHandler.Arn
- !GetAtt CheckAuthHandler.Arn
- !GetAtt HttpHeadersHandler.Arn
- !GetAtt RefreshAuthHandler.Arn
- !GetAtt SignOutHandler.Arn
from cloudfront-authorization-at-edge.
The 503 looks like this item on the LambdaEdgePr-UserPoolDomainHandler. Never been a problem before. If you've seen it, let me know!
12:36:27
2020-05-11T12:36:27.256Z e9bae167-9a46-45ec-9f89-136fad11abb7 ERROR Can't parse physicalResourceId: undefined
2020-05-11T12:36:27.256Z e9bae167-9a46-45ec-9f89-136fad11abb7 ERROR Can't parse physicalResourceId: undefined
all I can find in the (cfn) doc is this:
physicalResourceId
Optional. The unique identifier of the custom resource that invoked the function. By default, the module uses the name of the Amazon CloudWatch Logs log stream that's associated with the Lambda function.
from cloudfront-authorization-at-edge.
Sorry mate you run into every corner case possible it seems.
Is it an option for you to start development in a brand new stack? I think the errors you get now might be caused by having deployed the same stack several times, using different versions.
We should really get the "simple" option working for you, to inject the HTTP headers as app params. That should work - and if it does not, that is a bug we should fix.
from cloudfront-authorization-at-edge.
Yes, this is challenging. Help is welcome.
I am deploying in a new stack each time ... not solid on stack updates so I've been avoiding them. A new deploy seems to still bring the 503, so no idea how to proceed.
The interactions between the CloudFront and Cognito have always been solid until this last injection of a parameter into the the application. Can't imagine what's changing.
Probably near the end of your day, but thoughts welcome
from cloudfront-authorization-at-edge.
Can you paste your CFN template here? Then I can reproduce
from cloudfront-authorization-at-edge.
May or may not be relevant ... I see in logs:
@timestamp
1589211025611
errorMessage
SyntaxError: Unexpected end of JSON input
errorType
Runtime.UserCodeSyntaxError
stack.0
Runtime.UserCodeSyntaxError: SyntaxError: Unexpected end of JSON input
stack.1
at _loadUserApp (/var/runtime/UserFunction.js:98:13)
stack.2
at Object.module.exports.load (/var/runtime/UserFunction.js:140:17)
stack.3
at Object.<anonymous> (/var/runtime/index.js:43:30)
stack.4
at Module._compile (internal/modules/cjs/loader.js:1156:30)
stack.5
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1176:10)
stack.6
at Module.load (internal/modules/cjs/loader.js:1000:32)
stack.7
at Function.Module._load (internal/modules/cjs/loader.js:899:14)
stack.8
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
stack.9
at internal/main/run_main_module.js:18:47
Doublechecking my headers param to be sure I'm not screwing up the JSON
from cloudfront-authorization-at-edge.
Yeah, that's it. Many thanks for the direction ... the problem was indeed a bad default in the json parameter that HttpHeaders silently applies to the request to checkAuth, messing it up mightily.
Hopefully that will get us doing, and get the team a nice new PR with documentation. The reuse-auth-only
doesn't have a noSPA example, which is just as well, since I don't have testing for it, but we should have a SPA example shortly.
from cloudfront-authorization-at-edge.
OK, PR's in. Thanks for the help!
from cloudfront-authorization-at-edge.
Thanks for your help!
Closing this one as we have merged #55
from cloudfront-authorization-at-edge.
Related Issues (20)
- On signout Required String parameter 'redirect_uri' is not present HOT 5
- Possible Open Redirect (CWE-601) in sample code HOT 2
- nonce cookies are not expired HOT 1
- [Feature request] Support multiple Cognito user pool clients HOT 4
- custom domain is not redirecting to cognito hosted ui HOT 1
- Getting blocked by CORS policy but unable to figure out the source HOT 5
- Node version bump HOT 7
- Custom IDP with Amplify and Auth at Edge HOT 9
- Fail on delete of the stack HOT 3
- Function must be in an Active state error on deploying the solution HOT 7
- Errors from Lambda when destroiyng the stack HOT 2
- Cognito TAGS HOT 1
- How Do I add User Pool attributes to Cookies? HOT 1
- A potential risk in cloudfront-authorization-at-edge which can be used to upload malicious code. HOT 4
- Having the ability to tune logs HOT 1
- Deployment to eu-west-2 fails with error: Encountered a permissions error performing a tagging operation HOT 4
- Missing User-Agent header in Post request to cognito HOT 4
- Question: redirecting after download from S3 HOT 2
- 'JavaScript heap out of memory' when running npm run build HOT 4
- Sign in, signout and then sign in again gets stuck at parse auth HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cloudfront-authorization-at-edge.