programing

express.js를 사용하여 Ajax 호출에서 CSRF 보호를 구현하는 방법(완전한 예 찾기)?

iphone6s 2023. 8. 20. 10:33
반응형

express.js를 사용하여 Ajax 호출에서 CSRF 보호를 구현하는 방법(완전한 예 찾기)?

express.js 프레임워크를 사용하여 node.js를 사용하여 만든 앱에서 CSRF 보호를 구현하려고 합니다.앱은 서버에 대한 Ajax 포스트 콜을 풍부하게 활용합니다.연결 프레임워크가 CSRF 미들웨어를 제공하는 것은 이해하지만 클라이언트 측 Ajax 포스트 요청 범위에서 어떻게 구현해야 할지 잘 모르겠습니다.

스택 오버플로에 게시된 다른 질문에도 이와 관련된 부분이 있지만, 클라이언트와 서버 양쪽에서 이를 구현하는 방법에 대한 상당히 완벽한 예는 아직 찾지 못했습니다.

이를 구현하는 방법에 대해 공유하고 싶은 실무 사례가 있습니까?제가 본 대부분의 예는 서버 측에서 양식을 렌더링한 다음 (내장된 csrf_token 양식 필드와 함께) 클라이언트 측으로 보낸다고 가정합니다.내 앱에서 모든 콘텐츠는 Backbone.js를 통해 클라이언트 측(템플릿 포함)에서 렌더링됩니다.서버가 하는 모든 것은 클라이언트 측의 Backbone.js의 다양한 모델에서 사용되는 JSON 형식의 값을 제공하는 것입니다.제가 알기로는 먼저 아약스를 통해 csrf_token을 검색해야 사용할 수 있을 것 같습니다.하지만, 저는 이것이 보안 측면에서 문제가 될 수 있다고 우려합니다.이것이 타당한 우려입니까?

다음을 추가하여 수행할 수 있습니다.metaCSRF 토큰에 태그를 지정한 다음 모든 Ajax 요청과 함께 CSRF 토큰을 전달합니다.

서버

CSRF 미들웨어 추가

app.use(express.csrf());
app.use(function (req, res, next) {
  res.locals.token = req.session._csrf;
  next();
});

CSRF 토큰을 메타 태그 등을 통해 클라이언트 측에 전달할 수 있습니다.예를 들어,Jade

meta(name="csrf-token", content="#{token}")

고객

jQuery에는 Ajax Prefilter라는 기능이 있으며, 이 기능을 통해 모든 Ajax 요청을 호출할 수 있습니다.그런 다음 ajaxPrefilter를 사용하여 헤더를 설정합니다.

var CSRF_HEADER = 'X-CSRF-Token';

var setCSRFToken = function (securityToken) {
  jQuery.ajaxPrefilter(function (options, _, xhr) {
    if (!xhr.crossDomain) {
      xhr.setRequestHeader(CSRF_HEADER, securityToken);
    }
  });
};

setCSRFToken($('meta[name="csrf-token"]').attr('content'));

server.js

...
// All Cookies/Sessions/BodyParser go first
app.use(express.csrf());
...
// Get the request
app.post('/ajax', function(req, res){
    res.render('somelayout', {csrf_token: req.session._csrf});
});

어떤 레이아웃에서.

input(type='hidden', name='_csrf', value=csrf_token)

CSRF 미들웨어는 세션당 한 번만 csrf 토큰을 생성하므로 사용자가 방문하는 동안에는 변경되지 않을 수 있습니다.

또한 GET 및 HEAD 요청 시 토큰을 확인하지 않습니다.토큰이 요청(헤더, 본문 또는 쿼리)에 있는 한 괜찮습니다.그것이 그것의 거의 전부입니다.

사용 중이므로Backbone.js당신의 신청을 위해, 나는 그것이 SPA이고 당신이 처음에 로드한다고 가정합니다.index.html파일을 작성한 후 다음을 통해 다른 요청을 합니다.ajax만약 그렇다면, 당신은 JS 코드의 작은 조각을 당신의 컴퓨터에 추가할 수 있습니다.index.html입니다.ajax전화가 걸려오는 전화.

예:

index.html(템플릿에 핸들 바 사용...)

<!DOCTYPE html>
<html>
    <head>
        ...
        <script type="text/javascript">
            $( function() {
                window.Backbone.csrf = "{{csrfToken}}";
            });
        </script>
    </head>
    <body>
        ...
    </body>
</html>

를 때index.html▁it주,▁give▁file▁the.csrf: express 프임워여생성서한토큰기레가:req.session._csrf

를 할 때Backbone.js은 라고 글변설수다정니합를로라는 합니다.Backbone은 이함수수행모는든작다업같것설속다입정니성는하은을라는 을 설정하는 것뿐입니다.csrfBackbone물건.그리고 당신이 그것을 만들 때ajax로 불러들입니다.POSTdata, 이터추, 히가단을 합니다.Backbone.csrf를 이터에 변수한으로 합니다._csrf그것은 다음을 통해 보내집니다.ajax콜.콜.

서버:

app.use(function (req, res) {
  res.locals._csrf = req.csrfToken();
  res.locals.csrf_form_html = '<input type="hidden" name="_csrf" value="' + req.csrfToken() + '" >';
  req.next();
});

InClient: (템플릿 전환)

var csrf = {{ _csrf|json|safe }};

$.ajaxSetup({
  headers: {
    'X-CSRF-Token': csrf
  }
});

$.post("/create", data, function(result) {
  console.log(result);
}).fail(function(){
  console.log(arguments);
});

csrf 보호 미들웨어 추가:

app.use(csrf({cookie: true}));

// csrf middleware
app.use(function (req, res, next) {
   res.cookie('X-CSRF-Token', req.csrfToken());
   // this line below is for using csrfToken value in normal forms (as a hidden input)
   res.locals.csrfToken = req.csrfToken(); 
   next();
});

// routing setup goes here

추가 abeforeSend사하여콜을 사용하여 $.ajaxSetup에 이

$.ajaxSetup({
beforeSend: function (xhr, settings) {
    function getCookie(name) {
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }

    if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
        // Only send the token to relative URLs i.e. locally.
        xhr.setRequestHeader("X-CSRF-Token", getCookie('X-CSRF-Token'));
    }
}
});

이상입니다! 이제 Ajax 요청을 보낼 수 있으며 csrf를 통과하기 위해 헤더나 요청 매개 변수에 아무것도 추가할 필요가 없습니다.

언급URL : https://stackoverflow.com/questions/11200068/how-to-implement-csrf-protection-in-ajax-calls-using-express-js-looking-for-com

반응형