SAP BOX

'26/11/08 UPDATE

ABAP / FIELD NOTES

Z 프로그램 권한 점검, AUTHORITY-CHECK 뒤 sy-subrc 4만 보면 무엇이 빠질까

AUTHORITY-CHECK 뒤에 IF sy-subrc = 4만 두면 그 권한 객체를 아예 받지 않은 사용자(sy-subrc 12)는 그대로 통과합니다. sy-subrc 0·4·12·40의 뜻, 0이 '이 사용자에게 이 값의 권한'을 뜻하지 않는 네 경우, 암묵 검사가 없어 직접 막아야 하는 자리를 가상 Z 리포트로 짚고 점검 순서를 남깁니다.

Z 리포트의 권한 검사를 점검하다 보면 AUTHORITY-CHECK 바로 아래에 IF sy-subrc = 4.만 있는 코드를 만날 수 있습니다. 이 IF는 권한을 일부 받은 사용자는 막지만, 그 권한 객체를 아예 받지 않은 사용자는 그대로 통과시킵니다. 이 글을 읽고 나면 sy-subrc 값의 뜻, 0이 '이 사용자에게 이 값의 권한'을 뜻하지 않는 경우, AUTHORITY-CHECK를 직접 써야 하는 자리를 가려 Z 코드 점검 목록을 만들 수 있습니다.

예시는 가상 리포트 ZBOX_CARRIER_LIST입니다. 입력한 항공사의 항공편을 보여 주기 전에 권한 객체 S_CARRID로 항공사(CARRID)와 활동(ACTVT, 03 = 표시)을 검사합니다. S_CARRID는 SAP 키워드 문서의 예제에 나오는 객체입니다. 코드는 실제 시스템에서 실행하지 않았고, 동작은 ABAP 키워드 문서 7.58판의 AUTHORITY-CHECK 설명(영어)과 관련 페이지를 기준으로 썼습니다.

sy-subrc는 다섯 값, 4는 그중 하나

AUTHORITY-CHECK는 현재 사용자의 사용자 마스터 레코드에 그 객체의 권한이 있는지, 그 권한이 적은 값을 허용하는지 검사합니다. 실패해도 예외 없이 결과를 sy-subrc에 남길 뿐이라, 실제로 막는 일은 뒤의 IF가 맡습니다.

  • 0: 검사에 성공했거나 검사를 하지 않았습니다. 성공은 그 객체의 권한 가운데 적어도 하나가, 적은 모든 필드의 값을 함께 포함한다는 뜻입니다. 항공사 값은 한 권한에, 활동 03은 다른 권한에 나뉘어 있으면 성공이 아닙니다.
  • 4: 그 객체의 권한은 있지만 적은 값이 들어 있지 않습니다. 객체에 없는 필드 이름을 적었거나 필드를 너무 많이 적었을 때도 4입니다.
  • 12: 사용자 마스터 레코드에 그 객체의 권한이 하나도 없습니다.
  • 24: 더 이상 설정되지 않는 값입니다.
  • 40: FOR USER에 잘못된 사용자 이름을 주었습니다. FOR USER를 쓰지 않으면 나오지 않습니다.

이 다섯 값의 뜻은 7.40판, 7.50판, 7.58판, 8.16판 문서에서 같고 문구만 조금 다릅니다.

SAP GUI ABAP 편집기 화면 예시. 가상 리포트 ZBOX_CARRIER_LIST의 AT SELECTION-SCREEN에서 AUTHORITY-CHECK OBJECT 'S_CARRID'로 CARRID는 입력값 p_carr, ACTVT는 '03'을 검사하고, 바로 아래 IF sy-subrc = 4일 때만 오류 메시지를 낸다. START-OF-SELECTION의 SELECT * FROM spfli 조회에 번호 3이 붙어 있어, sy-subrc 12인 사용자가 이 조회까지 온다는 것을 보여 준다.
AUTHORITY-CHECK 뒤에 IF sy-subrc = 4만 둔 가상 리포트의 편집기 화면 예시. ZBOX_CARRIER_LIST와 값은 가상이며 코드는 실행하지 않았다.

화면 예시의 1번이 검사, 2번이 4만 실패로 보는 IF입니다. 권한은 받았지만 이 항공사가 빠진 사용자는 4를 받아 2번에서 멈춥니다. 그런데 S_CARRID 권한을 하나도 받지 않은 사용자는 12를 받고, IF를 지나 3번의 조회까지 갑니다. 이 객체에 대해 권한이 가장 적은 사용자가 가장 쉽게 통과하는 셈입니다. 거부되는 경우를 권한을 일부 받은 사용자로만 시험하면 4만 보게 되어 이 틈이 드러나지 않습니다.

고치는 방법은 IF sy-subrc <> 0.으로 0이 아닌 값을 모두 실패로 보는 것입니다. 12나 40에 다른 메시지를 보여 줄 수는 있어도, 통과시키는 값은 0 하나여야 합니다.

SAP 노트

= 4는 12와 40을 통과시킨다

AUTHORITY-CHECK 뒤 sy-subrc 값마다 두 IF가 하는 일 (ABAP 키워드 문서 7.58판 기준)

  • 0 · 성공 또는 검사하지 않음

    sy-subrc = 0

    • 권한 하나가 적은 값을 모두 포함
    • = 4: 통과 · <> 0: 통과
  • 4 · 권한은 있으나 값이 없음

    sy-subrc = 4

    • 또는 잘못된 필드, 너무 많은 필드
    • = 4: 멈춤 · <> 0: 멈춤
  • 12 · 이 객체의 권한이 하나도 없음

    sy-subrc = 12

    • 이 객체에 대해 권한이 가장 적은 사용자
    • = 4: 통과 · <> 0: 멈춤
  • 40 · FOR USER에 잘못된 사용자 이름

    sy-subrc = 40

    • FOR USER를 쓸 때만 나온다
    • = 4: 통과 · <> 0: 멈춤

24는 더 이상 설정되지 않습니다. 이 표는 7.40·7.50·7.58·8.16판에서 같습니다. 0에는 '검사하지 않음'도 들어 있습니다.

IF sy-subrc = 4는 실제로 나오는 네 값(24 제외) 가운데 하나만 막습니다. IF sy-subrc <> 0은 0이 아닌 값을 모두 실패로 봅니다.

0이 '이 사용자에게 이 값의 권한'을 뜻하지 않는 네 경우

<> 0으로 고쳐도 0 쪽에 틈이 남습니다. 검사를 하지 않았거나, 일부 필드만 검사했거나, 다른 사용자를 검사했을 때도 0이 나오기 때문입니다.

검사 표시가 '검사 안 함'일 때. 검사 표시(check indicator)는 맥락마다 그 권한 객체를 검사할지 말지 정하는 표시이고, 가장 중요한 맥락은 트랜잭션입니다. SAP는 SU22에서, 고객 시스템은 SU24에서 정합니다. 지금 맥락에서 그 객체가 '검사 안 함'이면 AUTHORITY-CHECK는 검사하지 않고 성공과 같은 0을 남깁니다. 같은 문장도 프로그램을 시작한 방식에 따라 결과가 달라질 수 있는 까닭입니다. 검사 표시는 늘 '검사'로 두는 것이 원칙이고, AS ABAP(BC) 영역과 인사 관리(HR) 영역의 객체는 '검사 안 함'으로 바꿀 수 없습니다.

업데이트 중일 때. COMMIT WORK가 부른 업데이트 함수 모듈 안에서는 권한 검사를 할 수 없습니다. 이때 AUTHORITY-CHECK는 검사하지 않고 sy-subrc를 늘 0으로 둡니다. 업데이트 세션뿐 아니라 로컬 업데이트도 같습니다. 그래서 권한은 CALL FUNCTION ... IN UPDATE TASK로 등록하기 전, 대화 단계에서 검사합니다. 업데이트가 언제 도는지는 COMMIT WORK 직후의 업데이트 태스크를 다룬 글에 있습니다.

DUMMY를 주었거나 필드를 적지 않았을 때. 문장에 적지 않은 필드와 DUMMY를 준 필드는 검사하지 않습니다. ID 'ACTVT' DUMMY라고 쓰면 활동은 보지 않고 항공사만 봅니다. 모든 필드를 DUMMY로 주면 7.58판 기준으로 결과는 0 아니면 12입니다. 값과 관계없이 그 객체의 권한이 하나라도 있으면 0이므로, 이때의 0은 '이 객체의 권한이 있다'는 뜻일 뿐입니다.

FOR USER로 다른 사용자를 검사했을 때. FOR USER를 붙이면 지정한 사용자의 권한을 검사합니다. 권한이 많은 사용자 이름을 넣어 검사를 우회하는 데 악용될 수 있어, 문서는 이 추가 문구를 보안 위험으로 분류합니다. 밖에서 넘어온 사용자 이름은 쓰지 않고, 꼭 써야 하면 그 이름을 꼼꼼히 검사합니다. FOR USER가 없으면 시스템 필드 sy-uname의 내용이 아니라 실제 사용자 이름으로 검사합니다. 그래서 FOR USER sy-uname은 중복일 뿐 아니라, 디버거 등에서 sy-uname을 덮어쓸 수 있어 위험하기도 합니다.

SAP 노트

0이라고 다 이 사용자의 허가는 아니다

0이 '이 사용자에게 이 값의 권한이 있다'를 뜻하지 않는 네 경우

  • 검사 표시가 '검사 안 함'

    • 검사하지 않고 성공처럼 0
    • 맥락마다 정하는 표시
    • 가장 중요한 맥락은 트랜잭션
    • 고객 시스템은 SU24에서 정함
    • BC·HR 객체는 '검사 안 함' 불가
  • 업데이트 중

    CALL FUNCTION … IN UPDATE TASK

    • COMMIT WORK가 부른 업데이트 함수 모듈
    • 검사하지 않고 항상 0
    • 로컬 업데이트도 같음
  • DUMMY이거나 적지 않은 필드

    ID 'ACTVT' DUMMY

    • 그 필드는 검사하지 않음
    • 모두 DUMMY면 결과는 0 또는 12
    • 값과 관계없이 권한이 있으면 0
  • FOR USER

    FOR USER lv_user

    • 다른 사용자의 권한을 검사
    • 밖에서 받은 이름은 쓰지 않음
    • FOR USER sy-uname은 중복
    • sy-uname은 덮어쓸 수 있음

FOR USER가 없으면 sy-uname의 내용이 아니라 실제 사용자 이름으로 검사합니다. 'DUMMY만 주면 0 또는 12'는 7.58판 문서에서 확인했습니다.

검사를 하지 않았거나, 일부 필드만 보았거나, 다른 사용자를 검사했을 때도 0이 나옵니다.

AUTHORITY-CHECK를 직접 써야 하는 자리

어떤 문장은 정해진 권한 객체로 스스로 검사합니다.

  • CALL TRANSACTION ... WITH AUTHORITY-CHECK는 호출 전에 S_TCODE와, SE93의 트랜잭션 정의에 적힌 권한 객체를 검사합니다. 권한이 없으면 잡을 수 있는 예외 CX_SY_AUTHORIZATION_ERROR가 나고, 잡지 않으면 런타임 오류 CALL_TRANSACTION_NO_AUTH로 끝납니다.
  • LEAVE TO TRANSACTION은 늘 같은 두 가지(S_TCODE와 SE93에 적힌 객체)를 검사하고, 권한이 없으면 종료 메시지(유형 A)를 보냅니다.
  • SUBMIT은 호출할 프로그램의 속성에 권한 그룹이 있으면 그 그룹을 S_PROGRAM으로 검사합니다.
  • ABAP 파일 인터페이스의 OPEN DATASET과 DELETE DATASET은 파일을 열거나 지울 때 S_DATASET으로 검사합니다. 테이블 SPTH 설정에 따라 S_PATH 검사도 더해집니다.

반대로 암묵 검사가 없는 대표적인 자리로는 WITH AUTHORITY-CHECK 없이 쓴 CALL TRANSACTION(기본 동작에서는 테이블 TCDCOUPLES에 이 호출의 OKFLAG가 X인 항목도 없을 때), 권한 그룹이 없는 프로그램의 SUBMIT, 데이터베이스 테이블을 읽는 SQL이 있습니다. 권한 없이 닿을 수 있는 이런 자리는 AUTHORITY-CHECK로 직접 막고 결과를 꼼꼼히 봅니다.

CALL TRANSACTION에 WITH AUTHORITY-CHECK와 WITHOUT AUTHORITY-CHECK 중 어느 것도 붙이지 않은 형태는 obsolete입니다. 이 두 추가 문구는 ABAP 7.40 SP02의 변경 사항에 새 기능으로 실려 있고, 7.31판 문서의 CALL TRANSACTION 문법에는 없습니다. 권장 방법은 WITH AUTHORITY-CHECK이고, 호출 앞에 따로 두던 AUTHORITY-CHECK나 AUTHORITY_CHECK_TCODE, TCDCOUPLES에 기대는 검사를 대신합니다. WITHOUT AUTHORITY-CHECK는 검사가 필요 없다고 드러내 적는 것입니다. 이것을 붙이면 확장 프로그램 검사의 보안 테스트가 그 호출을 오류로 보고하지 않고, TCDCOUPLES의 내용도 무시됩니다. 점검에서는 왜 검사가 필요 없는지 물을 자리입니다.

SAP 노트

암묵 검사가 있는 자리, 없는 자리

AUTHORITY-CHECK를 직접 써야 하는지 가르는 문장들 (7.58판 기준)

  • 암묵 검사가 있는 예

    • CALL TRANSACTION … WITH AUTHORITY-CHECK: S_TCODE와 SE93에 적힌 객체
    • LEAVE TO TRANSACTION: S_TCODE와 SE93에 적힌 객체
    • 권한 그룹이 있는 프로그램의 SUBMIT: S_PROGRAM
    • OPEN DATASET·DELETE DATASET: S_DATASET 등
  • 암묵 검사가 없는 예

    AUTHORITY-CHECK OBJECT …

    • WITH가 없는 CALL TRANSACTION (기본 동작: TCDCOUPLES에 OKFLAG X 항목도 없을 때)
    • 권한 그룹이 없는 프로그램의 SUBMIT
    • 데이터베이스 테이블을 읽는 SQL
    • 이런 자리는 직접 막고 결과를 꼼꼼히 본다
  • 검사하지 않는다고 적는다

    WITHOUT AUTHORITY-CHECK

    • 확장 프로그램 검사의 보안 오류가 나오지 않음
    • TCDCOUPLES 내용은 무시
    • 둘 다 없는 CALL TRANSACTION은 obsolete

WITH AUTHORITY-CHECK에서 권한이 없으면 CX_SY_AUTHORIZATION_ERROR가 나고, 잡지 않으면 런타임 오류 CALL_TRANSACTION_NO_AUTH입니다. 파일 인터페이스에는 테이블 SPTH 설정에 따른 S_PATH 검사도 있습니다.

암묵 검사가 있는 문장은 객체가 정해져 있습니다. 없는 자리는 AUTHORITY-CHECK로 직접 막아야 하고, WITHOUT AUTHORITY-CHECK는 점검에서 이유를 물을 자리입니다.

점검할 때 보는 순서

  1. AUTHORITY-CHECK마다 바로 뒤의 판정을 봅니다. = 4나 = 12처럼 값 하나만 실패로 보는 코드는 <> 0으로 바꿉니다.
  2. 실패 뒤에 sy-uname을 비교해 특정 사용자만 빼 주는 분기가 있는지 봅니다. 문서는 이런 분기를 뒷문의 예로 들고, sy-uname을 묻는 IF 블록을 걷어내 고치라고 합니다. 걷어내는 것은 그 조건뿐이고, 실패 처리(LEAVE PROGRAM 등)는 남깁니다.
  3. FOR USER가 있으면 사용자 이름이 어디서 오는지 봅니다. 밖에서 들어온 이름이면 고치고, FOR USER sy-uname은 지웁니다.
  4. DUMMY와 빠진 필드를 봅니다. 활동(ACTVT)을 빼면 표시 권한만 받은 사용자도 변경을 위한 검사를 통과합니다.
  5. 업데이트 함수 모듈 안의 AUTHORITY-CHECK는 호출 전 대화 단계로 옮깁니다.
  6. WITH AUTHORITY-CHECK가 없는 CALL TRANSACTION은 그 시스템의 릴리스에서 이 추가 문구를 쓸 수 있는지 보고, 쓸 수 없으면 앞에 검사가 있는지 봅니다. 권한 그룹이 없는 프로그램의 SUBMIT, 민감한 테이블을 읽는 SELECT처럼 암묵 검사가 없는 다른 자리도 앞에 검사가 있는지 봅니다.
  7. 리포트를 시작하는 트랜잭션의 SU24에서 그 객체의 검사 표시가 '검사'인지 확인합니다.
  8. 시스템에서 확인할 때는 ST01 시스템 트레이스가 검사한 권한 객체와 필드, 값을 기록합니다. 트레이스와 대상 트랜잭션이 같은 애플리케이션 서버에서 돌면 다른 세션의 검사도 남습니다. SU53은 마지막으로 실패한 권한 검사를 보여 주며, 오류가 난 세션이 아닌 자신의 다른 세션에서도 열 수 있습니다.

점검표의 첫 줄은 = 4를 <> 0으로 바꾸는 일이고, 둘째 줄은 0이 나왔을 때 '누구의 권한을, 어떤 필드로, 정말 검사했는가'를 묻는 일입니다. 이 질문에 답하지 못하는 0은 허가로 세지 않습니다.

끝 · END OF NOTE
RSS 구독목록으로
COMMENTS BOX

이 기록에 대화를 더해 주세요.

궁금한 점, 다른 접근, 직접 해 본 결과를 나눠 주세요.

최신순

로그인 상태 확인 중…

댓글을 불러오는 중…