Q&A

ajax로 정규식을 php에 넘겨주고 json을 받아올 때

2020.04.01 07:52
418
0
CMS/프레임워크 Rhymix 1.9
개발 언어 PHP 7.0

스크립트에서 ajax로 php에 정규식 패턴을 보내고

data: {pattern : '/^[ㄱ-힣]{3}-20\d{2}-[1|2]-.+$/i'},

php에서 얘를 받은 뒤

$pattern = $_REQUEST['pattern'];

서버단 변수 중 일부를 추린 뒤

if ( preg_match($pattern, $group->title) ) 블라블라~

$list라는 변수에 담아 json 형식으로 돌려보내는 작업을 하고 있습니다.

echo json_encode($list, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);

 

그런데 이게 잘 안 되네요.

 

다만, 다음과 같은 경우에만 작동이 됩니다.

1. ajax로 넘겨온 파라미터가 아니라 php에서 $pattern 변수에 직접 정규식을 넣는 경우

$pattern = '/^[ㄱ-힣]{3}-20\d{2}-[1|2]-.+$/i';

2. preg_match 함수에서 패턴을 그냥 스트링으로 주는 경우

if ( preg_match('/^[ㄱ-힣]{3}-20\d{2}-[1|2]-.+$/i', $group->title) ) 블라블라~

등에서만요.

 

그래서 정규식이 php로 잘 안 넘어온 건가 해서 

$pattern = $_REQUEST['pattern'];

echo json_encode($pattern, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);

으로 해보면 콘솔에서는 /^[ㄱ-힣]{3}-20\d{2}-[1|2]-.+$/i 를 잘 찍어줍니다.

 

제가 애초에 생각했던 절차에 무슨 문제가 있었던 걸까요?

윤삼 Lv. 19
아무래도 중급 초반 수준의 코딩 오타쿠인 것 같습니다.

댓글 15

  • 2020.04.01 07:58 #1370653
    어디로 넘겨 주시는지 모르겠지만 모듈로 넘겨서 받는거면 저렇게하면 안되고
    $this->add('이름',변수);
    로 해주셔야 합니다.
  • 2020.04.01 08:04 #1370665
    외부페이지로 넘겼다 받는 거여서요ㅜ
    별도의 php 파일을 따로 만들었고 거기서 변수 정리 작업 거친 뒤 스크립트로 다시 받는 작업이에요.
  • 2020.04.01 08:07 #1370675
    그렇다면 php 파일에서 헤더 선언이랑 출력시 양식만 맞으면 잘 될것 같은데요.
  • 2020.04.01 08:09 #1370685

    대강 이런 식입니다.

     

    $.ajax({
        url: './modules/member/skins/스킨폴더이름/ajax.php',
        dataType: 'json',
        data: {
            pattern : '/^[ㄱ-힣]{3}-20\d{2}-[1|2]-.+$/i'
        },
        success: function(data) {
            console.log(data);
        },
        complete: function() {
        },
        error: function(msg) {
            alert('서버와 연결이 원활하지 않습니다');
        }
    });

     

    <?php

    define('__XE__', true);
    require_once '../../../../config/config.inc.php';
    $oContext = &Context::getInstance();
    $oContext->init();

    $pattern = $_REQUEST['pattern'];

    $oMemberModel = getModel('member');
    $groups = $oMemberModel->getGroups();

    $group_list = array();
    foreach ( $groups as $group )
    {
        if ( preg_match($pattern, $group->title) )
        {
            $group_list[$group->group_srl] = $group->title;
        }
    }

    echo json_encode($group_list, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);

    unset($group_list);

    $oContext->close();

    ?>

     

  • 2020.04.01 08:10 #1370690

    외부파일로 하실거면
    header('Content-Type: application/json; charset=UTF-8');
    헤더 선언 해주시고요.
    file_get_contents("php://input");
    로 값을 가져와 주셔야 할것 같은데요.

    xe나 라이믹스에서는 json 관련으로 안되는게 있어서 저도 저렇게 했습니다.

  • 2020.04.01 08:53 #1370730
    엇, 됐습니다..(?)
    pattern : /^[ㄱ-힣]{3}-20\d{2}-[1|2]-.+$/i
    에서처럼 따옴표를 뺐더니 그냥 돼버렸어요ㅜㅜ

    아래 기진곰님 이야기처럼 따옴표 있고 없고에 따라서
    bin2hex 결과가 미묘하게 다르더라구요ㄷㄷ

    그나저나 file_get_contents("php://input"); 은 처음 접하는 건데 사용법을 잘 몰라서 해보다가 포기했어요ㅠㅠ
  • 2020.04.01 08:55 #1370734
    그렇군요 ㅎ
    제가 말씀 드린건 그냥 일반적인 php에서 사용하는 문법입니다 ㅎ
    외부 api들이 json 요청할때는 저걸 써야 작동해서요.
    해결 되셨다니 다행이군요 ㅎ
  • 2020.04.01 08:14 #1370695

    한글 인코딩이 다른 것 아닐까요?

    소스에 직접 박은 $pattern과 $_REQUEST['pattern']으로 받아온 문자열을

    var_dump나 bin2hex에 넣어서 완벽하게 동일한지 비교해 보셔야 할 것 같네요.

     

    그것과 무관하게, 사용자에게서 받은 임의의 정규식을 그대로 사용하면 보안취약점이 발생할 수 있습니다.

  • 2020.04.01 08:56 #1370738
    일단은 해결했습니다.
    bin2hex로 보니 값이 미묘하게 달랐는데 ajax에서 전송할 때 patten값에 따옴표를 뺐더니 돼버렸어요;;;
    그냥 pattern : /^[ㄱ-힣]{3}-20\d{2}-[1|2]-.+$/i 으로요.

    사실 회원그룹 리스트를 노출시키지 않으려고 계속 우회하는 방법을 쓰고 있는 건데요.
    스크립트단에서 ajax에 들어가는 정규식을 일반 사용자가 조작할 수가 있는 건가요?
  • 2020.04.01 08:59 #1370746
    스크립트는 사용자가 얼마든지 조작 가능합니다
  • 2020.04.01 09:06 #1370750
    정말 나쁜 사람들이군요!
    ... 라는 생각이 드네요ㅋㅋ

    사실 회원그룹 리스트를 동적으로 선별해서 가져오는 작업을 하는 중인데요.
    그러면서 리스트 전체는 노출하지 않으려구요.
    그러다보니 ajax 호출을 시도했습니다.

    처음엔 정규식 패턴을 php 파일에서만 사용했는데, 인터넷 주소창에 php 파일을 연결해보니까 회원그룹 리스트 결과값이 주르륵 뜨더라구요.
    그렇다고 파일 퍼미션을 바꾸면 ajax 전송 자체가 안 되고요ㅜ
    그래서 꼼수를 쓴 게 ajax로 정규식 패턴을 전송하자는 거였는데 실제로 이렇게 하니 주소창에서 php 파일 열어보면 딱 '[]'으로만 출력됩니다ㅋ

    그런데 스크립트 조작이 가능하다니 완전 실망이에요ㅠ
  • 2020.04.01 10:21 #1370791
    그래서 스크립트가 아니고 php 같은 서버단 쪽에서 처리를 해줘야 합니다.
  • 2020.04.01 11:12 #1370833

    굳이 정규식 자체를 ajax로 요청할 필요는 없겠는데요?
    사용되는 정규식을 PHP에 기록해 둔 뒤, ajax에서는 해당 정규식의 ID만 전달해주면 될 것 같네요 :)

     

    <?php
    $regexArr = [
     'All' => '/(.*)/',
     'AtoZ' => '/([a-zA-Z]*)/',
     'AtoZAndNum' => '/([a-zA-Z0-9]*)/'
    ];
    $regex = $regexArr[$_GET['regex']];

     

    이렇게 하고 AJAX에서는 regex 값을 All, AtoZ, AtoZAndNum 셋 중 하나로 지정하는... 그런 느낌..!

  • 2020.04.01 11:14 #1370841

    우와 그러면 되겠네요!

    조작 가능성도 줄고요. php파일로 인한 리스트 노출도 막을 수 있구요.
    이런 느낌 완전 좋아요!

    기억해두고 두고두고 써먹겠습니다~

  • 2020.04.01 23:19 #1371084
    제안해주신 방법으로 잘 처리했습니다.
    역시 배울 게 무궁무진하다는 생각을 하게 되네요.
    감사합니다~!