복붙노트

ajax 함수에 의해 호출 된 파일에 대한 직접 액세스 방지

PHP

ajax 함수에 의해 호출 된 파일에 대한 직접 액세스 방지

나는 아약스에서 php 코드를 다음과 같이 호출한다.

ajaxRequest.open("GET", "func.php" + queryString, true);

그것은 요청이기 때문에 누구나 단순히 헤더를 검사하여 그것을 볼 수 있습니다. 전달되는 데이터는 민감하지 않지만 잠재적으로 매개 변수 이름을 얻는 것이 쉽기 때문에 남용 될 수 있습니다.

http : //mysite/func.php에 대한 직접 액세스를 차단하고 내 아약스 페이지 액세스를 허용 하시겠습니까?

또한 여기에 게시 된 솔루션을 시도했지만 그게 나를 위해 작동하지 않습니다 - 항상 '직접 액세스하지 premitted'메시지를 얻을.

해결법

  1. ==============================

    1.대부분의 Ajax 요청 / 프레임 워크는 Ajax v Non-ajax 요청을 필터링하는 데 사용할 수있는이 특정 헤더를 설정해야한다. 많은 프로젝트에서 응답 유형 (json / html)을 결정하는 데 도움이됩니다.

    대부분의 Ajax 요청 / 프레임 워크는 Ajax v Non-ajax 요청을 필터링하는 데 사용할 수있는이 특정 헤더를 설정해야한다. 많은 프로젝트에서 응답 유형 (json / html)을 결정하는 데 도움이됩니다.

    if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) )
    {
        // allow access....
    } else {
        // ignore....
    } 
    

    편집하다: 자바 스크립트 코드에서 다음과 같이 자신의 Ajax 요청에 직접 추가 할 수있다.

    var xhrobj = new XMLHttpRequest();
    xhrobj.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 
    
  2. ==============================

    2.내가 사용하는 것은 : PHP 세션 + 요청할 때마다 전송되는 해쉬. 이 해시는 서버 측에서 일부 알고리즘을 사용하여 생성됩니다.

    내가 사용하는 것은 : PHP 세션 + 요청할 때마다 전송되는 해쉬. 이 해시는 서버 측에서 일부 알고리즘을 사용하여 생성됩니다.

  3. ==============================

    3.음 ... 세션 시작시 _SESSION에 저장할 수있는 일회용 비밀번호를 생성하고 AJAX 호출에 매개 변수를 추가하여 재전송 할 수 있습니다 (보안 문자와 비슷한 것). 해당 세션에서만 유효합니다.

    음 ... 세션 시작시 _SESSION에 저장할 수있는 일회용 비밀번호를 생성하고 AJAX 호출에 매개 변수를 추가하여 재전송 할 수 있습니다 (보안 문자와 비슷한 것). 해당 세션에서만 유효합니다.

    이렇게하면 자동 공격으로부터 보호받을 수 있지만 사이트에 액세스 할 수있는 사람은 수동으로이 작업을 수행 할 수 있지만 더 복잡한 작업을 수행하는 기반이 될 수 있습니다.

  4. ==============================

    4.왜 아무도 그 파일을 직접 방문 할 수 없다는 확신을 가지고있는 이유에 대해 질문 할 것입니다. 첫 번째 행동은 사람들이이 페이지를 직접 방문하여이 사건을 중심으로 행동 할 수 있다고 가정해야합니다. 여전히이 파일에 대한 액세스를 닫으려는 경우 $ _SERVER의 출처를 확인하기가 어려우며 헤더 값을 스푸핑 할 수 있으므로 $ _SERVER 변수를 신뢰할 수 없다는 것을 알아야합니다. 일부 테스트에서 나는 그 헤더 ($ _SERVER [ 'HTTP_X_REQUESTED_WITH'] & $ _SERVER [ 'HTTP_X_REQUESTED_WITH'])도 신뢰할 수 없다는 것을 알았습니다.

    왜 아무도 그 파일을 직접 방문 할 수 없다는 확신을 가지고있는 이유에 대해 질문 할 것입니다. 첫 번째 행동은 사람들이이 페이지를 직접 방문하여이 사건을 중심으로 행동 할 수 있다고 가정해야합니다. 여전히이 파일에 대한 액세스를 닫으려는 경우 $ _SERVER의 출처를 확인하기가 어려우며 헤더 값을 스푸핑 할 수 있으므로 $ _SERVER 변수를 신뢰할 수 없다는 것을 알아야합니다. 일부 테스트에서 나는 그 헤더 ($ _SERVER [ 'HTTP_X_REQUESTED_WITH'] & $ _SERVER [ 'HTTP_X_REQUESTED_WITH'])도 신뢰할 수 없다는 것을 알았습니다.

  5. ==============================

    5.헤더를 살펴 보라고 제안한이 스레드의 모든 사람은 어떤면에서든 또는 다른 방식 으로든 잘못되었습니다. 요청에 포함 된 내용 (HTTP_REFERER, HTTP_X_REQUESTED_WITH)은 공유 된 비밀을 포함하여 완전히 무능력이 아닌 공격자가 스푸핑 할 수 있습니다 [1].

    헤더를 살펴 보라고 제안한이 스레드의 모든 사람은 어떤면에서든 또는 다른 방식 으로든 잘못되었습니다. 요청에 포함 된 내용 (HTTP_REFERER, HTTP_X_REQUESTED_WITH)은 공유 된 비밀을 포함하여 완전히 무능력이 아닌 공격자가 스푸핑 할 수 있습니다 [1].

    사람들이 사이트에 대한 HTTP 요청을 못하게 할 수는 없습니다. 사용자가 세션 쿠키를 사용하여 사이트의 민감한 부분에 대한 요청을하기 전에 인증을 받아야합니다. 사용자가 인증되지 않은 요청을하는 경우 바로 멈추고 HTTP 403을 제공합니다.

    귀하의 예제는 GET 요청을하므로 요청의 리소스 요구 사항에 관심이 있다고 생각합니다 [2]. .htaccess 규칙에서 HTTP_REFERER 또는 HTTP_X_REQUESTED_WITH 헤더에 대한 단순성 검사를 통해 가짜 요청 (robots.txt를 수신하지 않는 멍청한 검색 크롤러)에 대해 새 프로세스가 생성되는 것을 막을 수 있지만 공격자가 가짜 그것들은 PHP 프로세스가 인증되지 않은 요청을 가능한 한 빨리 끝내기를 원할 것입니다.

    [1] 클라이언트 / 서버 응용 프로그램의 근본적인 문제 중 하나입니다. 그것이 작동하지 않는 이유는 다음과 같습니다. 클라이언트 앱이 서버에 대해 자신을 인증 할 수있는 방법 (비밀 암호 또는 다른 방법)이 있다고 가정 해보십시오. 앱이 필요로하는 정보는 앱에서 반드시 액세스 할 수 있어야합니다 (비밀번호는 어딘가에 숨겨져 있습니다.). 하지만 사용자의 컴퓨터에서 실행되기 때문에이 정보에 액세스 할 수 있습니다. 필요한 것은 소스 또는 바이너리 또는 앱과 서버 간의 네트워크 트래픽을 살펴 보는 것입니다. 앱이 인증하는 메커니즘 및 복제. 어쩌면 그들은 심지어 그것을 복사 할 것입니다. 어쩌면 앱을 무겁게 해줄 수있는 똑똑한 해킹을 만들 수 있습니다 (앱에 가짜 사용자 입력을 보낼 수는 있습니다). 하지만 아무리 많은 정보가 필요하다해도 앱이 가지고있는 것을 막을 수있는 방법이 없습니다.

    [2] 잘 설계된 응용 프로그램의 GET 요청에는 부작용이 없으므로 아무도 서버를 만들 수 없습니다. 인증 된 사용자 만 POST 요청을 호출 할 수 있도록 POST 요청은 항상 세션 + CSRF 토큰으로 인증되어야합니다. 누군가가 이것을 공격하면, 그들은 당신과 가진 계정을 가지고 있고 그 계정을 닫고 싶다는 것을 의미합니다.

  6. ==============================

    6.ajax에 의해 호출되는 PHP 파일의 맨 위에 다음 코드를 추가하십시오. 아약스 요청을 실행하지만 브라우저에서 직접 호출되는 경우 "죽습니다".

    ajax에 의해 호출되는 PHP 파일의 맨 위에 다음 코드를 추가하십시오. 아약스 요청을 실행하지만 브라우저에서 직접 호출되는 경우 "죽습니다".

    define('AJAX_REQUEST', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
    if(!AJAX_REQUEST) {die();}
    

    개인적으로, 나는 "die ()"이후 아무 것도 출력하지 않기로 선택했다. 나가 "if"또는 "왜"이 페이지가 보호되는지와 같은 힌트를주기보다는 오히려 "침입자"에게 다만 빈 페이지를 보여주는 것을 선호 한 ㄴ다는 것을 의미하는.

  7. ==============================

    7.나는 세 가지를 만드는 체크 함수를 준비하면서이 문제를 해결했다.

    나는 세 가지를 만드는 체크 함수를 준비하면서이 문제를 해결했다.

    세 가지가 모두 성공하면 아약스가 호출 한 PHP 파일을 볼 수 있습니다. 단 하나만 실패하면 성공하지 못합니다.

    포인트 1과 2는 이미 설명 했으므로 브리지 파일 솔루션은 다음과 같이 작동합니다.

    브리지 파일

    다음과 같은 시나리오를 생각해보십시오 :

    A.php B.php를 통한 A.php 페이지 호출 및 B.php에 대한 직접 액세스 금지

    이렇게하면 아빠 페이지 A에서 생성 된 아약스 호출을 통해서만 B 페이지에 액세스 할 수 있습니다. pageB.php의 키는 pageA.php에서만 주어진다.

  8. ==============================

    8.귀하의 설명을 토대로 본인은 철저히 만연한 학대를 막으려 고 노력하고 있지만 견고한 해결책은 필요하지 않다고 가정합니다.

    귀하의 설명을 토대로 본인은 철저히 만연한 학대를 막으려 고 노력하고 있지만 견고한 해결책은 필요하지 않다고 가정합니다.

    그래서 쿠키를 사용하는 것이 좋습니다.

    AJAX를 사용하는 페이지에서 setcookie ()를 실행하고 func.php의 올바른 값을 보려면 $ _COOKIE를 확인하십시오. 이렇게하면 func.php를 호출 한 사람이 최근에 귀하의 사이트를 방문했다는 합리적인 확신을 얻을 수 있습니다.

    더 좋아지기를 원하면 쿠키가 위조되거나 남용되지 않는다는 확신을 위해 고유 한 세션 ID를 설정하고 확인할 수 있습니다.

  9. ==============================

    9.이렇게하는 데는 아무런 의미가 없습니다. 실제 보안을 추가하지는 않습니다.

    이렇게하는 데는 아무런 의미가 없습니다. 실제 보안을 추가하지는 않습니다.

    HTTP_X_REQUESTED_WITH와 같은 요청이 Ajax를 통해 만들어지고 있음을 나타내는 모든 헤더는 클라이언트 측에서 위조 될 수 있습니다.

    Ajax가 중요한 데이터를 제공하거나 중요한 작업에 대한 액세스를 허용하는 경우 로그인 시스템과 같은 적절한 보안을 추가해야합니다.

  10. ==============================

    10.나는 이것을 시험해 보았다.

    나는 이것을 시험해 보았다.

    1) 메인 PHP 파일에서 (어떤 아약스 요청을 보내는) $ _SESSION [ 'random_value'] = 'code_that_creates_something_random'과 같은 임의의 값으로 세션을 생성합니다. 그 세션은 $ .post 위에 만들어야합니다.

    2) 다음

    $.post( "process_request.php", 
    { 
    input_data:$(':input').serializeArray(),
    random_value_to_check:'<?php echo htmlspecialchars( $_SESSION['random value'], ENT_QUOTES, "UTF-8"); ?>' 
    }, function(result_of_processing) {
    //do something with result (if necessary)
    });
    

    3) 및 process_request.php

    if( isset($_POST['random_value_to_check']) and 
    trim($_POST['random_value_to_check']) == trim($_SESSION['random value']) ){
    //do what necessary
    }
    

    세션을 정의하기 전에 세션 값과 함께 숨겨진 입력 필드를 입력 한 다음 숨겨진 입력 필드의 값을 ajax와 함께 보냅니다. 그런 다음 숨겨진 입력 필드가 필요 없으므로 그 필드없이 보낼 수 있다고 결정했습니다.

  11. ==============================

    11.Edoardo 솔루션의 단순화 된 버전이 있습니다.

    Edoardo 솔루션의 단순화 된 버전이 있습니다.

    또한 여러 요청을 제한하기 위해 스크립트 B로 즉시 [토큰] 파일을 삭제하는 것이 좋습니다.

    나는 쉽게 스푸핑 될 수 있기 때문에 HTTP 헤더 검사가 필요하다고 생각하지 않는다.

  12. ==============================

    12.나는 많은 제안을 시도했지만 아무도 문제를 해결하지 못했습니다. 마지막으로 PHP 대상 파일의 매개 변수를 보호하고 PHP 파일에 대한 직접 액세스를 제한하는 유일한 방법이었습니다. ** PHP 파일을 뿌리고 제한 by.htaccess를 설정하면 기본 HTML 페이지에서 Ajax 연결이 실패합니다.

    나는 많은 제안을 시도했지만 아무도 문제를 해결하지 못했습니다. 마지막으로 PHP 대상 파일의 매개 변수를 보호하고 PHP 파일에 대한 직접 액세스를 제한하는 유일한 방법이었습니다. ** PHP 파일을 뿌리고 제한 by.htaccess를 설정하면 기본 HTML 페이지에서 Ajax 연결이 실패합니다.

  13. from https://stackoverflow.com/questions/1756591/prevent-direct-access-to-file-called-by-ajax-function by cc-by-sa and MIT license