question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Secure Cookie Enforcement Breaks Logins Behind Proxy

See original GitHub issue

Expected Behavior

Upgrading to @backstage/plugin-auth-backend >= 0.6.0 and resolving all of the noted breaking changes should allow the app to continue to function.

Current Behavior

After upgrading (to 0.6.1, though the change was made in 0.6.0), we are unable to log into the application when deployed, as the connect.sid cookie is no longer being set, and the openid-client Passport Strategy requires sessions.

Possible Solution

The changes made in https://github.com/backstage/backstage/pull/8592, while good from a CodeQL standpoint, were breaking changes to anybody running behind a proxy that relies on express-session for their Passport Strategy.

The breaking change is caused due to express-session requiring the use app.set('trust proxy', 1); in the express app in order to run behind a proxy if enforcing secure cookies. (https://github.com/expressjs/session#cookiesecure)

There is not currently a way (that I am aware of) to set the trust proxy policy when using the ServiceBuilder, meaning that short of re-implementing the logic in the ServiceBuilder, there is nothing that can be done in the current state.

My recommendation is to revert the secure cookie change (or make it configurable) until such time as the hooks are in place to set the trust proxy policy in the underlying express server.

Steps to Reproduce

  1. Rely on a Passport Strategy that requires sessions (such as OIDC)
  2. Have the Backstage app running behind a proxy (AWS ALB in our case).
  3. Update @backstage/plugin-auth-backend to >= 0.6.0.

Context

We are trying to keep our implementation up to date with the Backstage project, and this problem appeared after running backstage-cli versions:bump.

Your Environment

OS:   Linux 5.4.0-1063-azure - linux/x64
node: v14.17.6
yarn: 1.22.17
cli:  0.10.5 (installed)

Dependencies:
  @backstage/app-defaults                                  0.1.3
  @backstage/backend-common                                0.10.2
  @backstage/catalog-client                                0.5.3
  @backstage/catalog-model                                 0.9.8
  @backstage/cli-common                                    0.1.6
  @backstage/cli                                           0.10.5
  @backstage/config-loader                                 0.9.1
  @backstage/config                                        0.1.11
  @backstage/core-app-api                                  0.2.1, 0.3.1
  @backstage/core-components                               0.8.3
  @backstage/core-plugin-api                               0.3.1, 0.4.1
  @backstage/dev-utils                                     0.2.16
  @backstage/errors                                        0.1.5
  @backstage/integration-react                             0.1.17
  @backstage/integration                                   0.7.0
  @backstage/plugin-api-docs                               0.6.21
  @backstage/plugin-app-backend                            0.3.21
  @backstage/plugin-auth-backend                           0.6.1
  @backstage/plugin-catalog-backend                        0.19.4
  @backstage/plugin-catalog-import                         0.7.8
  @backstage/plugin-catalog-react                          0.6.10
  @backstage/plugin-catalog                                0.7.7
  @backstage/plugin-cost-insights                          0.11.16
  @backstage/plugin-explore-react                          0.0.9
  @backstage/plugin-explore                                0.3.24
  @backstage/plugin-github-actions                         0.4.30
  @backstage/plugin-graphiql                               0.2.26
  @backstage/plugin-org                                    0.3.33
  @backstage/plugin-permission-common                      0.3.0
  @backstage/plugin-permission-react                       0.2.1
  @backstage/plugin-proxy-backend                          0.2.15
  @backstage/plugin-scaffolder-backend-module-cookiecutter 0.1.7
  @backstage/plugin-scaffolder-backend                     0.15.19
  @backstage/plugin-scaffolder-common                      0.1.2
  @backstage/plugin-scaffolder                             0.11.17
  @backstage/plugin-search                                 0.5.4
  @backstage/plugin-shortcuts                              0.1.18
  @backstage/plugin-sonarqube                              0.2.11
  @backstage/plugin-tech-radar                             0.5.1
  @backstage/plugin-techdocs-backend                       0.12.2
  @backstage/plugin-techdocs                               0.12.13
  @backstage/plugin-user-settings                          0.3.15
  @backstage/search-common                                 0.2.1
  @backstage/techdocs-common                               0.11.2
  @backstage/test-utils                                    0.2.1
  @backstage/theme                                         0.2.14
  @backstage/types                                         0.1.1
  @backstage/version-bridge                                0.1.1

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
Rugvipcommented, Jan 5, 2022

Thank you for reporting, and sorry for the breakage!

So if I understand the feature from express-session correctly, it’s avoiding sending cookies back in HTTP requests in case someone is snooping in on those? It seems like a bit of an overly defensive check since if you’re worried about that you’d usually enforce HTTPS ahead of the session handling.

I think it makes sense to revert the secure cookie change for now tbh, as we’re not storing anything particularly sensitive just yet so not too critical that it is available. Another option could be to use the 'auto' option for now, as that will still let people use secure cookies in some cases, but it won’t work in the proxy case. Yet another option is to introduce something like a backend.trustProxy config, it won’t fix the breakage but is probably closer to the state that we want to be at.

Regarding access to the express app, we’ve pretty much settled that the ServiceBuilder is operating at the wrong abstraction level and needs to be broken down into pieces that compose better. Not a short-term fix ofc, but something we’re likely to look at this spring.

As a workaround for now you could perhaps add a middleware before the auth backend that sets req.secure?

const authRouter = Router()
authRouter.use((req, _res, next) => {
  req.secure = true
  next()
})
authRouter.use(await auth(authEnv))

apiRouter.use('/auth', authRouter);

Didn’t test the above so I’m not sure if req.secure is writable, other options are req.connection.encrypted and req.headers['x-forwarded-proto'] = 'https', basically something that makes the check at https://github.com/expressjs/session/blob/66634e9f77132a444dfda7e279a399054e3b28df/index.js#L623 pass

1reaction
JP-Dhaboltcommented, Jan 5, 2022

I was able to do a workaround by registering the middleware in the authRouter, virtually identical to the setup in the plugin-auth-backend router config, except changing the secure cookie to auto. I wasn’t sure what (if any) impact having the express-session middleware registered twice would have, but it would appear (at least initially) there is none.

I’ll put this in place until there is a more permanent resolution to this issue. Thanks for the assistance!

  const authRouter = Router();
  const secret = config.getOptionalString('auth.session.secret');
  if (secret) {
    authRouter.use(cookieParser(secret));
    authRouter.use(
      session({
        secret,
        saveUninitialized: false,
        resave: false,
        cookie: { secure: 'auto' },
      }),
    );
  }
  authRouter.use(await auth(authEnv));

  apiRouter.use('/auth', authRouter);
Read more comments on GitHub >

github_iconTop Results From Across the Web

Chrome SameSite cookie behavior effect on customer ...
Describes a potential disruptive impact to customer applications and services because of a change in cookie behavior in Chrome browser ...
Read more >
SameSite Cookie Attribute Changes - Auth0
Describes how browser changes, such as the SameSite cookie attribute, affects your web applications that embed content from third-party domains.
Read more >
Using HTTP cookies - MDN Web Docs
Session management. Logins, shopping carts, game scores, or anything else the server should remember ; Personalization. User preferences, themes, ...
Read more >
HttpOnly - OWASP Foundation
HttpOnly on the main website for The OWASP Foundation. OWASP is a nonprofit foundation that works to improve the security of software.
Read more >
Protecting Your Cookies: HttpOnly - Coding Horror
HttpOnly cookies don't make you immune from XSS cookie theft, ... your site breaks horribly for users behind load balancing proxies (larger ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found