다른 사용자에게 속한 리소스에 대해 MVC / REST가 403 또는 404를 반환해야합니까?


33

리소스 기반 사이트 (예 : MVC 응용 프로그램 또는 REST 서비스)를 사용 GET하는 경우 클라이언트가 액세스 할 수없는 리소스에 클라이언트를 시도 할 때 두 가지 주요 옵션 이 있습니다.

  • 403 은 클라이언트가 인증되지 않았다고 말한다 ; 또는
  • 404 는 리소스 가 존재하지 않거나 찾을 수 없음을 나타냅니다.

일반적인 지혜와 관행은 진실, 즉 403으로 응답하는 것 같습니다. 그러나 이것이 실제로 옳은 일인지 궁금합니다.

보안 로그인 시스템은 사용자에게 로그인 실패 이유를 알려주지 않습니다. 즉, 클라이언트와 관련하여 존재하지 않는 사용자 이름과 잘못된 비밀번호 간에는 감지 할 수있는 차이가 없습니다. 이것의 목적은 사용자 ID 또는 전자 메일 주소를 검색 할 수 없게 만드는 것입니다.

A로부터 개인 정보 보호 관점, 어떤 리소스 사람이 소문을보고 리얼리티 쇼 (생존자, 나는 생각)의 수상자를 발견있어서, 내가이 사건을 생각 나게 해요 (404)를 반환하는 많은 안전 보인다 않았다 온 존재 사이트 대 수행 한 사이트 403이 일련 번호 또는 계좌 번호와 같은 민감한 정보를 제공 할 가능성이 있습니다.

404를 반환 하지 않는 강력한 이유가 있습니까? 404 정책이 다른 곳에서 부작용을 일으킬 수 있습니까? 그렇지 않다면 왜 연습이 더 일반적이지 않습니까?


1
404를 반환하지 않아야하는 강력한 이유 : 서비스가 다운되었거나 인증에 버그 / 오류가있는 경우 404가 발생하지만 문제를 진단하려는 고객 / 사용자 / 테스터 / 개발자 / 지원 담당자는 전혀 모를 수 있습니다. 오류 메시지에서 무엇이 잘못 되었습니까?
Steven Evers

@ Snorfus : 좋은 지적입니다-나는 대답에 넣었을 것입니다. Josh는 이미 좋은 반론을 추가했지만 ...
Aaronaught

명심해야 할 또 다른 측면은 다음과 같습니다. CDN 또는 어떤 종류의 캐싱이 있습니까? 당신이 그것들을 캐시하고 싶다면, 당신은 아마도 "사용자에게 권한이없는"404를 캐시하고 싶지 않을 것입니다.
pc1oad1etter

답변:


15

403 Forbidden서버 와 관련된 일반적인 오해 (및 오용) 는 서버가 요청에 대해 어떻게 생각하는지에 대한 정보를 제공하지 않습니다. 구체적으로 말하면,

나는 당신이 요구하는 것을 얻지 만, 당신이 무엇을 시도하든 요청을 처리하지 않을 것입니다. 그러니 노력을 중단하십시오.

모든 UA 또는 고객 요청이 작동 하지 않는다는 의미로 해석하고 적절하게 응답해야합니다.

이는 사용자를 대신하여 요청을 처리하는 클라이언트에 영향을 미칩니다. 사용자가 로그인하지 않았거나 잘못 입력 한 경우 요청을 처리하는 클라이언트는 "죄송하지만 아무 것도 할 수 없습니다"라고 대답해야합니다. 그것은 도착 403미래의 요청을 처리하고 정지합니다. 분명히 사용자가 실패한 후에도 개인 정보에 대한 액세스를 요청할 수있게하려면 이는 사용자에게 적대적인 행위입니다.

403대조적이다 401 Authorization Required하는 않는 서버가 당신이 올바른 자격 증명을 전달뿐만 요청을 처리 할 것을 멀리 제공합니다. 이것은 보통 사람들이들을 때 생각하는 것 403입니다.

또한 404 Page Not Found다른 사람들이 지적했듯이 "페이지를 찾을 수 없습니다"라고 말하고 서버가 향후 요청에 대해 성공 또는 실패를 주장하지 않는다는 것을 클라이언트에게 제안하도록 설계되었습니다.

으로 401하고 404, 서버는 그들이 진행하는 방법에 대한 클라이언트 또는 UA에 아무 말도하지 않습니다 그들은 다른 반응을 얻고 희망에 계속 시도 할 수 있습니다.

따라서 404모든 사람에게 보여주고 싶지는 않지만 특정 상황에서 왜 표시하지 않는지에 대해서는 아무 것도 알려주고 싶지 않은 적절한 페이지 처리 방법입니다.

물론, 이는 요청을하는 클라이언트가 사소한 RFC 플립 플랜지를 처리한다고 가정합니다. 악의적 인 충분한 클라이언트는 부수적 인 방법을 제외하고 반환 된 상태 코드를 신경 쓰지 않습니다. 알려진 다른 사용자 페이지와 비교하여 숨겨진 사용자 페이지 (또는 잠재적 인 숨겨진 사용자 페이지)임을 알 수 있습니다.

즉, 핸들러가 users/*입니다. 내가 알고있는 경우에 users/foo, users/barusers/baaz작업, 서버가 반환 401, 403또는 404위해 users/quux나는이 믿을만한 이유가, 특히, 그것을 시도하지 않을거야 의미하지 않는다 이다quux 사용자. 표준 예제 시나리오는 Facebook입니다. 내 프로필은 비공개이지만 공개 프로필에 대한 의견은 아닙니다. 악의적 인 클라이언트는 404내 프로필 페이지 로 돌아와도 내가 존재한다는 것을 알고 있습니다 .

따라서 상태 코드는 악의적 인 사용 사례가 아니라 규칙에 따라 행동하는 클라이언트를위한 것입니다. 그리고 해당 고객에게는 401또는 404요청이 가장 적합합니다.


4
401 대 403에 대한 좋은 지적. 나는 404에 대한 당신의 진술의 최종성에 동의하지 않습니다. 물론 Facebook의 예에서 이미 quux존재 한다는 것을 알고 있습니다. 그러나 특히 고객 데이터가 실제로 개인 이 아닌 비 사회적 사이트에는 항상 외부 증거가있는 것은 아닙니다 . 코가 또는 적대적 사용자는 결국 추론 할 수있을 것을 당신이 반드시 누워 것이 아니라, 어떤 당신이 거짓말 자원 에 대해 . 여기에 주목 할만한 점은 다른 발견 방법이 없다면 404 리소스를 귀찮게하지 않는다고
Aaronaught

@Aaronaught 문제는, 누군가가 서버가 무엇을기만하고 있는지 파악할 수 없거나 강화되지 않은 발견 방법이 없다는 것을 정말로 확신해야한다는 것입니다. 똑똑한 충분한 사람 알아낼 것이고, 그 시점에서 상태 코드는 의미가 없습니다.

1
사용자 프로필간에 데이터를 공유하지 않으면 똑똑한 사람 어떻게 그것을 알아낼 있는지에 대해서는 아직 확실하지 않습니다 . 누군가가 결국 "오, 404는 실제로 존재한다는 것을 의미하지만 액세스 할 수는 없다"는 것을 알게 될 것이라고 생각하지만 서버가 실제로 존재하지 않는 리소스에 대해 동일한 오류를 반환한다고 가정하면 어떻게 될까요? 존재하지 않는 리소스와 권한있는 리소스의 차이점을 알려주세요.
Aaronaught

@Aaronaught 사람이 알아야 할 유일한 것은 프로필의 URL이 존재해야한다는 것입니다. 프로파일 ID를 사용하여 의사 방식으로 증가시킬 수 있습니다 (프로파일 ID가 3333 인 사람이 프로파일 ID가 3332 인 사람을 의미하지는 않습니다). 유효한 ID의 샘플 크기. 그것을 실패하고 프로필 페이지의 URL을 생성하는 방법에 대한 정보를 유출하지 않는 완전히 강화 된 시스템조차도 항상 사회 공학이 있습니다.

8

RFC2616 에 따르면

10.4.4 403 금지

서버가 요청을 이해했지만 요청 이행을 거부하고 있습니다. 승인은 도움이되지 않으며 요청을 반복해서는 안됩니다. 요청 방법이 HEAD가 아니고 서버가 요청이 이행되지 않은 이유를 공개하기를 원한다면, 엔티티에서 거부 이유를 설명해야한다. 서버가이 정보를 클라이언트가 사용할 수 없게하려면 상태 코드 404 (찾을 수 없음)를 대신 사용할 수 있습니다.

또한 금지 된 리소스에 액세스 할 때 권한 부여가 도움이되지 않습니다 .


나는 RFC에 대해 알고 있지만 현실과 거의 유사하지는 않습니다. 첫 번째 문장을 넘어선 403의 이유를 설명하는 서버는 거의 없으며 ( "서버는 요청을 이해했지만 이행하기를 거부합니다.") 대부분의 MVC 프레임 워크 HttpUnauthorizedResult는 권한있는 리소스에 사용되는 것과 비슷한 것을 가지고 있습니다. . 나는 또한 404 대신 사용될 있다는 것을 알고 있다. 내 질문이 있는지 여부입니다 해야 사용하고, 그 결정을 내릴 때 무엇을 고려되어야한다.
Aaronaught

@Aaronaught : RFC는 404를 사용할 수 있도록 허용 하지 않으며 아무것도 인정하지 않으려면 404를 throw 하는 것이 좋습니다 .
Lie Ryan

3
괜찮아, 언제 아무것도 인정하지 않아야합니까? 아니면, 언제 해야 합니까? 이것이 바로 질문의 본질입니다.
Aaronaught

5

당신은해야합니까? .

당신은 스스로 그것을 말했다, 가능한 한 적게 배신하십시오. 시스템을 공격하고 서버가 403 코드로 응답하는 것을 확인한 경우 계속 진행하는 대신 해당 코드에 집중할 것입니다. 문이 존재하지 않는다고 선언하는 것이 더 좋다고 선언 한 다음 문을 금지한다고 선언하십시오.

404 요청을 사용하는 단점은 외부 적으로는 페이지가 존재하지 않는 것처럼 보이고 대신 존재 해야 하지만 누락 된 페이지와 비교할 때 충돌이 발생할 수 있다는 것입니다. 웹 크롤러에 대해 걱정하지 않는다면 (인증 된 시스템은 완전히 거부되어야합니다) 절대적으로 사용해야합니다. 내가 처리 한 모든 API는 똑같은 방식으로 무단 액세스를 처리하며 StackOverflow도 마찬가지 입니다. 해당 페이지가 보이지 않습니까? 난 당신이 확신 하지 그것을하지 주장에도 불구하고 존재를.

당신은 해야 자원이 경우 요청을 인정 알려진 존재하고 액세스가 거부됩니다. 로그인에 실패하면 404 메시지가 발생하지 않아야합니다. 당신은 자원 자체의 존재가 보호해야 할 때 요청을 인정합니다. 영역에 대한 액세스는 공용에 존재하지만 보안 그룹 또는 해당 영역 내의 역할은 없습니다.


404를 반환하지 않아야하는 강력한 이유 : 서비스가 다운되었거나 인증에 버그 / 오류가있는 경우 404가 발생하지만 문제를 진단하려는 고객 / 사용자 / 테스터 / 개발자 / 지원 담당자는 전혀 모를 수 있습니다. 오류 메시지에서 무엇이 잘못 되었습니까?

개발자는 로그에 액세스 할 수 있어야하며 이는 보호 된 리소스에 대한 액세스 시도를 나타냅니다. 고객 / 사용자 / 테스터는 피드백을 생성하여 개발자에게 영향을 미칩니다.

모호한 보안 ... 정말?

이것은 모호한 보안이 아닙니다. 적절한 보안 조치 외에도 모호성 사용하고 있습니다.

반면에 "404"를받는 유효한 요청은 필요하지 않은 경우 복잡성과 모호성을 추가합니다.

유효한 요청이 아니며 승인되지 않은 요청입니다. 공격자에게 실질적인 이점을 얻기 위해 작은 부분 (403 대신 404를 반환)을 변경하고 있습니다.


모호한 보안 ... 정말? 누군가가 악의적 인 의도로 귀하의 서비스를 찌르려고한다면 이미 그 서비스가 있다는 것을 알고 있습니다. 반면에 "404"를받는 유효한 요청은 필요하지 않은 경우 복잡성과 모호성을 추가합니다.
Steven Evers

4
@Snorfus : 보안프라이버시 사이에는 미묘한 차이가 있습니다 . 프라이버시는 거의 "모호하게"정의됩니다. 자원 의 존재 유무는 잠재적으로 중요한 정보이기 때문에 이는 자원 기반 시스템 의 맥락에서 특히 중요합니다. 보안 관련 논거가있을 수도 있지만, 그에 대해서는 덜 우려하고 있습니다. 나는 이 복잡성에 대한 자세한 내용을 듣고 싶어요; 당신은 당신의 초기 의견을 넘어서 자세히 설명 할 수 있습니까? (아마도 더 포괄적 인 대답으로 404 's 403에 물렸습니까?)
Aaronaught

2
@Snorfus : 또한 깊이있게 방어하는 것이 모호한 보안 과 동일하지 않다는 것을 덧붙이고 싶습니다 . 후자는 다른 보호 수단 이 없음을 의미합니다. 그러나 이미 안전한 시스템에 모호함을 추가하는 것은 다른 문제를 일으키지 않는 한 종종 좋은 일이 될 수 있습니다. 이 경우 404가 인증 코드로 생성되므로 시스템이 이미 보호 된 것입니다.
Aaronaught

@Aaronaught : 더 심층적 인 답변을 게시 할 것이지만 문제에 대해서는 자원이 비공개 인 경우 공개적으로 노출하는 이유는 무엇입니까?
Steven Evers

@Snorfus : 자원은 전 세계가 아닌 클라이언트 또는 그룹 에게 비공개 입니다.
Aaronaught

0

그것은 실제로 403 상태 코드에 의해 제공된 정보에 달려 있습니다. GET /myresource/{id}자원이 없을 때 404로 응답하는 API 엔드 포인트가있는 경우, 자원이 존재하지만 현재 사용자에게 권한이 부여되지 않은 경우 엔드 포인트가 리턴 한 상태 코드는 id매개 변수 의 예측 가능성 및 양에 따라 달라집니다 그 자체로 포함 된 정보.

  • id전자 메일 주소 나 은행 계좌 번호와 같은 개인 필드 인 경우 항상 404 뒤에 숨겨져 있어야합니다. 전자 메일 주소의 경우 스팸봇이 웹 사이트에 등록 된 유효한 전자 메일 주소 목록을 컴파일하지 못하게 할 수 있습니다.
  • 경우 id공공 이름이다 (당신의 웹 사이트의 포럼 페이지를 검색하여 같은)이 정보에 대한 액세스를 얻을 수있는 다른 방법이 있습니다, 귀찮게하지 않습니다.
  • 경우 id불투명하지만, 예측 가능한 식별자 (예를 들어, 자동 증가 정수), 당신은 그가 다른 방법으로 얻을 수 있다는 공격자에 대한 정보를 포기하지 않습니다. 제 생각에는 403 상태 코드를 반환하는 것이 안전합니다.
  • 경우 id불투명, (임의의 GUID 같은) 예측할 수없는 식별자로, 질문은 더 미묘하다. 개인적으로 403 상태 코드를 반환하는 데 아무런 문제가 없다고 생각합니다. 이 정보는이 ID를 사용하여 API에 다른 결함이있는 엔드 포인트가있는 경우에만 악용 될 수 있지만 실제 결함은 다른 엔드 포인트입니다.

어떤 경우 든 유감스럽게 생각하는 것보다 안전하다고 생각하고 상황에 관계없이 정보를 숨길 수 있지만 실제로는 이러한 유형의 동작에 의존하여 모든 형태의 보안 을 제공 할 수는 없습니다 . 반면에 기밀성 을 보장 할 수 있습니다 (또는 다른 사람들이 말한 것처럼 개인 정보 보호).

보안 메커니즘은 공격자에게 속도 충돌이되어서는 안되며, 그렇지 않으면 평범한 쓸모가 없습니다. 이 경우 다른 기능을 올바르게 사용하지 못할 수도 있습니다 (크롤러, 웹 응용 프로그램 방화벽은 사용자를 차단하기 위해 비정상적인 403 상태 코드를 찾습니다 ...).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.