질문/조언팁/리소스 공유

DB에 직접 sql 쿼리문을 PHP에서 작성하여 사용되는 서드파티들이 몇가지 있습니다.

 

그런 서드파티들이 아무래도 라이믹스 2.0에서 에러가 나는것 같습니다.

 

왜냐하면 라이믹스2.0에서는 $oDB 오브젝트 디비 인스턴스클래스에 Prefix 항목을 제거했기 때문입니다.

 

라이믹스 초기에는 XML쿼리를 제거하자는 큰 포부를 안고 진행해왔지만 포기했습니다.

 

XML쿼리가 보안이 탄탄하기에 이를 버리지말고 수정하기로 선택했기 때문입니다.

 

주소파라미터에 값을 받아와서 바로 디비쿼리에 넣는 형태

 

EX

 

도메인/index.php?act=member~~~&member_srl=4

 

$sql = "SELECT member_srl FROM {$oDB->prefix}member WHERE member_srl = {Context::get('member_srl')}";

 

이런 형태의 코드는 되도록이면 XE에서는 쓰지 마세요 (라이믹스포함). 위에서 넘어오는 member_srl 값을 아무리 잘 채크한다 해도 어떻게든 인젝션 어택이 들어가길 마련입니다. (이런 쿼리들 때문에 주소의 제일 마지막에 4대신에 0=0같은걸 넣으면 잘못하면 참사도 일어납니다.)

 

그리고 그외 비개발자로 활동하시는 분들께서 난감하시게 최근에 2.0 올라오면서 DB쪽에 변경이 많아서 뭔가 작동이 안되는 자료들이 좀 있는 것 같습니다.

 

위에서 언급했다 시피 라이믹스 2.0 부터는 prefix값이 누락되기 때문에 이 값을 추가해야합니다.

 

위의 

 

$sql = "SELECT member_srl FROM {$oDB->prefix}member WHERE member_srl = {Context::get('member_srl')}";

$sql = "SELECT member_srl FROM member WHERE member_srl = {Context::get('member_srl')}";

으로 수정하시고

그 아랫줄에

$sql = $oDB->addPrefixes($sql);

를 붙여주세요.

 

이렇게하면 {$oDB->prefix} 를 알아서 잘 붙여줍니다.

 

그리고 개발자라면 XML쿼리 쓰세요! 두번쓰세요.

글쓴이 람보

profile
람보입니다.

Email : [email protected]

포트폴리오 : https://bjrambo.com/portfolio
작업의뢰 신청 : https://bjrambo.com/request
  • profile

    공식적으로 지원되지 않는 내부 함수를 사용해서
    커스텀 쿼리를 실행하던 자료들이 이번에 다 뽀록나는군요.

    참고로 저런 쿼리를 꼭 실행해야 할 경우
    라이믹스 2.0에서 공!식!권!장!하는 방법은 아래와 같습니다.

    $oDB = DB::getInstance();
    $member_srl = intval(Context::get('member_srl'));
    $query = $oDB->prepare('SELECT member_srl FROM member WHERE member_srl = ?');
    $query->execute(array($member_srl));
    $result = $query->fetchAll();

    Prepared statement를 활용하지 않는 커스텀 쿼리는
    차라리 실행되지 않고 에러나는 편이 사용자 입장에서 더 안전합니다.

    그런 위험한 자료도 더이상 판매되지 말아야겠고요.

  • profile profile
    저런 코드들이 실행되었을때 언제 터질지 몰라 걱정입니다.ㅠㅠ
  • profile profile
    그래서 $oDB->prefix를 날려버린 겁니다.
    보안취약점이 의심되는 자료들 일괄적으로 에러유발... ㅎㅎ
  • profile profile
    네 그게 좋겠네요 ㅋㅋㅋ
  • profile ?
    이게 라이믹스에서만 가능한 방법인가요?
    아니면 XE 1.11.6 기반에서도 사용 가능한 권장 방법인건가요?
    ( 내부 함수 차이가 있을테니.. )

    ps. 모듈에 따라 쿼리를 유동적으로 돌려야할때 $oDB 기반에 prefix 쓰는 경우 종종 있는데.. 골치아픈게 많군요
  • ? profile

    if(version_compare(__XE_VERSION__, '2.0', '>=')) 조건 달아서 분기하셔야 합니다.

    query()에서 돌아오는 결과가 PDOStatement 인스턴스이기 때문에

    기존 mysqli에서 쓰시던 함수는 하나도 안 통합니다.

    XE는 비공식적인 _query() + _fetch() 외에는 커스텀 쿼리를 실행할 방법이 없잖아요.
    XE가 처음 나왔을 때는 해당 함수들을 private으로 지정할 방법조차 없었기 때문에
    본의 아니게 public으로 노출되었고, 그걸 서드파티 자료 제작자분들이 그대로 갖다 썼지요.

    라이믹스 2.0에서는 언더바 없는 query() 함수로 커스텀 쿼리를 공식 지원함과 동시에
    기존 방식은 deprecated되었습니다. _query() + _fetch() 메소드는 존재하지만,
    prefix를 막아놓아서 현실적으로 막 사용하기에 허들이 있습니다.

    기존 소스를 최소한의 수정만으로 사용하시려면 위에서 알려드린 대로 버전에 따라 분기한 후
    $oDB->prefix 대신 config('db.master.prefix')를 불러와서 사용하실 수도 있긴 합니다만,
    마지막의 언더바(예: xe_) 처리 방식 등에서 약간의 차이가 있을 수도 있습니다.

  • profile profile
    공개된 위젯 중 이러한 쿼리 부분이 있는데요.

    $wd_oDB = &DB::getInstance();
    $wdmf_sql = "SELECT member_follow.target_srl as target_srl, member.nick_name as target_nick_name, member.user_id as user_id, member.regdate as regdate, member.last_login as last_login, count(member_follow.target_srl) cnt FROM ".$wd_oDB->prefix."member_follow as member_follow left join ".$wd_oDB->prefix."member as member on member_follow.target_srl = member.member_srl WHERE 1 AND member.member_srl IS NOT NULL ".$login_target_sql.$ban_sql.$date_sql." GROUP BY member_follow.target_srl ".$having_sql." ORDER BY ".$order_sql." LIMIT 0, ".$list_counts;

    $wdmf_query = $wd_oDB->_query($wdmf_sql);
    $subscri_member_rank = new stdClass;
    $wdmf_result = $wd_oDB->_fetch($wdmf_query);


    라이믹스 2.0 에서는 동작이 안되는 걸까요???
  • profile profile
    $wdmf_query = $wd_oDB->query($wdmf_sql);
    $subscri_member_rank = new stdClass; // 이 줄은 쿼리와 관련 없어 보입니다만 아무튼 그대로...
    $wdmf_result = $wdmf_query->fetchAll();
    로 바꾸면 될 것 같습니다만, 직접 확인은 안 해봤습니다.
  • profile profile
    $wd_oDB->prefix

    prefix를 가져오는 부분 때문에 SQL 수정 없이는 실행되지 않을겁니다.
  • profile profile

    이게 2.0 아래에서는 또 바꾸면 안되는거죠??

    나름 중요한 역할을 하는 자료의 위젯이라 2.0 에서 문제가 되니 걱정이 많네요.
    다른 자료들도 문제가 되는게 더 있을거구요... 실운영 커뮤니티 중 1개는 많은 기능을 포기할때 2.0 업데이트 결심이 설 것 같습니다.

    2.0 올릴때 조치 해야겠습니다.

  • profile profile

    prefix를 못 가져왔으니 빈 문자열로 들어갈 것이고, 따라서 SELECT ... FROM member_follow ... 이렇게 prefix 없는 테이블명이 포함된 쿼리문이 작성되겠지요.

    라이믹스 2.0의 $oDB->query() -- 앞에 언더바가 없습니다! -- 메소드는 prefix 없는 쿼리문을 받아서 적재적소에 자동으로 prefix를 붙여줍니다. 결과적으로는 prefix가 붙은 쿼리문이 실행됩니다. 서드파티 자료는 커스텀 쿼리 작성시 prefix를 신경쓰지 않아도 된다(신경써서는 안 된다)는 개발 의도에 아주 딱 맞지요.

  • profile profile
    그렇긴 한데, 굳이 못가져오는걸 그냥 둘 필요는 없지 않나요? 어차피 수정하는김에 빼버리는게 낫죠.
  • profile profile
    네, 빼버리면 더 좋지요. 단지 최소한의 수정으로 해결하는 법을 알려드렸을 뿐입니다.

    저렇게 하면 쿼리 작성하는 부분은 그대로 두고, 실제 쿼리를 실행하는 2줄 정도만 RX_VERSION 또는 XE_VERSION의 값에 따라 분기하면 될 테니까요.
  • profile
    정보 감사합니다.
  • profile
    Xml 로 할수 없는 쿼리가 있어서 직접 날려서 썼었는데
    이젠 그럴 필요가 없군요.
    XML 익숙해지니 넘 좋습니다
  • profile profile
    XML쓸수있는 쿼리는 되도록이면 XML쿼리 쓰시는게 맞습니다.

    모른다면 배우셔야하고요 ㅎㅎ

    괜히 이상한것 건드려서 에러먹게하거나 날려먹지 마시고 정석을 따르는게 가장 좋은 방법이죠 ㅋㅋㅋ
  • profile profile
    https://www.bloger.kr/51

    이런식의 랭킹을 뽑아 오는 쿼리 XML로 할수 있나요?
  • profile profile

    비개발자는 결국 구글신의 도움으로 Query 문을 가져와 Table, Field 교체해서 사용하다보니 XML 과감하게 실행 못하는거 같습니다. (제가요;;) .. XML 쿼리를 실행하기 위한 php 파일안에서의 문법도 있고.

    개발자 보다 비개발자가 운영하는 경우가 대다수 일꺼라 생각합니다. 내부에서 해결을 해야하는데 외부에서 해결하다보니 공식적인 방법을 안쓰는게 가장 큰 문제점.

    ZB(zero님) 시절에는 Tip 이란것들이 존재해서 따라했지만. 지금은 팁은 구글에 의존하다보니.. 뭔가 사용자들에게 Fllow me 할 수 있는 (아주 상식적이지만 초보자들이 몰라서 실수하는 것) 메뉴얼/팁이 생성되면 좋겠네요.

     

  • profile profile
    그런 것들이 현재는 xetown의 팁게시판에 있지요.

    이 글도 그 일환으로써 하나의 자리매김을 위한 글입니다.
  • profile profile
    XE 개발자 매뉴얼이 있긴 하지만 너무 따분하게 쓰여 있어서...
    라이믹스에서 추가된 내용들 포함하여 다시 정리하여 매뉴얼을 만들어야겠습니다.
    초보자 입장에서는 제대로 된 매뉴얼이 있고 없고 차이가 무척 크지요.
  • profile profile
    XETOWN 타운이 생겼을 때 XE1 팬사이트 느낌이였습니다. 팁들도 XE 와 RXE들이 섞여 있어서 저도 가끔 혼란스러운 자료가 더러 있었습니다. RXE 를 위한 분기를 해야 할 시점인 것 같습니다.
  • ?

    결론은...그동안 XE에서 PHP,XML 문법사용을 정석대로 하지 않았다는것이군요.....

  • ? profile
    XE코어는 업데이트되가면서 정석을 그대로 지켰다는거고.

    이글에서 작성하는 취지는 서드파티개발자들 중에서 직접 쿼리 날리시는 경우를 말씀드리는것입니다.

    XE에는 그런 대안이 없어서 그냥 쿼리문을 직접 작성해서 쿼리를 만드는경우도 있었는데 그당시 XML쿼리문으로도 해결가능한 기능들을 굳이 일부 레이아웃 개발자 및 서드파티 개발자분들께서 쿼리문을 직접 날리는 형태로 제작한 자료가 있었다는 것입니다.

    라이믹스는 이런 부분에서 인젝션 공격에 취약점들을 보이는 서드파티들의 보안 취약점을 최대한 없애고자 DB에도 더 많은 기능을 추가하고 XE보다 더 탄탄하게 만들어져 있습니다.

    XE코어자체의 문제라기보단 일부 서드파티에서 이런 코드들이 보인다면 경각심을 가지고 최대한 안쓰도록 노력해야할 것입니다.