답변:
차이의 리디렉션 문제 POST
, PUT
그리고 DELETE
요청과 어떤 서버의 기대 (사용자 에이전트 행동이다 RFC 2616
) :
참고 : RFC 1945 및 RFC 2068은 클라이언트가 경로 재 지정된 요청에 대한 메소드를 변경할 수 없도록 지정합니다. 그러나 대부분의 기존 사용자 에이전트 구현은 원래 요청 방법에 관계없이 Location 필드 값에 대해 GET을 수행하여 302를 303 응답 인 것처럼 처리합니다. 클라이언트에 어떤 종류의 반응이 예상되는지 명확하게 나타내려는 서버에 대해 상태 코드 303 및 307이 추가되었습니다.
또한 30x 리디렉션 코드 에 대한 Wikipedia 기사를 읽으십시오 .
307은 사용자 에이전트 가 302 응답을 수신하고 위치 응답 헤더에 GET 요청을 보내는 POST 요청을 취하는 사실상의 행동으로 채택 되었기 때문에 발생했습니다 .
이는 잘못된 동작입니다 . 303 만으로 POST가 GET으로 바뀌어야합니다. 원래 POST 요청이 302를 반환 한 경우 새 URL을 요청할 때 사용자 에이전트는 POST 메소드를 사용하지 않아야합니다.
(307)는 서버가이 방법 변경해야하는 사용자 에이전트을 명확하게 할 수 있도록 도입 하지 위치 응답 헤더를 다음과 같은 경우 클라이언트가 될.
302
잘못 처리 합니다. 크롬 30, IE10. 사실상 잘못된 구현 이되었습니다 . 너무 많은 웹 사이트 문제가 실수로 302를 발행하기 때문에 변경 될 수 없습니다. 실제로 ASP.net MVC 는 브라우저가 잘못 처리한다는 사실 에 따라 302를 잘못 발행 합니다.
303
에도 도입 307
되어 HTTP 1.0 사용자 에이전트와의 하위 호환성을 허용 하기 때문 입니다. 물론 실제 질문은 지금도 여전히 HTTP 1.0 사용자 에이전트를 처리해야 하는가입니다.
Response.RedirectSeeOther
), 클라이언트가 1.1이 아닌 경우 (예를 들어 GET /foo.html
, GET /foo.html HTTP/1.0
) 다음 유산을 발행 302
.
/register-form.html
했습니다 signup-form.html
. /register.php
이제로드 (GET) /success.html
합니다./register.php
를 다시 실행하도록 지시합니다 /signup.php
.RFC 7231 (2014 년부터) 은 읽기 쉽고 지나치게 장황하지 않습니다. 정확한 답을 알고 싶다면 권장되는 내용입니다. 다른 답변은 1999 년부터 RFC 2616을 사용하지만 아무것도 변경되지 않았습니다.
RFC 7238 은 308 상태를 지정합니다. 실험적인 것으로 간주되지만 2016 년 모든 주요 브라우저 에서 이미 지원되었습니다 .
302에 대해 예상 : 리디렉션은 NEW_URL에서 동일한 요청 방법 POST를 사용합니다.
CLIENT POST OLD_URL -> SERVER 302 NEW_URL -> CLIENT POST NEW_URL
302, 303에 대한 실제 : NEW_URL의 POST에서 GET으로 경로 변경 요청 방법 리디렉션
CLIENT POST OLD_URL -> SERVER 302 NEW_URL -> CLIENT GET NEW_URL (redirect uses GET)
CLIENT POST OLD_URL -> SERVER 303 NEW_URL -> CLIENT GET NEW_URL (redirect uses GET)
307에 대한 실제 : 리디렉션은 NEW_URL에서 동일한 요청 방법 POST를 사용합니다.
CLIENT POST OLD_URL -> SERVER 307 NEW_URL -> CLIENT POST NEW_URL
302는 서버에 의해 생성되는 임시 리디렉션이고, 307은 브라우저에 의해 생성 된 내부 리디렉션 응답입니다. 내부 리디렉션은 리디렉션이 내부적으로 브라우저에 의해 자동으로 수행됨을 의미합니다. 기본적으로 브라우저는 요청을하기 전에 입력 한 URL을 http에서 https로 변경하여 요청을하기 전에 인터넷에 연결되지 않습니다. 브라우저가 URL을 https로 변경할지 여부는 브라우저에 사전 설치된 hsts 사전로드 목록에 따라 다릅니다. chrome : // net-internals / # hsts에있는 자체 브라우저의 hsts 사전로드 목록에 도메인을 입력하여 https를 지원하는 모든 사이트를 목록에 추가 할 수도 있습니다. 소유자가 웹 사이트 도메인을 하나 더 추가 할 수 있습니다. 양식을 작성하여 목록을 미리로드 https://hstspreload.org/ 하십시오.모든 사용자를 위해 브라우저에 사전 설치되어 있기 때문에 특히 자신을 위해 할 수 있다고 언급합니다.
예를 들어 설명해 드리겠습니다 :
https 만 지원
하는 http://www.pentesteracademy.com에 대한 요청을 했고 사이트 소유자가 등록하지 않았으므로 브라우저의 hsts 사전로드 목록에 해당 도메인이 없습니다 사전 설치된 hsts 사전로드 목록과 함께 제공됩니다.
사이트의 안전하지 않은 버전에 대한 GET 요청은 보안 버전으로 리디렉션됩니다 (위 이미지에서 이에 대한 응답으로 해당 위치의 http 헤더 참조).
이제 Chrome 브라우저의 개인 사전로드 목록을 수정하는 chrome : // net-internals / # hsts의 hsts 도메인 양식에 도메인을 추가하여 자체 브라우저 사전로드 목록에 사이트를 추가합니다. STS 옵션이 있습니다.
hsts 사전로드 목록에 추가 한 후 동일한 웹 사이트에 대한 요청 및 응답을 살펴 보겠습니다.
응답 헤더에서 내부 리디렉션 307을 볼 수 있습니다. 실제로이 응답은 서버가 아닌 브라우저에서 생성됩니다.
또한 HSTS 사전로드 목록은 302 리디렉션이 mitm 공격을 받기 쉽기 때문에 사용자가 안전하지 않은 사이트 버전에 도달하는 것을 방지 할 수 있습니다.
리디렉션에 대해 더 이해하는 데 도움이 되었기를 바랍니다.
원래는 302
| Response | What browsers should do |
|------------------------|---------------------------|
| 302 Found | Redo request with new url |
아이디어는 다음과 같습니다.
GET
특정 위치에서 작업을 수행 한 GET
경우 새 URL로 다시POST
특정 위치에서 작업을 수행 한 POST
경우 새 URL로 다시PUT
특정 위치에서 작업을 수행 한 PUT
경우 새 URL로 다시DELETE
특정 위치에서 작업을 수행 한 DELETE
경우 새 URL로 다시불행히도 모든 브라우저가 잘못했습니다. 를 받고 때 302
, 그들은 항상로 전환 할 GET
오히려 사용하여 요청을 재 시도하기보다, 새로운 URL에 같은 동사를 ( 예를 들어 , POST
) :
그것은되었다 사실상 잘못.
모든 브라우저가 302
잘못되었습니다. 그래서 303
및 307
작성되었습니다.
| 응답 | 브라우저가해야 할 일 | 실제로 브라우저가하는 일 | | ------------------------ | ------------------------ --- | --------------------------- | | 302 발견 | 새 URL로 요청을 다시 실행 | 새로운 URL로 GET | | 303 기타 | 새로운 URL로 GET | 새로운 URL로 GET | | 307 임시 리디렉션 | 새 URL로 요청을 다시 실행 | 새 URL로 요청을 다시 실행 |
5 가지 종류의 리디렉션 :
╔═══════════╤════════════════════════════════════════════════╗
║ │ Switch to GET? ║
║ Temporary │ No │ Yes ║
╠═══════════╪════════════════════════╪═══════════════════════╣
║ No │ 308 Permanent Redirect │ 301 Moved Permanently ║
╟───────────┼────────────────────────┼───────────────────────╢
║ Yes │ 307 Temporary Redirect │ 303 See Other ║
║ │ 302 Found (intended) │ 302 Found (actual) ║
╚═══════════╧════════════════════════╧═══════════════════════╝
또는
| Response | Switch to get? | Temporary? |
|--------------------------|----------------|------------|
| 301 Moved Permanently | No | No |
| 302 Found (intended) | No | Yes |
| 302 Found (actual) | Yes | Yes |
| 303 See Other | Yes | Yes |
| 307 Temporary Redirect | No | Yes |
| 308 Permanent Redirect | No | No |
또한 서버 관리자의 경우 307 리디렉션을 사용하는 경우 브라우저가 사용자에게 프롬프트를 표시 할 수 있습니다.
예를 들어, Firefox 및 Opera는 사용자에게 리디렉션 권한을 요청하는 반면 Chrome, IE 및 Safari는 리디렉션을 투명하게 수행합니다.
* 방탄 SSL 및 TLS 당 (192 페이지)
일부 사용 사례에서 공격자에 의해 307 리디렉션이 악용되어 피해자의 자격 증명을 알 수 있습니다.
추가 정보는 OAuth 2.0 에 대한 포괄적 인 공식 보안 분석의 3.1 섹션 에서 찾을 수 있습니다 .
위 논문의 저자는 다음을 제안합니다.
고치다. OAuth 표준의 현재 문구와 달리 리디렉션의 정확한 방법은 구현 세부 정보가 아니라 OAuth 보안에 필수적입니다. HTTP 표준 ( RFC 7231 )에서는 HTTP POST 요청의 본문을 삭제하기 위해 303 리디렉션 만 명확하게 정의됩니다. 가장 일반적으로 사용되는 302를 포함한 다른 모든 HTTP 리디렉션 상태 코드는 POST 요청과 양식 데이터를 유지하는 옵션을 브라우저에 남겨 둡니다. 실제로 브라우저는 일반적으로 GET 요청에 다시 쓰기 때문에 307 리디렉션을 제외하고 양식 데이터를 삭제합니다. 따라서 OAuth 표준에서는이 문제를 해결하려면 위에서 언급 한 단계에 대해 303 리디렉션이 필요합니다.