Programing

$ _REQUEST []를 사용하는 데 무엇이 문제입니까?

crosscheck 2020. 7. 21. 07:53
반응형

$ _REQUEST []를 사용하는 데 무엇이 문제입니까?


$_REQUEST변수 를 사용하지 말라고 말하는 많은 게시물을 보았습니다 . 나는 보통 그렇지 않지만 때로는 편리합니다. 무슨 일이야?


입력 $_GET$_POST결합 하여 입력하는 데 아무런 문제가 없습니다 . 사실 그것은 당신이 거의 항상하고 싶은 것입니다 :

  • 일반적으로 GET을 통해 제출되는 일반 dem 등원 (imdempotent) 요청의 경우, 원하는 데이터 양이 URL에 맞지 않을 수 있으므로 실제 문제 대신 POST 요청으로 변경 될 수 있습니다.

  • 실제 효과가있는 요청의 경우 POST 메소드에 의해 요청이 제출되었는지 확인해야합니다. 그러나 그렇게하는 방법 은 GET $_SERVER['REQUEST_METHOD']$_POST대해 비어 있지 않고 명시 적 으로 확인 하는 것입니다. 어쨌든 메소드가 POST인 경우 URL에서 일부 쿼리 매개 변수를 계속 사용할 수 있습니다.

아니요, 문제 $_REQUEST는 GET 및 POST 매개 변수를 병합하는 것과 관련 이 없습니다. 또한 기본적으로 포함되어 $_COOKIE있습니다. 쿠키는 실제로 양식 제출 매개 변수와 전혀 다릅니다. 쿠키를 거의 같은 것으로 취급하고 싶지는 않습니다.

실수로 양식 매개 변수 중 하나와 동일한 이름으로 쿠키 세트를 사이트에 가져 오면 해당 매개 변수에 의존하는 양식이 예상 매개 변수를 대체하는 쿠키 값으로 인해 제대로 작동하지 않습니다. 동일한 사이트에 여러 앱이있는 경우 매우 쉽게 수행 할 수 있으며 오래된 쿠키를 사용하는 사용자가 몇 명인 경우 더 이상 사용하지 않고 양식을 깨는 방식으로 디버깅하지 못할 수 있습니다. -다른 사람이 재생할 수 있습니다.

PHP 5.3 request_order 설정을 사용하면 이 동작을 훨씬 합리적인 GP(no C) 순서로 변경할 수 있습니다 . 이것이 불가능한 경우 개인적으로 피하고 GET + POST 배열을 결합 해야하는 경우 수동으로 생성하십시오.$_REQUEST


PHP Internals 에 관한 뉴스 그룹 게시물을 살펴보고 주제에 대한 흥미로운 토론을 찾았습니다. 초기 스레드는 뭔가 다른,하지만 스테판 ESSER, A (아니라면하여 발언 PHP는 세계에서) 보안 전문가는 몇 게시물 $ _REQUEST를 사용하는 보안 관련쪽으로 논의를 돌았 다.

PHP 내부에서 Stefan Esser 인용

$ _REQUEST는 PHP에서 가장 큰 디자인 취약점 중 하나입니다. $ _REQUEST를 사용하는 모든 응용 프로그램은 지연된 크로스 사이트 요청 위조 문제에 가장 취약합니다. (이것은 기본적으로 (age)라는 쿠키가 존재하면 항상 GET / POST 내용을 덮어 쓰므로 원하지 않는 요청이 수행됨을 의미합니다)

과에서 나중에 같은 글타래에 댓글을 올리

누군가가 GET, POST를 위조 할 수 있다는 사실이 아닙니다. 쿠키 변수. COOKIE가 GET 및 POST 데이터를 REQUEST로 겹쳐 쓰게됩니다.

따라서 브라우저에 action = logout이라는 쿠키를 감염시킬 수 있으며 REQUEST [action]이 영구적으로 로그 아웃되므로 쿠키를 수동으로 삭제할 때까지 해당 날짜부터 더 이상 응용 프로그램을 사용할 수 없습니다.

그리고 COOKIE로 당신을 감염시키는 것은 매우 간단합니다 ...
a) 하위 도메인의 모든 응용 프로그램에서 XSS 취약점을 사용할 수 있습니다.
b) * .co.uk 또는 * .co.kr에 쿠키를 설정하려고 시도한 적이 단일 도메인이 있습니까?
c) 다른 도메인 간 방법 ...

그리고 이것이 문제가 아니라고 생각되면 fe를 * .co.kr 쿠키로 설정하여 여러 PHP 버전으로 화이트 페이지를 반환하는 간단한 가능성이 있음을 알 수 있습니다. 상상해보십시오 : * .co.kr의 모든 PHP 페이지를 죽이는 단일 쿠키

그리고 + PHPSESSID = illegal 변수에 * .co.kr에 유효한 쿠키에 잘못된 세션 ID를 설정하면 PHP 세션을 사용하여 한국의 모든 PHP 응용 프로그램을 여전히 DOS 할 수 있습니다 ...

토론은 계속해서 몇 차례 더 게시되며 흥미 롭습니다.


보시다시피, $ _REQUEST의 주요 문제는 $ _GET 및 $ _POST의 데이터가 아니라 $ _COOKIE의 데이터가 아닙니다. 목록의 다른 사람들은 $ _REQUEST가 채워지는 순서 (예 : $ _COOKIE를 먼저 채우는 순서)를 변경하도록 제안했지만, 이로 인해 세션 처리와 같은 다른 많은 잠재적 인 문제가 발생할 수 있습니다 .

$ _REQUEST 전역에서 $ _COOKIES를 완전히 생략하여 다른 배열로 덮어 쓰지 않도록 할 수 있습니다 (실제로 variable_order ini 설정PHP 매뉴얼 과 같이 표준 내용의 조합으로 제한 할 수 있습니다) 우리에게 말해:

variable_order EGPCS (환경, 가져 오기, 게시, 쿠키 및 서버) 변수 구문 분석의 순서를 설정합니다. 예를 들어 variables_order를 "SP"로 설정하면 PHP는 $ _SERVER 및 $ _POST 슈퍼 글로벌을 생성하지만 $ _ENV, $ _GET 및 $ _COOKIE는 생성하지 않습니다. ""로 설정하면 슈퍼 글로벌이 설정되지 않습니다.

그러나 PHP에서 자체 전역에서 Environment, Get, Post, Cookie 및 Server에 액세스 할 수 있고 하나의 공격 경로가 적기 때문에 $ _REQUEST를 함께 사용하지 않는 것도 고려할 수 있습니다. 여전히이 데이터를 삭제해야하지만 걱정할 것이 더 적습니다.


이제 왜 $ _REQUEST가 존재하고 왜 제거되지 않는지 궁금 할 것입니다. 이것은 PHP 내부에서도 요청되었습니다. Rasmus Lerdorf를 인용하여 $ _REQUEST가 왜 존재합니까? PHP 내부에서

이와 같은 것들을 더 많이 제거할수록 사람들이 새롭고 더 빠르고 안전한 PHP 버전으로 빨리 옮기기가 더 어려워집니다. 이로 인해 몇 가지 "못생긴"레거시 기능보다 모든 사람이 좌절감을 느끼게됩니다. 적절한 기술적 이유, 성능 또는 보안이있는 경우이를 자세히 검토해야합니다. 이 경우, 우리가 살펴 봐야 할 것은 $ _REQUEST를 제거해야하는지가 아니라 쿠키 데이터를 제거해야하는지 여부입니다. 내 구성을 포함한 많은 구성이 이미 그렇게하고 있으며 $ _REQUEST에 쿠키를 포함시키지 않는 강력한 보안상의 이유가 있습니다. 대부분의 사람들은 GET 또는 POST를 의미하기 위해 $ _REQUEST를 사용합니다. 쿠키에도 쿠키가 포함될 수 있다는 사실을 알지 못하고 나쁜 사람들이 쿠키 삽입 트릭을 수행하고 순진한 응용 프로그램을 손상시킬 수 있습니다.

어쨌든, 약간의 빛이 비추기를 바랍니다.


$_REQUEST모든 종류의 요청 (GET, POST 등)을 나타냅니다. 이것은 때로는 유용하지만 일반적으로 정확한 방법 ($ _GET, $ _POST 등)을 지정하는 것이 좋습니다.


$_REQUEST 일반적으로 복잡한 복잡성 데이터 변환이 종종 SQL로 선언 된 대신 응용 프로그램 코드에서 수행되는 것과 같은 이유로 유해한 것으로 간주됩니다.

따라서 $_REQUEST어느 곳에서나 사용하는 경향이있는 경우 POST를 통해 할 수있는 GET을 통해 모든 작업을 수행 할 수 있습니다. 즉, <img>전자 상거래 모듈에 로그인 한 사용자가 자동으로 제품을 구매하도록하는 (악의적 인) 사이트에 태그를 설정 하거나 위험한 행동이나 민감한 정보의 계시를 초래할 수있는 링크를 클릭하게 할 수 있습니다.

However, this is because of a novice, or at least inexperienced, PHP programmer making simple mistakes. First off, know when data of what type is appropriate. For example, I have a web service which can return responses in URLEncoding, XML or JSON. The application decides how to format the response by checking the HTTP_ACCEPT header, but can be coerced into one specifically by sending the format parameter.

When checking the content of the format parameter, it could be sent via querystring or a postdata, depending on a multitude of factors, not the least of which being whether or not the calling applications wants "&format=json" mixed in with its request. In this case, $_REQUEST is very convenient because it saves me having to type something like this:

$format = isset($_POST['format']) ? $_POST['format'] 
    : (isset($_GET['format']) ? $_GET['format'] : null);

I'm not going to ramble on much further, but suffice to say that $_REQUEST usage is not dissuaded because it is inherently dangerous - it's just another tool that does exactly what is asked of it, whether you understand those implications or not - it is the poor, lazy or uninformed decision of a poor, lazy or inexperienced programmer that causes this problem.

How to use $_REQUEST safely


  1. Know your data: You should have some expectation as to what kind of data you will get, so sanitize it accordingly. Data for a database? addslashes() or *_escape_string(). Going to show it back to the user? htmlentities() or htmlspecialchars(). Expecting numerical data? is_numeric() or ctype_digit(). In fact, filter_input() and its related functions are designed to do nothing but check and sanitize data. Use these tools, always.
  2. Don't access user-supplied superglobals data directly. Make a habit of sanitizing your data, every time, and move your data to clean variables, even if it's just $post_clean. Alternatively, you can just clean directly in the superglobals, but the reason I advocate using a separate variable is because doing so makes it easy to spot vulnerabilities in code, as anything pointing directly to a superglobal and not its sanitized equivalent is considered a dangerous error.
  3. Know where you data should be coming from. Referencing my example from above, it is perfectly reasonable to allow the response format variable to be sent via GET or POST. I also allow the "action" variable to be sent via either method. However, the actions themselves have very specific requirements as to which HTTP Verb is acceptable. Functions, for example, that make changes to data used by the service may only be sent via POST. Requests for certain types of non- or low-privilege data (such as dynamically generated map images) may be served in response to requests from either method.

In conclusion, remember this simple rule:

SECURITY IS WHAT YOU MAKE IT, PEOPLE!

EDIT:

I strongly recommend bobince's advice: if you can, set the request_order parameter in php.ini to "GP"; that is, no cookie component. There is almost no rational reasoning for this in 98%+ of cases, as cookie data should almost never be considered comparable to the querystring or to postdata.

P.S., Anecdote!

I knew a programmer who thought of $_REQUEST a place to simply store data that was accessible in a superglobal way. Important usernames and passwords, paths to files, you name it and it was stored in $_REQUEST. He was a bit surprised (although not comically so, unfortunately) when I told him how that variable behaves. Needless to say, that practice has been deposed.


GET requests should be idempotent and POST requests are generally not. This means that data in $_GET and $_POST should generally be used in different ways.

If your application is using data from $_REQUEST, it will behave the same for both GET and POST requests, which violates the idempotence of GET.


It's vague. You don't really know how the data got to you since it carries post, get, and cookie data. I don't necessarily think that is always a bad thing, unless you need to know or restrict the method of delivery.


I actually like using it. It gives you the flexibility to use GET or POST which can come in handy for things like search forms where most of the time data is POSTed, but sometimes you'll want to say link to a particular search, so you can use GET parameters instead.

Also, if you look at many other languages (ASP.NET for example) they make no distinction between GET and POST variables at all.

ETA:

I've never used REQUEST to get COOKIE values, but I think Kyle Butt makes a great point in the comments on this post about that. It is NOT a good idea to use REQUEST for getting COOKIE values. I believe he is right that there is some real potential for cross-site request forgery if you do that.

Also, the order in which stuff gets loaded into REQUEST is controlled by configuration parameters in php.ini (variables_order and request_order). So, if you have the same variable passed in via both POST and GET, which one actually gets into REQUEST depends on those ini settings. This could affect portability if you depend on a particular order and those settings are configured differently than you expect them to be.


It's important to understand when to use POST, when to use GET and when to use a cookie. With $_REQUEST, the value you're looking at could have come from any of them. If you expect to get the value from a POST or a GET or from a COOKIE, it's more informative to someone reading your code to use the specific variable instead of $_REQUEST.

Someone else pointed out also that you don't want to all POST's or cookies to be overridden by GETs because there are different cross-site rules for all of them, for instance, if you return ajax data while using $_REQUEST, you are vulnerable to a cross site script attack.


The only time using $_REQUEST is not a bad idea is with GET.

  • If you use it to load POST values, you risk cross-site request forgeries
  • If you use it to load cookie values, you again risk cross-site request forgeries

And even with GET, $_GET is shorter to type than $_REQUEST ;)


I might be used only if you want to retrieve the current url or hostname, but for actually parsing data from that URL such as parmeters using the & symbol it's probably not a good idea. In general, you don't want to use a vague description of what you are trying to do. If you need to be specific that's where $_REQUEST is bad, if you don't need to be specific then feel free to use it. I would think.


If you know what data you want, you should explicitly ask for it. IMO, GET and POST are two different animals and I can't think of a good reason why you would ever need to mix post data and query strings. If anyone has one, I'd be interested.

It can be convenient to use $_REQUEST when your scripts might respond to either GET or POST in the same manner. I would argue though that this should be an extremely rare case, and in most instances two separate functions to handle two separate concepts, or at the very least checking the method and selecting the correct variables, is preferred. Program flow is usually a lot easier to follow when it's not necessary to cross reference where the variables might be coming from. Be kind to the person who has to maintain your code in 6 months time. It might be you.

In addition to the security problems and WTFs caused by cookies and environment variables in the REQUEST variable (don't get me started on GLOBAL), consider what might happen in the future if PHP started natively supporting other methods such as PUT and DELETE. While it's extremely unlikely that these would be merged into the REQUEST superglobal, it's possible they could be included as on option in the variable_order setting. So you really have no idea whatsoever what REQUEST holds, and what is taking precedence, particularly if your code is deployed on a third-party server.

Is POST safer than GET? Not really. It's better to use GET where practical because it's easier to see in your logs how your application is being exploited when it gets attacked. POST is better for operations that affect domain state because spiders generally don't follow them, and predictive fetching mechanisms won't delete all your content when you log into your CMS. However, the question was not about the merits of GET vs POST, it was about how the receiver should treat the incoming data and why it's bad to merge it, so this is really just a BTW.


I think there is no problem with $_REQUEST, but we must be careful when using it since it is a collection of variables from 3 sources (GPC).

I guess $_REQUEST is still available to make old programs compatible with new php versions, but if we start new projects (including new libraries) I think we should not use $_REQUEST anymore to make the programs clearer. We should even consider deleting uses of $_REQUEST and replacing it with a wrapper function to make the program lighter, especially in processing large submitted text data, since $_REQUEST contains copies of $_POST.

// delete $_REQUEST when program execute, the program would be lighter 
// when large text submitted
unset($_REQUEST);

// wrapper function to get request var
function GetRequest($key, $default = null, $source = '') 
{
  if ($source == 'get') {
    if (isset($_GET[$key])) { 
      return $_GET[$key]; 
    } else { 
      return $default; 
    }
  } else if ($source == 'post') {
    if (isset($_POST[$key])) { 
      return $_POST[$key]; 
    } else { 
      return $default; 
    }
  } else if ($source == 'cookie') {
    if (isset($_COOKIE[$key])) { 
      return $_COOKIE[$key]; 
    } else { 
      return $default; 
    }
  } else {
    // no source specified, then find in GPC
    if (isset($_GET[$key])) {
      return $_GET[$key];     
    } else if (isset($_POST[$key])) {
      return $_POST[$key]; 
    } else if (isset($_COOKIE[$key])) {
      return $_COOKIE[$key]; 
    } else {
      return $default; 
    } 
  }
}

Darren Cook: "Since php 5.3 the default php.ini says only GET and POST data are put into $_REQUEST. See php.net/request_order I just stumbled on this backwards-compatibility break when expecting cookie data to be in $_REQUEST and wondering why it wasn't working!"

Wow... just had some of my scripts stop working because of an upgrade to PHP 5.3. Did the same thing: assume that cookies would be set when using the $_REQUEST variable. With the upgrade exactly that stopped working.

I now call cookie values separately using $_COOKIE["Cookie_name"]...


The central problem is that it contains cookies, as others have said.

In PHP 7 you can do this:

$request = array_merge($_GET ?? [], $_POST ?? []);

This avoids the cookie problem and gives you at worst an empty array and at best a merger of $_GET and $_POST with the latter taking precedence. If you are not too bothered with allowing URL injection of parameters through the query string, it's quite convenient.


It's very insecure. Also it's awkward since you don't know if you're getting a POST or a GET, or another request. You really should know the difference between them when designing your applications. GET is very insecure as it's passed in the URL and is not suitable for almost anything besides page navigation. POST, while not safe by itself either, provides one level of safetey.

참고URL : https://stackoverflow.com/questions/2142497/whats-wrong-with-using-request

반응형