L
L
Ler Den2018-12-26 03:14:58
Nginx
Ler Den, 2018-12-26 03:14:58

How to organize csrf protection for NodeJS API?

There are 3 NodeJS applications on the server: public(angular + nodejs for uploading files), admin(same as public), API(nodejs). Nginx is configured as a reverse proxy so the config looks like this:

spoiler
server {
  listen 80 default_server;
  listen[::]: 80 default_server;
  server_name _;
  return 301 https://$host$request_uri;
}

server {
  listen 443;
  server_name example.com;
  ssl on;
  ssl_certificate / home / example.com / ssl - bundle.crt;
  ssl_certificate_key / home / example.com / private - key.key;
  ssl_prefer_server_ciphers on;
  root /var/www/html;
  index index.html index.htm index.nginx - debian.html;

  location / {
    proxy_pass http://localhost:4444;
      proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }

  location / api {
    proxy_pass http://localhost:5555;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }

  location / admin {
    proxy_pass http://localhost:7777;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }
}


The problem arose that I don’t understand how to protect the API using csrf or any other methods from being used by third-party users. This means that the API will only be used by my two applications on the . All others are banned. Now done like this
const csurf = require('csurf');
const csrfProtection = csurf({
  cookie: true
});
app.use(cookieParser());
if (process.env.PROD) {
    app.use(csrfProtection);
}
app.use(function (req, res, next) {
  res.cookie('XSRF-TOKEN', req.csrfToken());
  next();
});

The csrf token does not come to the angular, which is logical in principle - it has a different port and the API does not give the csrf token to it. And so when I try to submit the form, I get a message that the token is invalid. Through some manipulations with the code, I managed to get the token, though I can’t understand now how exactly I managed to do it. Roughly tried to do the following
app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "http://localhost:7777"); // порт ангуляра
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, XSRF-TOKEN");
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,PATCH,DELETE');
    res.header("Access-Control-Allow-Credentials", "true");
    res.cookie('XSRF-TOKEN', req.csrfToken());
  next();
});

I myself assume that the system should be fundamentally different. For example, make it so that Angular sends a request to its nodejs (there is its own csrf). There, set some kind of hash that will be checked against the API, plus allow requests only from this domain. If the hash matches, we return the data. It's all just kind of a pain in the ass. Is it possible to do something sooner?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question