programing

PHP 및 jQuery를 사용하여 보안 AJAX 요청을 보내는 방법

javamemo 2023. 3. 21. 21:24
반응형

PHP 및 jQuery를 사용하여 보안 AJAX 요청을 보내는 방법

문제

그래서 저는 지금까지 MySQL 데이터베이스 내에 처리 및 저장될 서버에 데이터를 전송하는 다양한 AJAX 접근 방식을 실험해 왔습니다.

가 AJAX에 히트한 api.phpPHP의 준비 에 MySQL 가 있는 도 PDO에 의해 api.php입니다.제 질문은 클라이언트에서 서버로 데이터를 전송할 때 데이터를 안전하게 보호하는 방법에 관한 것입니다.

어프로치

현재 (아래에 기재한 로그인 예시의 경우)를 사용하고 있습니다.

  • 도메인에서 실행 중인 SSL 증명서/HTTPS.
  • 요구는 처음부터이 없기 때문에 는합니다(양쪽 모두 AJAX에서 됨).login.php ★★★★★★★★★★★★★★★★★」api.php★★★★★★★★★★★★★★★★★★★★★」
  • api.php기능을 액세스할 때 사용합니다.
  • PHP 할 때 했습니다.api.php.
  • 합니다.api.php(서양속담, 친구속담)

질문

마지막으로 질문하겠습니다.

  1. PHP 페이지에 데이터를 송신해 리다이렉트 하는 것이 아니라, 비동기 HTTP(Ajax) 요구를 사용하는 것이 안전한가(이렇게 하면 유저 익스피리언스가 향상됩니다).
  2. 사용자가 보낸 데이터가 변경되지 않았는지 확인하려면 어떻게 해야 합니까?
  3. 사용자의 데이터를 보호하기 위해 충분한 조치를 취하고 있습니까?그렇지 않은 경우, 그 밖에 무엇을 할 수 있습니까?

예시

사이트 데이터 처리와 전송에 대한 접근 방식이 사람마다 다르다는 것을 알고 있습니다.또, 어떠한 조작을 실시해도, 시스템의 주변에는 설명할 수 없는 취약성이나 방법이 있는 경우가 있기 때문에, 100%의 보호를 받을 수 없다는 것도 이해하고 있습니다.아래의 특정 코드에 대한 비판보다는 데이터를 안전하게 전송하는 일반적인 접근법에 대한 피드백이나 개선점을 찾고 있습니다.하지만 건설적인 답변은 환영입니다.시간을 내어 읽어주셔서 감사합니다.

function loginUser() {
    var process = "loginUser";
    var data = $("form").serializeArray();
    data[1].value = SHA512(data[1].value); // sha then encrypt on api.php page 
    data = JSON.stringify(data);

    $("#loginButton").html('<i class="fa fa-spinner fa-pulse fa-lg fa-fw"></i> Login');
    $.ajax({
        type: "POST",
        url: "api.php",
        data: {"process": process, "data": data},
        success: function(data) {
            if (data.response.state == "success") {
                // if api.php returns success, redirect to homepage
            } else {
                // if api.php returns failure, display error
            }  
        },
        error: function(jqXHR, textStatus, errorThrown, data) {
            // error handling
        },
        dataType: "json"
    });
}

1. ORIGIN 헤더를 확인합니다.

OWASP에 의해 지정되어 있는 바와 같이, 이것은 충분하지 않지만 권장되는 것은 다음과 같이 권장됩니다.

자신의 브라우저에서 헤더를 스푸핑하는 것은 간단한 일이지만, 일반적으로 CSRF 공격에서는 XSS의 취약성을 제외하고는 스푸핑이 불가능합니다.따라서 헤더를 체크하는 것은 CSRF 방어의 합리적인 첫 번째 단계이지만 항상 존재하는 것은 아니기 때문에 일반적으로 그 자체로는 충분한 방어로 간주되지 않습니다.

그리고 Mozilla:

오리진 헤더는 JSON 데이터 도난 및 CSRF 공격에 도움이 되는 것으로 간주됩니다.오리진에서 제공하는 정보(상황별 요청 작성 정보)는 요청의 신뢰성에 대한 힌트를 웹 서버에 제공해야 합니다. [...]

HTTP_ORIGIN은 : 라고 쓸 수 있습니다

header('Content-Type: application/json');

if (isset($_SERVER['HTTP_ORIGIN'])) {
    $address = 'http://' . $_SERVER['SERVER_NAME'];
    if (strpos($address, $_SERVER['HTTP_ORIGIN']) !== 0) {
        exit(json_encode([
            'error' => 'Invalid Origin header: ' . $_SERVER['HTTP_ORIGIN']
        ]));
    }
} else {
    exit(json_encode(['error' => 'No Origin header']));
}

1. (bis) REFERER 헤더를 확인한다.

OWASP에서 다시:

오리진 헤더가 없는 경우 Referer 헤더의 호스트명이 사이트의 오리진과 일치하는지 확인합니다.referer 체크는 임베디드 네트워크 디바이스에서 CSRF를 방지하기 위해 일반적으로 사용되는 방법입니다.이는 사용자별 상태가 필요하지 않기 때문입니다.이 CSRF 경감 방법은 인증되지 않은 요구에도 일반적으로 사용됩니다.[...]

HTTP_REFERER에서는, 「PHP」를 사용하는 것도 꽤 .$_SERVER['HTTP_REFERER']위의 코드를 업데이트하기만 하면 됩니다.


example.com 또는 api.example.com만 체크하지 말고 https://example.com 전체를 체크하지 마십시오.왜냐고요? api.example.com.hacker.com과 같은 원본에서 이 수표를 스푸핑할 수 있기 때문입니다.


2. CSRF 토큰 생성

PHP에 대한 명확한 답변이 제공되었습니다.간단히 다음과 같습니다.

  1. 토큰을 생성합니다.

    session_start();
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    
  2. 메타(Github 등)를 통해 생성된 뷰에 추가합니다.

    <meta name="csrf-token" content="<?= $_SESSION['csrf_token'] ?>">
    
  3. 다음 토큰을 포함하도록 jQuery ajax 호출을 설정합니다.

    $.ajaxSetup({
        headers : {
            'CsrfToken': $('meta[name="csrf-token"]').attr('content')
        }
    });
    
  4. 서버측에서 AJAX 요구를 확인합니다.

    session_start();
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    
    header('Content-Type: application/json');
    
    $headers = apache_request_headers();
    if (isset($headers['CsrfToken'])) {
        if ($headers['CsrfToken'] !== $_SESSION['csrf_token']) {
            exit(json_encode(['error' => 'Wrong CSRF token.']));
        }
    } else {
        exit(json_encode(['error' => 'No CSRF token.']));
    }
    

대부분의 PHP 프레임워크는 자체 CSRF 구현을 가지고 있으며, 이는 거의 같은 원리에 기초하고 있습니다.


3. 유효성 검사 사용자 입력을 삭제합니다.

espace 입력은 항상 필터링하고 검증해야 합니다.


4. 서버 보호


5. 사용자 입력을 절대 신뢰하지 않는다

@blue112가 말했듯이 이것은 가장 기본적인 보안 원칙 중 하나입니다.

여기에 이미지 설명 입력

간단한 답변: 고객 측을 보호할 수 없습니다.

장황한 답변:

  • AJAX를 사용하는 것은 예를 들어 폼을 사용하여 데이터를 게시하는 것만큼 안전합니다.
  • HTTPS를 사용하면 중간자(man-in-the-middle)가 사용자 데이터를 볼 수 없으므로 사용자가 보낸 실제 데이터는 안전합니다.

브라우저가 실제로 클라이언트 측에서 실행되는 Javascript 코드임을 증명하기 위해 아무것도 할 수 없습니다.그리고 가장 간단한 방법은 NEVER TRUST User INPUT입니다.

즉, 시작과 같이 세션, 환율 제한, 데이터 검증, fail2ban(일정 횟수 실패 후 클라이언트 IP 금지), 로그 모니터링 등을 사용하여 서버 측을 보호합니다.

가장 좋은 방법은 여전히 서버 측의 보안을 유지하는 것입니다.또한 사이트에 로그인한 사용자라면 메타 태그의 csrf 토큰을 체크하고 스크립트를 서버에 위조할 수 있습니다.따라서 서버측 검증이 확실합니다.

언급URL : https://stackoverflow.com/questions/37912937/how-to-send-secure-ajax-requests-with-php-and-jquery

반응형