перенаправление HTTPS для всех маршрутов node.js / express - проблемы безопасности

17

Недавно я принял удар по настройке HTTPS на узле / экспресс-сервере. Мне удалось перенести все маршруты на использование https, используя следующий код:

// force https redirect
var https_redirect = function(req, res, next) {
  if (req.secure) {
    if(env === 'development') {
      return res.redirect('https://localhost:3000' + req.url);
    } else {
      return res.redirect('https://' + req.headers.host + req.url);
    }
  } else {
    return next();
  }
};

app.get('*', function(req, res, next) {
  https_redirect(req, res, next);
});

Кажется, это работает нормально. Тем не менее, поскольку я не имел права на это, прежде чем у меня возникнет пара вопросов:

  1. Это идеальный способ перенаправления с http на https?
  2. Если пользователь использует маршрут http, перед перенаправлением возможно, чтобы кто-нибудь использовал что-то вроде sslstrip, чтобы вынюхивать информацию о сеансе.

узел: v0.8.2; экспресс: v3.05

    
задан los7world 04.04.2013 в 16:11
источник

3 ответа

42
function requireHTTPS(req, res, next) {
    if (!req.secure) {
        //FYI this should work for local development as well
        return res.redirect('https://' + req.get('host') + req.url);
    }
    next();
}

app.use(requireHTTPS);
app.get('/', routeHandlerHome);

Подход промежуточного ПО будет работать, потому что express будет запускать промежуточное программное обеспечение в добавленном порядке до того, как он запустит маршрутизатор, и, в общем, такая политика на уровне сайта более чиста, чем промежуточное ПО и шаблон подстановочного знака.

Относительно вопроса 2 о купировании сеансов фальсификации, это должно быть устранено путем маркировки файлов cookie как secure при их установке. Если они не были помечены как безопасные, браузер также будет передавать их с HTTP-запросами, тем самым подвергая их обнюхиванию.

    
ответ дан Peter Lyons 05.04.2013 в 09:28
  • Питер благодарит за ответ. Это действительно помогло. –  los7world 05.04.2013 в 16:01
  • Это замечательно, но для разработки это немного проблематично, если вы используете нестандартные (80 для HTTP, 443 для HTTPS), потому что он пытается перенаправить на https: // localhost: [PORT]. Обходной путь - установить переменную среды SSL_PORT в среде разработки и, если она определена, заменить порт. См. Здесь измененный фрагмент. –  Gingi 12.06.2014 в 16:21
  • hei, как я могу подключиться к внешнему клиенту после этого? Благодаря ! –  alexsc 12.05.2015 в 14:46
  • В качестве примечания, на heroku вы должны использовать req.headers ['x-forwarded-proto']! == 'https', иначе это не сработает. См. Stackoverflow.com/questions/7185074/... –  S.Kiers 07.04.2017 в 07:48
1

Вы можете просто использовать функцию https_redirect (хотя и немного измененную) в качестве автоматического перенаправления всех ваших защищенных запросов:

// force https redirect
var https_redirect = function () {
  return function(req, res, next) {
    if (req.secure) {
      if(env === 'development') {
        return res.redirect('https://localhost:3000' + req.url);
      } else {
        return res.redirect('https://' + req.headers.host + req.url);
      }
    } else {
      return next();
    }
  };
};
app.use(https_redirect());

app.get('/', routeHandlerHome);
    
ответ дан red 04.04.2013 в 17:21
  • Эй, Джош. Спасибо за ответ. Можете ли вы подчеркнуть, как ваш подход конкретно с приложением. использование будет работать по сравнению с моей реализацией. –  los7world 05.04.2013 в 04:40
  • @ los7world: с помощью app.use () вы настраиваете промежуточное программное обеспечение без соответствия маршрутов, таким образом, все ваши маршруты будут проходить через него. –  red 05.04.2013 в 15:50
  • Понял. Спасибо за ваш вклад. –  los7world 05.04.2013 в 16:02
  • Не должно быть этого первого условия! req.secure –  Mladen Janjetovic 13.12.2016 в 10:27
0

Я использую этот простой код для перенаправления запросов в зависимости от того, находится ли приложение в разработке или производстве.

// force https redirect
var forceHTTPS = function () {
  return function(req, res, next) {
    if (!req.secure) {
      if (app.get('env') === 'development') {
         return res.redirect('https://localhost:3001' + req.url);
      } else {
        return res.redirect('https://' + req.headers.host + req.url);
      }
    } else {
      return next();
    }
  };
};
    
ответ дан davejoem 14.12.2015 в 22:08