당신이 나와 같다면, 당신은 멋진 앱을 만드는 것을 좋아하기 때문에 이 사업에 뛰어든 것입니다. 개발 분야에 오랫동안 종사했다면 결국에는 별로 멋지다고 느껴지지 않는 멋진 앱 작업을 하게 될 것입니다. . 보안은 그러한 것 중 하나일 수 있습니다. Rails 프레임워크가 많은 무거운 작업을 수행하더라도 Rails 보안을 진지하게 고려하는 것이 중요합니다.
Ruby on Rails 보안에 대해 자세히 알아보기 전에 잠시 좋았던 시절을 되돌아보겠습니다.

...그리고 이제 현실 세계로 돌아왔습니다.
보안 위협에 대해 걱정해야 한다는 것조차 짜증스럽습니다. 매일 아침 일어나서 당신이 만들고 있는 것을 부수려고 하는 사람들이 있다는 사실이 정말 안타깝습니다.
그런데 이런 사람들이 존재합니다. 그들은 보안에 구멍을 뚫기 위해 열심히 노력합니다. 그리고 성공하면 그것은 당신의 잘못입니다.
귀하의 클라이언트는 귀하를 대신하여 귀하의 코드를 안전하게 만들 수 없습니다. 당신의 관리자는 당신을 위해 그것을 할 수 없습니다. 모든 것은 당신에게 달렸습니다. 그러니 당신이 지금 무슨 짓을 하고 있는지 더 잘 알 수 있을 겁니다.
Rails 보안에 관심을 가져야 하는 이유는 무엇인가요?
- 보안 모범 사례를 따르려고 노력하지만 실제로는 이해하지 못하시나요?
- XSRF, MITM 및 XSR 공격이 어떻게 작동하는지 잘 모르시나요?
- 귀하의 앱이 작거나 내부용이므로 위험하지 않다고 생각하시나요?
이들 중 하나라도 사실이라면 이 가이드는 확실히 당신을 위한 것입니다. 보안은 모든 앱에 중요하며, 그렇지 않을 때까지는 보안에 투자하지 않는 것이 좋습니다. Rails를 사용하면 웹 애플리케이션의 가장 큰 보안 위험 중 일부를 매우 간단하게 완화할 수 있으므로 격차를 좁히지 않는 것은 어리석은 일입니다.
귀하의 애플리케이션이 타겟이 아니라고 생각하시나요?
당신은 아마도 틀렸을 것입니다. 인터넷에 있다면 포위 공격을 받고 있는 것입니다. 자동화된 시스템은 취약한 웹 앱을 24시간 내내 검색하고 있습니다.
조직 범죄든 봇이든 인터넷에는 사용자의 데이터를 손에 넣으려는 악의적인 행위자로 가득 차 있습니다.
조직범죄는 현실이다
데이터베이스에 신용 카드를 저장하고 있습니까? 무염 비밀번호 해시? 나는 그렇지 않기를 바랍니다! 그렇다면 당신은 망한 것입니다. Rails를 사용하면 이와 같은 실수를 비교적 쉽게 방지할 수 있습니다.
봇넷이 당신을 무너뜨릴 것입니다

봇넷을 실행하면 더 많은 봇이 더 많은 돈을 벌게 됩니다. 따라서 익스플로잇 팩을 구입하고 오래된 브라우저가 페이로드에 도달하면 악성 코드를 설치하도록 설정한 다음 일부 합법적인 사이트를 해킹하여 많은 사용자에게 페이로드를 전달합니다.
외국 정부가 당신을 잡으러 나섰습니다
농담처럼 들리겠지만, 중국 정부는 영업 비밀, 정부 정보, 심지어 정치적 적에 관한 정보까지 찾아내기 위해 수천 명의 해킹 시스템을 보유하고 있습니다.
정말 재미있는 일 같지 않나요?
전 세계적으로 해킹 자원을 지휘하는 국가는 중국만이 아닙니다. 전 세계 정부가 참여하므로 귀하의 애플리케이션이 보안 문제를 심각하게 받아들일 만큼 중요하지 않다고 생각하지 마세요.
Hacktivists는 그림자 속에 숨어 있습니다
열화우라늄 슬러그를 국방부에 판매합니까? 그렇다면 자신이 하는 일을 아는 사람을 고용할 수 있을 만큼 충분한 돈이 있어야 합니다. 핵티비스트는 활동 목표에 부합하는 웹사이트를 정기적으로 표적으로 삼습니다.
필수 읽기
부적절한 가이드입니다. 포괄적일 것으로 예상했나요? 최소한 다음 내용도 읽어야 합니다:
- Rails 보안 가이드
- 공식 Ruby 보안 페이지
8가지 Ruby 보안 취약점(또는 p0wn'd를 얻는 8가지 쉬운 방법)
이제 보안이 얼마나 심각한지(소규모 앱의 경우에도) 동일한 내용을 다루었으니 아마도 Ruby 앱의 보안을 보장하는 방법이 궁금하실 것입니다.
우리는 8가지 취약점 클래스를 다룰 것입니다. 이는 웹 개발자가 이해하는 데 매우 중요합니다.
- 비기술적
- 교차 사이트 스크립팅(XSS)
- 교차 사이트 요청 위조(CSRF, XSRF)
- 중간자(MITM)
- SQL 주입(SQLI)
- 대량 할당 및 매개변수 주입
- 서비스 거부(DOS, DDOS)
- 플랫폼 공격(애플리케이션을 실행하는 호스트 악용)
Ruby on Rails 보안에 영향을 미칠 수 있는 비기술적 보안 악용
때로는 명백한 문제가 가장 눈에 띄기 어려울 때도 있습니다. 체크리스트에는 이러한 실수가 없을 수도 있지만 상식을 활용하는 것이 좋습니다.
당신이 할 수 있는 어리석은 짓의 수와 다양성은 끝이 없으므로 몇 가지만 지적하겠습니다.
하지 말아야 할 것:
- 이메일을 통해 일반 텍스트 비밀번호 보내기
- 어디서나 동일한 비밀번호를 사용하세요
- 쿠키를 가지고 사무실에 나타나는 사람들을 신뢰하세요
- 노트북에 민감한 데이터를 보관하세요
교차 사이트 스크립팅
악의적인 행위자가 사용자가 애플리케이션을 사용할 때 이를 이용할 수 있는 한 가지 유형의 취약점이 있습니다.
내가 나쁜 행위자라면 내 JavaScript 중 일부를 귀하의 페이지에 삽입하는 방법에 관심이 있을 수도 있습니다.
일단 그렇게 하면 활성 세션 쿠키를 훔칠 수 있고, DOM에 익스플로잇 킷을 부트스트랩할 수도 있고, 페이지에 이상한 내용을 표시하게 할 수도 있습니다. 별로 해롭지 않게 들릴 수도 있지만 악성 콘텐츠를 삽입하는 것만으로도 평판이 훼손될 수 있습니다.

교차 사이트 스크립팅을 방어하는 간단한 방법이 있습니다
크로스 사이트 스크립팅을 이용하려는 공격자를 막으려면 사용자 입력에서 모든 텍스트를 이스케이프 처리해야 JavaScript가 무해한 텍스트로 전환됩니다.
당신은 이것을 원합니다.
<script>alert('I am stealing your cookies! Ha!');</script>
당신은 이것을 원하지 않습니다:
<script>alert('I am stealing your cookies! Ha!');</script>
Cross-Site Scripting을 방어하는 것이 쉽지 않은 경우도 있습니다.
여기에 문제가 있습니다. 보안 패치 없이 실행 중인 오래된 Rails 애플리케이션이 있다면 XSS 취약점이 있을 가능성이 높습니다. Rails 초기 버전에서는 h()를 사용하여 신뢰할 수 없는 입력을 수동으로 이스케이프 처리해야 했습니다. 방법입니다.
Modern Rails 앱은 기본적으로 HTML 출력을 이스케이프 처리하므로 대부분의 XSS 취약점이 즉시 방지됩니다. 하지만 특히 레거시 코드, 타사 라이브러리 또는 동적 HTML 렌더링을 처리할 때 놀라울 정도로 실수하기 쉽습니다.
최신 버전의 Rails에서도 발에 총을 쏠 수 있습니다. html_safe에 전화 걸기 사용자 입력 시 이스케이프를 완전히 우회하므로 사용자 입력을 HTML에 삽입하고 안전하다고 표시하는 경우 기본적으로 Rails의 내장 보호 기능을 끄고 XSS를 애플리케이션에 초대하는 것입니다.
Rails 팀은 크로스 사이트 스크립팅이 특히 만연하고 피해를 주는 악용임을 인식하고 이러한 위험을 완화하는 데 필요한 정보를 확보하기 위해 보안 문서의 한 섹션을 전담했습니다. 귀하의 애플리케이션이 안전하다고 생각되더라도 읽어볼 가치가 있습니다.
교차 사이트 요청 위조
Rails 애플리케이션의 또 다른 일반적인 보안 취약점은 교차 사이트 요청 위조입니다. 예시를 살펴보겠습니다.
사용자가 비밀번호를 변경하고 싶다면 백엔드에 양식을 게시하면 됩니다. 그렇죠? 그렇다면 웹사이트에 양식이 없으면 어떻게 되나요?
요청이 계속 진행됩니다. 공격자는 신중한 공격을 통해 이 사실을 이용할 수 있습니다.
CSRF 공격 분석
제가 CSRF를 통해 귀하의 애플리케이션을 악용하는 데 관심이 있는 공격자라고 가정해 보겠습니다. 귀하가 앱에 관리자로 로그인되어 있다는 사실을 우연히 알게 되면 다른 것으로 위장한 '비밀번호 변경' 양식을 만들 수도 있습니다. 자신도 모르게 양식을 제출하고 비밀번호를 변경하게 됩니다.
그리고 앱이 POST 요청 대신 GET 요청을 사용하는 경우 상황은 더욱 악화됩니다.
나는 당신을 속일 필요조차 없습니다. 최근 방문한 페이지에 이미지 태그를 추가하기만 하면 인증된 요청이 발생하도록 할 수 있습니다.
다행스럽게도 Ruby on Rails는 대부분 내장된 CSRF 보호 기능을 제공하여 이러한 유형의 공격을 회피합니다. "어떤 이유로든 내 모든 양식에 들어가는 이상한 텍스트"로 알고 계실 것입니다.
<input type="hidden" name="authenticity_token" value="kM3jN8vBx2QzE-7wRtFpL6aYsI9uZcXmD4oHgK1rVnWe5qA0bUiJlSfTyP3hG2oC8xZ7mBvNkL4wQrEtYuI6pA" autocomplete="off" />
해독 불가능한 텍스트는 사용자의 세션 데이터에 저장되는 비밀 키입니다. 사용자가 세션의 토큰과 일치하지 않는 CSRF 토큰을 제출하면 앱에서 예외가 발생합니다. 다행히 Honeybadger는 이러한 예외를 찾아 해결하는 데 도움을 줄 수 있습니다!
하지만 여전히 망칠 수는 있습니다
물론 컨트롤러에서 겉으로는 무해해 보이는 코드 줄을 사용하여 CSRF 검사를 비활성화할 수 있습니다.
skip_before_action :verify_authenticity_token
POST 경로여야 하는 항목에 대해 GET 경로를 사용하면 문제가 발생할 수도 있습니다.
MyApp::Application.routes.draw do
match "/launch_all_the_missiles", to: "missiles#launch_all"
end
하지만 당신은 그렇게 하지 않을 거에요, 그렇죠? 그럼에도 불구하고 CSRF의 무서운 부분은 문제가 있는 앱이 반드시 앱일 필요는 없다는 것입니다. 사용자는 CSRF 익스플로잇이 포함된 다른 사이트를 방문하여 앱에 대한 요청을 트리거할 수 있습니다. Lean on Rails의 대응책은 이런 종류의 일로부터 보호하는 데 도움이 될 수 있습니다.
중간자 공격 및 패킷 스니핑
중간자 공격은 비유로 가장 잘 설명됩니다. 당신이 썩고 쓸모없는 사촌 Vinny에게 현금을 보내야 한다고 가정해 보겠습니다. 현금을 받아 봉투에 넣은 다음 그 놈의 주소를 적고 우표를 붙인 다음 봉투를 우편배달원에게 건네줄 수도 있습니다.
일주일 후, 봉투는 안에 현금이 없는 채 비니의 집에 도착합니다. 무슨 일이에요? 귀하와 의도한 수신자 사이에서 누군가가 봉투의 내용물을 조작했습니다. 이는 단순한 중간자 공격입니다.
애플리케이션 쿠키는 중간자 공격에 취약합니다
위의 이야기는 다소 어리석게 들릴 수도 있지만 사용자의 쿠키에서도 같은 일이 일어날 수 있습니다.
쿠키는 일반적으로 모든 웹 요청과 함께 전송됩니다. 공용(Wi-Fi) 네트워크를 통해 일반 텍스트로 전송되면 게임이 종료됩니다.
Firesheep과 같은 프로그램을 실행하는 악의적인 행위자는 쉽게 사용자 쿠키의 복사본을 얻고 계정을 손상시킬 수 있습니다.
SSL을 구출
쉬운 대답은 모든 것에 HTTPS를 사용하고 엄격한 전송 보안을 따르는 것입니다. 카페에 있는 사람들은 여전히 사용자의 트래픽을 볼 수 있지만 암호화되어 있습니다. 쉽지는 않지만 어떤 상황에서는 더 나은 대답은 Rails의 보안 쿠키를 사용하는 것입니다.
보안 쿠키는 Rails 3부터 기본값인 HTTPS 연결을 통해서만 브라우저로 전송됩니다.
운이 좋지 않아 그보다 오래된 Rails 버전을 실행하고 있다면 보안 쿠키가 일반 텍스트를 통해 전송될 수 있습니다. 별로 안전하지 않죠?
SQL 주입
인터넷에 있는 대부분의 웹사이트는 텍스트 조각을 서로 붙여서 SQL이라는 언어로 작은 프로그램을 만드는 방식으로 작동합니다.
그것에 대해 생각해보십시오. 이게 얼마나 미친 짓인지 아시나요?
그러나 좋든 싫든 이것이 일이 진행되는 방식입니다. 그리고 인터넷이 존재한다는 사실을 토대로 볼 때 인터넷은 합리적으로 잘 작동해야 합니다.
인터넷에 SQL을 퍼뜨리는 것의 한 가지 부작용은 해커가 작은 SQL 프로그램에 자신의 텍스트를 추가할 수 있으면 데이터가 문제에 노출될 수 있다는 것입니다.

SQL 삽입의 예
계약자가 다음과 같은 코드를 보냈다고 가정해 보세요.
Building.where("st_intersects(st_setsrid(st_makebox2d(st_point(#{params[:northeast][:lng]}, #{params[:northeast][:lat]}), st_point(#{params[:southwest][:lng]}, %{params[:southwest][:lat]})), 4326), buildings.location)")
이는 SQL 주입을 초래할 수 있는 큰 실수입니다. SQL 쿼리에서 매개변수에 직접 액세스하면 클라이언트에 자체 SQL을 강제로 실행할 수 있는 옵션이 제공됩니다. 기민한 공격자는 params[:southwest][:lat]을 만들 수 있습니다 다음과 같은 악성 SQL 코드가 포함되어 있습니다:
")), 4326), buildings.location); UPDATE users SET admin=1 WHERE id=666;--"
이제 내 사용자 ID에는 관리자 권한이 있습니다. SQL 삽입은 일반적이고 쉬운 공격이므로 사이트의 트래픽을 오랫동안 지켜본 사람이라면 누구나 결국 SQL 삽입 시도를 보게 될 것입니다.
Rails는 거의 자동으로 SQL 주입으로부터 우리를 보호합니다.
Rails는 사용자가 허용하는 한 많은 경우 SQL 주입으로부터 보호합니다. where을 사용했다면 올바르게, 매개변수는 이스케이프 처리되고 SQL 삽입 시도는 실패했을 것입니다.
where("st_intersects(st_setsrid(st_makebox2d(st_point(?, ?), st_point(?, ?)), 4326), #{table_name}.location)", box[:northeast][:lng], box[:northeast][:lat], box[:southwest][:lng], box[:southwest][:lat]).
Rails가 항상 SQL 삽입을 방지하는 것은 아닙니다.
그러나 Rails가 원시 SQL을 사용하는 곳은 많습니다. 쉽게 간과할 수 있는 장소.
예를 들어 SomeModel.sum("amount")에 있다는 사실을 알고 계셨나요? , "금액" 문자열이 이스케이프되지 않고 쿼리에 추가됩니까?
따라서 sum에 전화하는 보고서가 있는 경우 params["col"]에 직접 액세스할 수 있는 메소드 , 문제가 생겼습니다.
다음은 신뢰할 수 없는 입력을 sum 메소드에 전달한 결과를 보여주는 IRB 세션의 예입니다.
pry(main)> User.sum(%[id) AS sum_id FROM users; update users set
admin='t' where id=224;--])
(22.4ms) SELECT SUM(id) AS sum_id FROM users; update users set
admin='t' where id=224;--) AS sum_id FROM "users"
=> "0"
#pluck도 마찬가지입니다. , 기타 다양한 방법이 있습니다.
대량 할당 공격
2012년 3월 4일, 러시아 해커 Egor Homakov는 공격자가 GitHub 사용자로 가장할 수 있는 대량 할당 취약점을 공개했습니다. 상상할 수 있듯이 이것은 매우 문제가 많은 일이었습니다.
GitHub이 어떻게 해킹되었는지
아마도 여러분은 이와 같은 코드를 수백 번 작성했을 것입니다:
User.create(params[:user])
Ruby 코드의 가독성 덕분에 이 코드가 주어진 매개변수를 사용하여 사용자를 생성한다는 것을 매우 쉽게 알 수 있습니다.
Rails 3.2.3 이전에는 모든 매개변수를 의미했습니다. 달리 명시적으로 지정하지 않는 한 입력된 내용이 모델에 할당됩니다.
이로 인해 발생하는 문제는 잊어버리기 쉽다는 것입니다. 그래서 공격자가 올바른 POST 요청을 보내면 이런 일이 발생하게 되는 상황에 처하게 됩니다.
User.create({admin: true, ...})
또는 GitHub의 경우 다음과 같습니다:
PublicKey.update({user_id: "123"})
대량 할당은 쉽게 해결할 수 있습니다
최신 Rails 앱의 대량 할당 취약점에 대해 선호되는 솔루션은 이 문서의 앞부분에서 익숙해져야 할 강력한 매개변수를 사용하는 것입니다.
params 전체를 맹목적으로 전달하는 대신 User.create으로 해시 , 허용되는 속성을 명시적으로 선언합니다:
def user_params
params.require(:user).permit(:name, :email)
end
User.create(user_params)
이 간단한 선택은 업데이트하려는 필드만 허용 목록에 추가하여 모델을 보호합니다. Rails 4 이상에서는 기본 보호 기능입니다. 매우 오래된 앱(예:Rails 4 이하)을 유지 관리하고 있다면 업그레이드할 가치가 있습니다.
서비스 거부 공격
오늘 얼마나 많은 사람을 화나게 했나요? 지난 달은 어떻습니까?
서비스 거부 공격(DOS)과 분산 서비스 거부 공격(DDOS)은 infosec 커뮤니티의 분노 만화 버전입니다. 이러한 공격은 데이터를 훔치거나 맬웨어를 확산시키지 않습니다. 그들은 단지 당신을 폐쇄하고 싶어합니다. 이는 여전히 회사에 막대한 재정적 또는 평판 손상을 초래할 수 있습니다.
DDOS는 조잡하지만 효과적인 공격입니다
분산 서비스 거부 공격을 실행하려면 가장 가까운 친구 500명에게 전화를 걸어 국제앰네스티 웹사이트로 이동시킨 후 한 시간 동안 새로 고침 버튼을 계속 누르기만 하면 됩니다. 봇이 친구를 대신할 수 있습니다
이와 같은 문제가 있는 경우 다양한 해결 방법이 있습니다. Rails는 이런 종류의 공격에 특별히 집중하지는 않지만, 속도 제한을 신속하게 도입하는 데 도움이 되는 여러 가지 보석이 있습니다. Rails에는 사용할 수 있는 조절 미들웨어도 있습니다. ISP에 문의하고 강력한 속도 제한 기능을 제공하는 Cloudflare와 같은 프록시를 사용하는 것도 고려할 수 있습니다. 꽤 지루하지만 잘 알려진 문제입니다.
알고리즘 복잡성 공격
정말 멋지지 않나요?
이러한 공격은 운영 체제, 애플리케이션 스택 등의 특정 약점을 이용하여 애플리케이션 호스트에 문제를 일으킵니다. 서버 메모리를 채우거나, CPU 사용률을 높이거나, 심지어 디스크 공간을 채우는 데에도 사용할 수 있습니다.
예를 들어, 전형적인 SYN 플러드 공격은 SYN 요청을 서버에 보내는 방식으로 작동합니다. 서버는 닫히지 않은 수많은 연결을 엽니다. 연결이 충분히 열려 있으면 운영 체제의 메모리가 빨리 부족해지고 애플리케이션 자체가 충돌하게 됩니다. 이는 알고리즘 현실을 활용하여 애플리케이션을 완전히 중단시킬 수 있는 의미 있는 문제를 야기합니다.
훌륭한 구식 서버 공격
이것이 바로 우리가 해커를 생각할 때 생각하는 것입니다. 그렇죠? 버퍼 오버플로를 사용하여 Apache가 루트 사용자로 임의의 코드를 실행하게 하는 수상한 사람들이 있습니까?
그러나 많은 지루한 작업과 마찬가지로 이 작업도 자동화되었습니다. 지금 시스템 로그를 보면 봇이 SSH 로그인을 무차별 공격하는 것을 볼 수 있을 것입니다.
공격 감지 자동화
Fail2ban과 같은 널리 사용되는 도구를 사용하여 알려진 공격을 시도하는 호스트의 IP 주소를 자동으로 차단할 수 있습니다.
해야 한다고 알고 있는 일을 하세요.
운영 체제를 패치된 상태로 유지하세요. 필요하지 않은 서비스를 실행하지 마십시오. SSH에 대한 비밀번호 인증을 허용하지 않습니다. 목록은 계속됩니다. 플랫폼을 사용하는 경우 이 중 대부분이 자동으로 처리됩니다.
이제 Rails 보안을 강화할 시간입니다.
첫째, 당황하지 마십시오! Rails 보안은 원하든 원하지 않든 업무의 일부입니다. 이제 심각하게 받아들였으므로 취약점을 완화하는 데 빠른 진전을 이루게 될 것입니다. 과소평가되었지만 효과적인 승리는 여전히 보안 업데이트를 받고 있는 Rails 버전을 사용하고 있는지 확인하는 것입니다. 프레임워크가 현재 심각한 취약점을 공개한 버전에서 실행되고 있다면 세상의 모든 SQL 탈출이 당신을 보호할 수 없습니다. gem 의존성에도 마찬가지입니다.
프레임워크가 지원되면 이 가이드(및 Rails 보안 가이드!)를 사용하여 앱의 위험 노출 영역을 줄이세요. 강력한 매개변수를 사용하세요. 속도 제한기와 프록시를 구성하십시오. 메서드에 대한 HTTP 규칙을 따르고 트래픽을 SSL로 강제합니다. 이 모든 것들이 보안 문제를 겪을 가능성을 조금씩 줄여줄 것입니다.
편집자 주:이 게시물은 원래 2013년 3월에 게시되었으며 정확성을 위해 업데이트되었습니다.