카테고리 없다

프론트엔드 앱을 위한 13 가지 보안 팁(한글번역)

maravilloso 2023. 5. 8. 21:13
728x90
앱을 잠그고 악성 행위자에게 덜 취약하게 만들기

React.js, Angular, Vue.js 또는 단순히 프론트엔드 개발자인 경우 코드가 해커에게 유혹적인 문이 될 수 있습니다.

프론트엔드 개발자로서 우리는 대부분 성능, SEO, UI/UX에 신경을 쓰지만, 보안은 종종 무시됩니다.

큰 프레임워크가 어떻게 크로스 사이트 스크립팅(XSS) 공격에 취약해지게 되는지 놀라울 수 있습니다. React의 dangerouslySetInnerHTML이나 Angular의 bypassSecurityTrust API와 같은 위험한 작업 이름이 있습니다.

프론트엔드가 이제 보안 측면에서 백엔드 또는 DevOps와 동등한 책임을 갖는다는 것을 명심해야 합니다. 프론트엔드에서 수천 가지 악의적인 공격이 발생할 수 있습니다.

가장 일반적인 것들을 이해해봅시다. 이들은 이러한 유형의 공격의 상당 부분을 다룰 것입니다.

 


1. 제한 없는 파일 업로드
이 공격은 악성 파일이 서버에 업로드되어 시스템을 공격하기 위해 실행되는 것입니다. 공격에는 파일 시스템이나 데이터베이스의 과부하, 시스템 전체 인수, 클라이언트 측 공격, 백엔드 시스템으로의 공격 전달 또는 간단한 변조가 포함될 수 있습니다.

2. 클릭 재킹
이 공격은 사용자가 사이트에 속하지 않는 웹 페이지 또는 요소를 클릭하도록 속이는 공격입니다. 이 공격으로 사용자가 실수로 인증 정보 또는 민감한 정보를 제공하거나 악성 소프트웨어를 다운로드하고, 악성 웹 페이지를 방문하거나, 온라인에서 제품을 구입하거나, 돈을 이체할 수 있습니다.

3. XSS 공격
이 공격은 악성 스크립트가 브라우저 측 스크립트 형태로 웹 페이지에 주입되는 것입니다. 웹 사이트의 결함으로 이러한 공격이 성공하고 널리 퍼질 수 있습니다.

4. SQL 인젝션
이 공격은 입력 필드를 통해 데이터베이스를 파괴하기 위해 SQL 문에 악성 코드를 주입하는 것입니다.

5. 서비스 거부 공격(DoS 공격)
이 공격은 서버에 트래픽을 폭탄으로 몰아 서버 또는 그 자원을 의도한 사용자에게 이용할 수 없게 만드는 것입니다.

6. 중간자 공격 또는 세션 하이재킹
이 공격은 클라이언트와 서버 간의 통신이 도청되어 비밀번호, 계좌 번호 또는 개인 정보를 훔치는 것입니다.


공격자는 항상 프론트엔드에 있는 취약점을 찾아 서버에 도달하고 작업을 수행하려고 시도합니다. 이 글에서는 프론트엔드 코딩 시 항상 염두에 두어야 할 일반적인 모범 사례 몇 가지를 살펴보겠습니다.


1. 엄격한 사용자 입력 (첫 번째 공격 포인트)


사용자 입력은 항상 엄격한 성격을 가져야 하며, SQL 인젝션, 클릭재킹 등의 취약점을 피할 수 있습니다. 따라서 사용자 입력을 백엔드로 보내기 전에 검증하거나 정화하는 것이 중요합니다.

데이터 정화는 화이트리스트를 사용하여 입력 데이터를 이스케이프하거나 문맥상 위험한 문자를 제거하거나 대체함으로써 수행할 수 있습니다.

그러나 모든 가능성에 대해 정화와 인코딩이 쉬운 작업이 아님을 인지하고 있으므로 다음 오픈 소스 라이브러리를 사용할 수 있습니다:

DOMPurify. 가장 간단하게 사용할 수 있으며 사용자의 입력을 정화하는 하나의 방법이 있습니다. 규칙을 사용자 정의할 수 있는 옵션이 있으며 HTML5, SVG, MathML을 지원합니다.
secure-filters. Salesforce 라이브러리로 HTML, JavaScript, 인라인 CSS 스타일 및 기타 컨텍스트를 정화하는 메서드를 제공합니다. 예를 들어, CSS 또는 JavaScript를 생성하는 데 사용자 입력을 활용하려는 경우 특히 유용합니다.
파일 업로드의 경우 항상 파일 유형을 확인하고 파일 필터 기능을 사용하며 특정 파일 유형만 업로드하도록 허용합니다. 자세한 내용은 여기를 참조하세요.



2. 숨겨진 필드 또는 브라우저 메모리에 저장된 데이터 주의


페이지에서 민감한 데이터를 숨기기 위해 input type="hidden"을 추가하거나 브라우저의 localStorage, sessionStorage, 쿠키에 추가하고 안전하다고 생각한다면 다시 생각해야 합니다.

브라우저에 추가된 모든 것은 공격자가 쉽게 액세스할 수 있습니다. 공격자는 개발 도구를 열어 메모리에 있는 모든 변수를 변경할 수 있습니다. 그리고 localStorage, sessionStorage 및 쿠키 값에 따라 인증 페이지를 숨겼다면 어떨까요?

ZapProxy와 같은 도구와 브라우저의 검사 도구가 있어 공격자가 스크립트를 삽입할 방법을 찾으면 해당 값을 공격자에게 노출시킬 수 있으며 그런 다음 공격을 계속할 수 있습니다.

따라서 type="hidden" 사용을 피하고 가능한 한브라우저의 인 메모리 저장소에 키, 인증 토큰 등을 저장하지 마십시오. 대신 서버 측에서 보안을 더 강화하여 인증 및 권한 부여를 처리하십시오.


3. 강력한 콘텐츠 보안 정책 (CSP) 사용하기


서버가 보내는 모든 것을 믿지 마세요. 항상 특정 신뢰할 수 있는 콘텐츠만 브라우저에서 실행되거나 더 많은 리소스를 렌더링할 수 있도록 하는 강력한 Content-Security-Policy HTTP 헤더를 정의하세요.

허용된 소스 목록인 화이트리스트를 사용하는 것이 좋은 관행입니다. 이제 공격자가 스크립트를 주입하더라도 스크립트는 화이트리스트와 일치하지 않아 실행되지 않습니다.

예를 들어:

content-security-policy: script-src 'self' https://apis.xyz.com

여기서 애플리케이션은 apis.xyz.com 및 자체(셀프)에서 오는 스크립트만 신뢰합니다. 나머지 소스에 대해서는 콘솔에 오류가 발생합니다.

참고: 강력한 콘텐츠 보안 정책은 인라인 스크립트 실행 문제를 해결하지 않으므로, XSS 공격은 여전히 유효합니다.

MDN 웹 사이트에서 CSP 지시문의 전체 목록을 읽을 수 있습니다.


4. XSS 보호 모드 활성화하기


어떻게든 공격자가 사용자 입력에서 악성 코드를 주입하면 "X-XSS-Protection": "1; mode=block" 헤더를 제공하여 브라우저가 응답을 차단하도록 지시할 수 있습니다.

대부분의 현대 브라우저는 기본적으로 XSS 보호 모드가 활성화되어 있지만, X-XSS-Protection 헤더를 포함하는 것이 여전히 권장됩니다. 이는 CSP 헤더를 지원하지 않는 이전 버전의 브라우저에 대한 보안을 개선하는 데 도움이 됩니다.


5. 전형적인 XSS 실수 피하기


XSS 공격은 대개 DOM API의 innerHTML로 추적됩니다. 예를 들면:

document.querySelector('.tagline').innerHTML = nameFromQueryString
위의 코드로 공격자가 악성 코드를 주입할 수 있습니다.

HTML 출력을 전혀 생성하지 않도록 innerHTML 대신 textContent를 사용하는 것을 고려하세요. HTML을 생성하지 않으면 JavaScript를 삽입할 수 없습니다. 즉, 내용은 볼 수 있지만 아무 일도 발생하지 않습니다.

구글러들이 만든 DOM 기반 크로스 사이트 스크립팅 공격을 모두 방지하려는 새로운 신뢰할 수 있는 유형(Trusted Types) 명세를 주의 깊게 살펴보세요.

React.js의 경우, dangerouslySetInnerHTML은 명확하고 주의를 요하는데 innerHTML과 비슷한 영향을 가질 수 있습니다.

참고: 사용자 입력에 기반한 innerHTML 값을 설정하지 말고 가능한 한 innerHTML 대신 textContent를 사용하세요.

또한, HTTP 응답 헤더인 Content-Type과 X-Content-Type-Options는 의도된 동작과 함께 올바르게 설정되어야 합니다. 예를 들어, JSON 데이터는 text/HTML로 인코딩되어서는 안되며, 실수로 실행되는 것을 방지해야 합니다.


6. iframe 임베딩 비활성화


iframe을 비활성화하면 클릭재킹 공격으로부터 보호할 수 있습니다. 프레임 내에서 웹사이트 렌더링을 금지하는 요청에서 "X-Frame-Options": "DENY" 헤더를 항상 사용해야 합니다.

또한, iframe에 페이지를 포함시킬 수 있는 부모를 더욱 통제할 수 있는 frame-ancestors CSP 지시문을 사용할 수 있습니다.


7. 오류를 일반적으로 유지


"비밀번호가 틀렸습니다"와 같은 오류는 사용자에게 도움이 되지만 공격자에게도 도움이 됩니다. 이러한 오류로부터 정보를 파악하여 다음 조치를 계획할 수 있습니다.

계정, 이메일 및 개인 식별 정보와 관련하여 "로그인 정보가 잘못되었습니다"와 같은 모호한 오류를 사용해야 합니다.


8. 캡차 사용


공개 접근 가능한 엔드포인트(로그인, 회원 가입, 연락처)에 캡차를 사용하세요. 캡차는 인간과 봇을 구별하기 위한 컴퓨터 프로그램이나 시스템으로, DoS(서비스 거부) 공격을 막는 데 도움이 됩니다.


9. 항상 Referrer-Policy 설정


앵커 태그나 웹사이트를 벗어나는 링크를 사용할 때 헤더 정책 "Referrer-Policy": "no-referrer"를 사용하거나 앵커 태그의 경우 rel = noopener 또는 noreferrer를 설정하세요.

이러한 헤더와 rel을 설정하지 않으면 대상 웹사이트가 세션 토큰과 데이터베이스 ID와 같은 데이터를 얻을 수 있습니다.


10. 제한된 브라우저 기능 및 API 사용


CSP에서 제한된 도메인만 웹사이트에 연결할 수 있듯이, 브라우저 기능 및 API에도 동일한 원칙이 적용됩니다. Feature-Policy 헤더를 추가하여 특정 기능 및 API에 대한 액세스를 거부할 수 있습니다. 자세한 내용은 이곳에서 확인하세요.

Tip: 사용하지 않는 모든 기능에 대해 none을 설정하세요.


11. 정기적으로 종속성 검사


npm audit을 정기적으로 실행하여 취약한 패키지 목록을 받고 보안 문제를 피하기 위해 업그레이드하세요.

GitHub에서는 취약한 종속성을 표시합니다. 또한 Snyk를 사용하여 소스 코드를 자동으로 확인하고 버전을 올리기 위한 풀 리퀘스트를 엽니다.


12. 애플리케이션을 분리하세요


백엔드에서는 마이크로서비스 아키텍처를 사용하여 모놀리식 애플리케이션을 더 작은 독립된 구성 요소로 분할하고 각각 개별적으로 실행합니다.

이와 같은 원칙이 프론트엔드에도 적용될 수 있습니다. 예를 들어, 애플리케이션을 공용, 인증된, 관리자 부분으로 나누고 각각 별도의 서브도메인에 호스팅할 수 있습니다. 예를 들면 https://public.example.com, https://users.example.com 및 https://admin.example.com 와 같습니다.

이렇게 하면 클라이언트 측 취약점이 줄어들 것입니다.

참고: 적절한 구획화는 애플리케이션의 공용 부분에서 XSS 취약성이 발생할 경우 사용자 정보가 자동으로 침해되는 것을 방지합니다.


13. 서드파티 서비스 사용을 피하세요


Google Analytics, Google Tag Manager, Intercom, Mixpanel과 같은 서드파티 서비스를 사용하는 한 줄의 코드가 웹 앱을 취약하게 만들 수 있습니다. 이러한 서드파티 서비스가 손상될 경우를 생각해보세요.

강력한 CSP 정책을 갖는 것이 중요합니다. 대부분의 서드파티 서비스는 정의된 CSP 지시문을 가지고 있으므로 항상 추가하세요.

또한, 가능한 경우 스크립트 태그를 추가할 때 integrity 속성을 포함하십시오. 서브리소스 무결성 기능은 스크립트의 암호화 해시를 확인하고 변조되지 않았는지 확인할 수 있습니다.

<script src= "https://example.com/example-framework.js" integrity= "sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/ux..." crossorigin= "anonymous" ></script>

자동 완성 필드를 신중하게 고려하세요

브라우저의 자동 완성에 저장된 개인 식별 정보는 사용자와 공격자 모두에게 편리할 수 있습니다.

공격자들은 이메일 주소를 추출하여 추적 식별자를 작성하는 데 사용하는 브라우저의 내장 자동 완성을 악용하는 서드파티 스크립트를 추가합니다. 이를 통해 사용자의 브라우징 기록 프로필을 작성하고 이를 악당들에게 팔 수 있습니다. 이에 대한 자세한 내용은 여기서 확인하세요.

우리 중 많은 사람들은 브라우저의 자동 완성이 어떤 정보를 저장하고 있는지조차 인식하지 못하고 있습니다.

팁: 민감한 데이터에 대한 자동 완성 양식을 사용하지 않도록 설정하세요.

 

땡큐

 

원문 : https://betterprogramming.pub/frontend-app-security-439797f57892