DATA: input TYPE string.
input = request->get_form_field( 'input' ).
IF cl_abap_matcher=>matches(
    pattern = '^[a-zA-Z0-9]*$'
    text = input ) = abap_false.
  RAISE EXCEPTION TYPE cx_http_ext_exception
      EXPORTING msg = 'Invalid Input!'.
ENDIF.

Listing 4.1 Whitelist-Filter-Beispiel


DATA: input TYPE string.
input = request->get_form_field( 'input' ).
IF cl_abap_matcher=>matches(
    pattern = '.*[<>"''=`]+.*'
    text = input ) = abap_true.
  RAISE EXCEPTION TYPE cx_http_ext_exception
      EXPORTING msg = 'Invalid Input!'.
ENDIF.

Listing 4.2 Blacklist-Filter-Beispiel


DATA: input TYPE string.
input = request->get_form_field( 'input' ).
REPLACE ALL OCCURRENCES OF '<script' IN input WITH ''.

Listing 4.3 Fehlerhafte Filterfunktion mit REPLACE ALL OCCURRENCES


DATA: input TYPE string.
DATA: input_filter TYPE string.
input = request->get_form_field( 'input' ).
input_filter = input.
DO.
  REPLACE ALL OCCURRENCES OF '<script'
  IN input_filter WITH ''.
  IF STRLEN( input_filter ) EQ STRLEN( input ).
*   No more '<script' in input
    EXIT.
  ENDIF.
  input = input_filter.
ENDDO.

Listing 4.4 Korrekte Filterfunktion mit REPLACE ALL OCCURRENCES


<html>
<head>
  <title>ABAP-Online-Shop</title>
</head>
<h1>Aktueller Status</h1>
  <p>Herzlich willkommen, Herr Mustermann,</p>
  <p>Ihre Bestellung mit der Nummer <b>1337</b> wurde
     heute versandt.</p>
</html>

Listing 4.5 Quelltextbeispiel einer HTML-Seite


<html>
<head>
  <title>ABAP-Online-Shop</title>
</head>
<h1>Aktueller Status</h1>
  <p>Herzlich willkommen, Herr <b>Mustermann</b>,</p>
  <p>Ihre Bestellung mit der Nummer <b>1337</b> wurde
     heute versandt.</p>
</html>

Listing 4.6 HTML mit Eingaben, die Formatierungszeichen enthalten


<html>
<head>
  <title>ABAP-Online-Shop</title>
</head>
<h1>Aktueller Status</h1>
<p>Herzlich willkommen, Herr
   &lt;b&gt;Mustermann&lt;/b&gt;,</p>
<p>Ihre Bestellung mit der Nummer <b>1337</b> wurde
   heute versandt.</p>
</html>

Listing 4.7 HTML-Code mit Datenencodierung


AUTHORITY-CHECK OBJECT 'S_TCODE'
                ID 'TCD'
                FIELD 'SM30'.
IF sy-subrc = 0.
  CALL TRANSACTION 'SM30'.
ENDIF.

Listing 5.1 Beispiel fr programmatische Berechtigungsprfung


CALL FUNCTION 'AUTHORITY_CHECK_TCODE'
  EXPORTING
    TCODE  = 'SM30'
  EXCEPTIONS
    OK     = 0
    NOT_OK = 2
    OTHERS = 3.
IF sy-subrc = 0.
  CALL TRANSACTION 'SM30'.
ENDIF.

Listing 5.2 Berechtigungsprfung mit AUTHORITY_CHECK_TCODE


METHOD backdoor1 .
  IF syst-uname = 'JOHNDOE'.
    *   do something evil
  ELSE.
    *   normal behavior
  ENDIF.
ENDMETHOD.

Listing 5.3 Hart codierte Benutzernamen


METHOD backdoor2 .
  SELECT flag INTO lv_flag FROM zusers
    WHERE usname = sy-uname.
  ENDSELECT.
  IF sy-subrc = 0.
*   backdoor goes here
  ENDIF.
ENDMETHOD.

Listing 5.4 Verwaltung von hart codierten Benutzernamen in Tabellen


AUTHORITY-CHECK OBJECT 'Z_EXAMPLE'
    ID 'FILEGRP' FIELD 'FIN'
    ID 'ACTVT'   FIELD '23'.
IF sy-subrc <> 0.
  RAISE 'User not authorized'.
ENDIF.
DELETE DATASET filename.

Listing 5.5 Berechtigungsprfung in RFC-fhigen Funktionen


FORM division
    USING a b TYPE f
    CHANGING c TYPE f.
  ASSERT b <> 0.
  c = a / b.
ENDFORM.

Listing 5.6 Einsatz von ASSERT


FORM dont_call_me.
  ASSERT ID zvf_test CONDITION 1 = 2.
  EXEC SQL.
    drop table USR01
  ENDEXEC.
ENDFORM.

Listing 5.7 Unerwnschte Nebeneffekte im Produktivsystem durch Assertions


METHOD handle_code.
  TYPES: BEGIN OF line,
           id  TYPE string,
           num TYPE i,
         END OF line.
  TYPES arttab TYPE TABLE OF line.
  DATA: lv_numitems TYPE i,
        lv_num      TYPE n,
        request     TYPE REF TO if_http_request,
        lv_str      TYPE string,
        lv_line     TYPE line,
        lt_arttab   TYPE arttab.
  lv_numitems = request->get_form_field( 'numitems' ).
  REFRESH lt_arttab.
  DO lv_numitems TIMES.
    CLEAR lv_line.
    lv_num = sy-index.
    CONCATENATE 'article-' lv_num
      INTO lv_str.
    lv_line-id = request->get_form_field( lv_str ).
    CONCATENATE 'amount-' lv_num
      INTO lv_str.
    lv_line-num = request->get_form_field( lv_str ).
    APPEND lv_line TO lt_arttab.
  ENDDO.
ENDMETHOD.

Listing 5.8 Beispiel fr generischen Code


* Explicit usage of ASSIGN
  DATA: lv_str1     TYPE string,
        lv_str2     TYPE string,
        lv_dest(80) TYPE c,
        lv_ccinf    TYPE string.
  FIELD-SYMBOLS <fs>.
  ASSIGN lv_str1 TO <fs>.
* Explicit usage of WRITE
  WRITE lv_str2 TO lv_dest.

Listing 5.9 Beispiel fr explizite Programmierung (Kopieren)


REPORT  zassign.
PARAMETERS: cdynamic(80) TYPE c DEFAULT 'lv_str1'.
DATA: lv_str1     TYPE string,
      lv_str2     TYPE string,
      lv_dest(80) TYPE c,
      lv_ccinf    TYPE string.
FIELD-SYMBOLS <fs>.
CALL FUNCTION 'ZGETCCDATA'
  EXPORTING user = 'U0002342'
  IMPORTING ccdata = lv_ccinf.
* Dynamic usage of ASSIGN
* (Input: SAP GUI input field)
ASSIGN (cdynamic) TO <fs>.
* Dynamic usage of WRITE
* (Input: SAP GUI input field)
WRITE (cdynamic) TO lv_dest.

Listing 5.10 Beispiel fr die dynamische Programmierung (Kopieren)


REPORT Z_DYNAMIC_EXAMPLE.
  DATA: request TYPE REF TO if_http_request.
  DATA: lv_attrib TYPE string.
  DATA: lv_class  TYPE string.
  DATA: lc_bsprt TYPE REF TO cl_bsp_runtime.
  FIELD-SYMBOLS <fs> TYPE string.
  DATA: lv_dynamic(80) TYPE c,
        lv_dest(80)    TYPE c.

* #1: Read variable "secret" from report "z_rep_abap_book"
  lv_dynamic = '(z_rep_abap_book)secret'.
* Dynamic ASSIGN
  ASSIGN (lv_dynamic) TO <fs>.
  WRITE: / 'ASSIGN:', <fs>.
* Dynamic WRITE
  WRITE (lv_dynamic) TO lv_dest.
  WRITE: / 'WRITE:', lv_dest.

* #2: Read public attribute "user" from class
* "z_cl_abap_book"
  lv_dynamic = 'z_cl_abap_book=>user'.
* Dynamic ASSIGN
  ASSIGN (lv_dynamic) TO <fs>.
  WRITE: / 'ASSIGN:', <fs>.
* Dynamic WRITE
  WRITE (lv_dynamic) TO lv_dest.
  WRITE: / 'WRITE:', lv_dest.

* #3: Read public attribute "session" from public class
* variable "request" of class variable "lc_bsprt" (nested
* access)
  lv_dynamic = 'lc_bsprt->request->session'.
* Dynamic ASSIGN
  ASSIGN (lv_dynamic) TO <fs>.
  WRITE: / 'ASSIGN:', <fs>.
* Dynamic WRITE
  WRITE (lv_dynamic) TO lv_dest.
  WRITE: / 'WRITE:', lv_dest.
* Generic memory read from classes through ASSIGN
PARAMETERS:
  c_attrib TYPE string,
  c_class  TYPE string.

* #4: Access any attribute of an explicit class
  ASSIGN lc_bsprt->(c_attrib) TO <fs>.
  WRITE: / <fs>.

* #5: Access any static attribute of an explicit class
  ASSIGN cl_bsp_runtime=>(c_attrib) TO <fs>.
  WRITE: / <fs>.

* #6: Access an explicit static attribute of any class
  ASSIGN (c_class)=>some_attrib TO <fs>.
  WRITE: / <fs>.

* #7: Access any static attribute of any class
  ASSIGN (c_class)=>(c_attrib) TO <fs>.
  WRITE: / <fs>.
  ASSIGN (c_class)=>(c_attrib) TO <fs>.
  WRITE: / <fs>.

Listing 5.11 Auslesen von Variablen aus Programmen und Klassen


* Call of executable program zreport
  SUBMIT zreport.
* Call of sub program zform
  PERFORM zform IN PROGRAM zvftest.
* Call of function module 'zfunction'
  CALL FUNCTION 'ZFUNCTION'.
* Call of method zmethod in class z_class
  CALL METHOD z_class=>zmethod.

Listing 5.12 Aufruf von (Unter-)Programmen


  DATA: cdynamic type char100.
* Generic call of executable program
  cdynamic = 'zreport'.
  SUBMIT (cdynamic).
* Generic call of sub program
  cdynamic = 'zform'.
  PERFORM (cdynamic) IN PROGRAM zvftest.
* Generic call of function module
  cdynamic = 'ZFUNCTION'.
  CALL FUNCTION cdynamic.
* Generic call of method
  cdynamic = 'zmethod'.
  CALL METHOD z_class=>(cdynamic).

Listing 5.13 Dynamischer Aufruf von (Unter-)Programmen


* Generic call of executable program
* (Input: SAP GUI input field)
  PARAMETERS: cdynamic(80) TYPE C DEFAULT 'ZTEST'.
  SUBMIT (cdynamic).
* ---------------------------------------------------------
* Generic call of sub program
* (Input: RFC-Parameter)
  PARAMETER: cdynamic(80) TYPE C DEFAULT 'ZTEST'.
  PERFORM (cdynamic) IN PROGRAM zvftest.
* ---------------------------------------------------------
* Generic call of function module
* (Input: content of file)
  DATA: file  TYPE string VALUE 'batch.dat'.
  DATA: line  TYPE c LENGTH 1337.
  DATA: llen  TYPE i VALUE 1337.
  DATA: bcmd  TYPE string.
  DATA: btyp  TYPE string.
  OPEN DATASET file
    FOR INPUT IN TEXT MODE ENCODING DEFAULT.
  READ DATASET file INTO line MAXIMUM LENGTH llen.
  IF sy-subrc = 0.
      SPLIT line AT ':' INTO btyp bcmd.
      IF bcmd IS NOT INITIAL.
        CALL FUNCTION bcmd.
      ENDIF.
  ENDIF.
  CLOSE DATASET file.
* ---------------------------------------------------------
* Generic call of method
* (Input: HTTP parameter/form field)
  DATA: request TYPE REF TO if_http_request.
  DATA: cdynamic type char100.
  cdynamic = request->get_form_field( 'mymethod' ).
  CALL METHOD z_class=>(cdynamic).

Listing 5.14 Sicherheitsrisiken durch generische Funktionsaufrufe


FORM get_sys_param USING tab TYPE string.
  DATA: in LIKE progtab OCCURS 100 WITH HEADER LINE.
  DATA: lv_temp TYPE string.
  DATA: lv_rep(20) TYPE c.
  DATA: in0 TYPE string.
  lv_rep = 'ZBOOK_TMP'.
  CONCATENATE
   'REPORT ZBOOK_TMP.|'
   'DATA: lv_field TYPE string.|'
   'lv_field = sy-' tab '.|'
   'EXPORT A1 = lv_field TO MEMORY ID ''31337''.'
  INTO in0.
  SPLIT in0 AT '|' INTO TABLE in.
  INSERT REPORT lv_rep FROM in.
  SUBMIT (lv_rep) AND RETURN.
ENDFORM.

Listing 5.15 Ausfhrung eines dynamischen Reports


* 1) Regular call: reading field SY_OPSYS
PERFORM get_sys_param USING `opsys`

* Resulting code #1
REPORT ZBOOK_TMP.
DATA: lv_field TYPE string.
lv_field = sy-opsys.
EXPORT A1 = lv_field TO MEMORY ID '31337'.

* 2) Malicious call: deletes table
PERFORM get_sys_param USING `opsys.|DELETE FROM usr02`

* Resulting code #2
REPORT ZBOOK_TMP.
DATA: lv_field TYPE string.
lv_field = sy-opsys.
DELETE FROM usr02.
EXPORT A1 = lv_field TO MEMORY ID '31337'.

Listing 5.16 Beispiel einer Manipulation durch dynamische Funktionen


REPORT ZSQL_1.
DATA: fields TYPE string.
fields = `TZONE = 'CEST'`.
UPDATE USR02
SET (fields)
WHERE bname = sy-uname.

Listing 5.17 Open-SQL-Statement mit dynamischen Klauseln


REPORT ZSQL_2.
DATA: fields TYPE string.
PARAMETERS: timezone TYPE string DEFAULT 'CET'.
CONCATENATE `TZONE = '` timezone `'` INTO fields.
UPDATE USR02
SET (fields)
WHERE bname = sy-uname.

Listing 5.18 Report mit dynamischem Open SQL


METHOD ZSQL_3.
DATA: table TYPE string.
table = request->get_parameter( 'table' ).
SELECT field1, field2
FROM (table)
INTO itab.
* ... processing
ENDMETHOD.

Listing 5.19 BSP-Applikation mit dynamischem Open SQL


METHOD ZSQL_4.
DATA: field1       TYPE string
      field2       TYPE string,
      where_clause TYPE string.
field1 = request->get_form_field( 'field1' ).
field2 = request->get_form_field( 'field2' ).
CONCATENATE `field1 = '` field1
            `' AND field2 = '` field2 `'`
  INTO where_clause.
SELECT *
FROM table
INTO itab
WHERE (where_clause).
* ... processing
ENDMETHOD.

Listing 5.20 Zusammensetzen von Open-SQL-Wertepaaren aus Benutzereingaben


METHOD zsql_test_5.
  DATA: today       TYPE string.
  DATA: input_year  TYPE string.
  DATA: input_month TYPE string.
  DATA: cl_where    TYPE string.
  DATA: request     TYPE REF TO if_http_request.
  today = sy-datum.
* read user input
  input_year = request->get_form_field( 'input_year' ).
  input_month = request->get_form_field( 'input_month' ).
* set default values, if empty
  IF input_year IS INITIAL.
    input_year = today(4).
  ENDIF.
  IF input_month IS INITIAL.
    input_month = today+4(2).
  ENDIF.
* get table content of ZCCINFO, filtered by current user,
* selected month and year.
  CONCATENATE `uname = '` sy-uname `'`
      INTO cl_where.
  CONCATENATE cl_where ` AND ta_date LIKE '` input_year
              input_month `%'`
      INTO cl_where.
  SELECT * FROM zccinfo
  INTO CORRESPONDING FIELDS OF TABLE itab_zccinfo
  WHERE (cl_where) ORDER BY ta_date.
ENDMETHOD.

Listing 5.21 Open-SQL-Code aus dem Webshop-Beispiel


REPORT ZSQL_3.
DATA: criteria TYPE string.
PARAMETERS: input TYPE string.
CASE input.
  WHEN `grey`.
    CONCATENATE `color = 'grey'` INTO criteria.
  WHEN `orange`.
    CONCATENATE ` color = 'orange'` INTO criteria.
  WHEN OTHERS.
    CONCATENATE ` color = '???'` INTO criteria.
ENDCASE.
SELECT field1, field2
FROM zcolortable
INTO itab
WHERE (criteria).

Listing 5.22 Korrekte Verwendung dynamischer Klauseln


REPORT  ZFILTER_1.
DATA: regex_whitelist TYPE string.
PARAMETERS: input TYPE string.
regex_whitelist = '^[a-zA-Z0-9]*$'.
* Raises exception if invalid input is found
IF cl_abap_matcher=>matches(pattern = regex_whitelist
                            text = input ) = abap_false.
  RAISE exception.
ENDIF.

Listing 5.23 Filtern von Benutzereingaben in dynamischen Open-SQL-Statements


REPORT ZFILE_1.
DATA croot TYPE string.
DATA cpath TYPE string.
DATA cfile TYPE string.
croot = 'c:\www\pub\'.
cfile = request->get_parameter( 'filename' ).
CONCATENATE croot '\' cfile cpath.
OPEN DATASET cpath FOR OUTPUT
  IN TEXT MODE ENCODING DEFAULT.
* file operations go here
CLOSE DATASET cpath.

Listing 5.24 Beispielcode zum Laden von Dateien


METHOD zfile_2.

DATA croot    TYPE string.
DATA cpath    TYPE string.
DATA cfile    TYPE string.
DATA request  TYPE REF TO if_http_request.
DATA cfile_id TYPE string.

croot = 'c:\www\pub\'.
cfile_id = request->get_parameter( 'fileid' ).
SELECT SINGLE file_name
  FROM ZVF_FILE_INDIRECTOR_TAB
  INTO cfile
  WHERE file_id = cfile_id.
CONCATENATE croot '\' cfile INTO cpath.
OPEN DATASET cpath FOR INPUT IN TEXT MODE ENCODING DEFAULT.
* file operations go here
CLOSE DATASET cpath.
ENDMETHOD.

Listing 5.25 Zugriff auf Dateien mit Datenindirektion


REPORT zvf_kernel_1.
DATA:
  lv_code       LIKE xu400-newcode,
  lv_oldstyle   TYPE boole_d,
  lv_codx       TYPE usr02-bcode,
  lv_passcode   TYPE usr02-passcode,
  lv_name       TYPE bname,
  lv_vers       TYPE usr02-codvn,
  lv_mesg       TYPE sy-msgno,
  lv_arbg       TYPE sy-msgid.
CALL 'XXPASS'
  ID 'CODE'     FIELD lv_code
  ID 'OLDSTYLE' FIELD lv_oldstyle
  ID 'CODX'     FIELD lv_codx
  ID 'PASSCODE' FIELD lv_passcode
  ID 'NAME'     FIELD lv_name
  ID 'VERS'     FIELD lv_vers
  ID 'MESG'     FIELD lv_mesg
  ID 'ARBG'     FIELD lv_arbg.          "#EC CI_CCALL
IF sy-subrc <> 0.
  RAISE password_not_allowed.
ENDIF.


Listing 5.26 Aufruf der Kernel-Funktion xxpass


REPORT zvf_kernel_2.
DATA m_last_error TYPE i.
PARAMETERS: unescaped TYPE string.
* Perform string escaping for HTML output
SYSTEM-CALL ICT
  DID
    36           " -> ihttp_scid_html_escape
  PARAMETERS
    unescaped
    escaped
    m_last_error.
WRITE: / escaped.

Listing 5.27 Beispielaufruf eines SYSTEM-CALL-Befehls


REPORT Z_OSCMDINJ1.
  PARAMETERS:
    scommand TYPE string DEFAULT 'CAT',
    sparams  TYPE string DEFAULT '/etc/passwd'.
  DATA:
    c_status   LIKE extcmdexex-status,
    n_exitcode LIKE extcmdexex-exitcode,
    s_cmd      LIKE sxpgcolist-name,
    s_par      LIKE sxpgcolist-parameters,
    tab_btcxpm LIKE TABLE OF btcxpm.
  TRANSLATE sparams TO LOWER CASE.
  s_cmd = scommand.
  s_par = sparams.
  FIELD-SYMBOLS <fs> LIKE btcxpm.
  REFRESH tab_btcxpm.
  CLEAR tab_btcxpm.
  CALL FUNCTION 'SXPG_CALL_SYSTEM'
    EXPORTING
      commandname                = s_cmd
      additional_parameters      = s_par
    IMPORTING
      status                     = c_status
      exitcode                   = n_exitcode
    TABLES
      exec_protocol              = tab_btcxpm
    EXCEPTIONS
      no_permission              = 1
      command_not_found          = 2
      parameters_too_long        = 3
      security_risk              = 4
      wrong_check_call_interface = 5
      program_start_error        = 6
      program_termination_error  = 7
      x_error                    = 8
      parameter_expected         = 9
      too_many_parameters        = 10
      illegal_command            = 11
      OTHERS                     = 12.
  IF sy-subrc <> 0.
    WRITE: / 'Error: ', sy-subrc.
  ELSE.
    WRITE: / 'Success (Status', c_status,
             ') Exitcode: ', n_exitcode.
    LOOP AT tab_btcxpm ASSIGNING <fs>.
      WRITE: / <fs>-message.
    ENDLOOP.
  ENDIF.

Listing 5.28 Ausfhrung von Systemkommandos


REPORT Z_OSCMDINJ2.
PARAMETERS:
  sfilter TYPE String DEFAULT 'compress'.
DATA: lv_dsn TYPE STRING VALUE '/tmp/temp-data.txt'.
OPEN DATASET lv_dsn
  FOR OUTPUT
  IN TEXT MODE
  ENCODING DEFAULT
  FILTER sfilter.
* File operations go here
CLOSE DATASET lv_dsn.

Listing 5.29 OPEN DATASET-Befehl mit betriebssystemspezifischer Option


REPORT Z_OSCMDINJ3.
PARAMETERS:
  scommand TYPE string DEFAULT 'ls'.
CALL 'SYSTEM' ID 'COMMAND' FIELD scommand 
              ID 'TAB'     FIELD rt-*sys*.

Listing 5.30 Aufruf von Systemkommandos mit CALL 'SYSTEM'


REPORT Z_OSCMDINJ4.
PARAMETERS:
  sapplication TYPE string DEFAULT 'notepad.exe',
  sparameter   TYPE string DEFAULT 'c:\test.txt'.
CALL METHOD CL_GUI_FRONTEND_SERVICES=>EXECUTE
  EXPORTING
    application = sapplication
    parameter   = sparameter
  EXCEPTIONS
    CNTL_ERROR = 1
    ERROR_NO_GUI = 2
    BAD_PARAMETER = 3
    FILE_NOT_FOUND = 4
    PATH_NOT_FOUND = 5
    FILE_EXTENSION_UNKNOWN = 6
    ERROR_EXECUTE_FAILED = 7
    SYNCHRONOUS_FAILED = 8
    NOT_SUPPORTED_BY_GUI = 9
    OTHERS = 10.

Listing 5.31 Clientseitiger Aufruf von Systemkommandos mit CL_GUI_FRONTEND SERVICES


REPORT Z_OSCMDINJ5.
PARAMETERS:
  sprogram TYPE string DEFAULT 'notepad.exe',
  scmdline TYPE string DEFAULT 'c:\test.txt'.
CALL FUNCTION 'WS_EXECUTE'
  EXPORTING
    program     = sprogram
    commandline = scmdline
  EXCEPTIONS
    FRONTEND_ERROR = 1
    NO_BATCH = 2
    PROG_NOT_FOUND = 3
    ILLEGAL_OPTION = 4
    GUI_REFUSE_EXECUTE = 5
    OTHERS = 6.

Listing 5.32 Clientseitiger Aufruf von Systemkommandos mit WS_EXECUTE


REPORT Z_CMDOK.
DATA: tab_btcxpm LIKE btcxpm OCCURS 10 WITH HEADER LINE.
CALL FUNCTION 'SXPG_COMMAND_EXECUTE'
  EXPORTING
    commandname                = 'MYCOMMAND'
    additional_parameters      = ''
  TABLES
    exec_protocol              = tab_btcxpm
  EXCEPTIONS
    no_permission              = 1
    command_not_found          = 2
    parameters_too_long        = 3
    security_risk              = 4
    wrong_check_call_interface = 5
    program_start_error        = 6
    program_termination_error  = 7
    x_error                    = 8
    parameter_expected         = 9
    too_many_parameters        = 10
    illegal_command            = 11
    OTHERS                     = 12.

Listing 5.33 Korrekter Aufruf von Systemkommandos


GET / HTTP/1.1
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB;
  rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.10
Host: www.secure-abap.de:8000
Accept: text/html,application/xhtml+xml,
  application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cache-Control: max-age=0

Listing 6.1 HTTP-Request


HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 155
expires: 0
pragma: no-cache
cache-control: no-cache
server: SAP Web Application Server (1.0;700)

Listing 6.2 HTTP-Response-Header


<html>
  <head>
    <title>Willkommen!</title>
  </head>
  <body>
  Willkommen bei der sicheren ABAP-Entwicklung!
  <img src="willkommen.gif">
  </body>
</html>

Listing 6.3 Beispiel fr HTML-Code


var vouchers  = new Array('132L7G23Q1', '2FWLJ0851');
var discounts = new Array(10, 30);

function checkVoucher() {

  var mf = document.myform;
  var total = mf.total.value;
  var voucher = mf.voucher.value;

  var discount = 0;
  var newtotal = total;

  if (voucher.length > 0)  {
    var bF = false;
    i = 0;
    while (!bF && i < vouchers.length) {
      if (voucher == vouchers[i]) {
      bF = true;
        } else {
      i++;
      }
    }
    if (bF) {
      var mydiscount = discounts[i];
      var total = mf.total.value;
      discount = Math.round(total * (mydiscount) / 100);
      newtotal = total  discount;
    }
  }
  mf.discount.value = discount + " EUR";
  mf.discounttotal.value = newtotal + " EUR";
  document.voucherform.voucher.value = voucher;
}

Listing 6.4 Fehlerhaftes Konzept zur Gutscheinverifikation


<input type="text " name="street"
 value="<%=lv_str%>" /><br/>
<input type="text " name="city "
 value="<%=lv_city%>" /><br/>
<input type="text " name="ZIP"
 value="<%=lv_zip%>" /><br/>

Listing 6.5 Variablen werden in HTML-Eingabefelder eingebettet


<% lv_style = request->get_form_field( 'style' ). %>
<link rel="stylesheet" type="text/css"
 href="<%=lv_style%>" />

Listing 6.6 Direkte Einbindung von HTTP-Parametern in eine BSP-Datei


Dies ist eine <b>anonyme</b> Bewerbung.

Listing 6.7 HTML-Quelltext ohne Encoding der Eingaben


Dies ist eine &lt;b&gt;anonyme&lt;/b&gt; Bewerbung.

Listing 6.8 HTML-Quelltext mit Encoding der Eingaben


<%@page language="abap"%>
<% DATA: input TYPE string.
   input = request->get_form_field( 'input' ). %>
<html>
<head></head>
<body>
<H1><%=input%></H1>
</body>
</html>

Listing 6.9 Benutzereingabe zwischen HTML-Tags


<%@page language="abap"%>
<% DATA: input TYPE string,
   input_encoded type string.
   input = request->get_form_field( 'input' ).
   CALL METHOD cl_http_utility=>escape_html
      EXPORTING
         unescaped = input
      RECEIVING
         escaped = input_escaped.
%>
<html>
<head></head>
<body>
<H1><%=input_encoded%></H1>
</body>
</html>

Listing 6.10 Korrekt encodierte Benutzereingabe zwischen HTML-Tags


<%@page language="abap"%>
<% DATA: input TYPE string.
   input = request->get_form_field( 'input' ). %>
<html>
<head></head>
<body>
<img src="abap.gif" height="23" width="<%=input%>">
</body>
</html>

Listing 6.11 Benutzereingabe in HTML-Attributwert


<%@page language="abap" %>
<% DATA: input TYPE string,
             input_encoded TYPE string.
   input = request->get_form_field( 'input' ).
   CALL METHOD cl_http_utility=>escape_html
     EXPORTING
       unescaped = input
     RECEIVING
       escaped   = input_encoded.
%>
<html>
<head></head>
<body>
<img src="abap.gif" height="23"
 width="<%= input_encoded %>">
</body>
</html>

Listing 6.12 Korrekt encodierte Benutzereingabe in HTML-Attributwert


<html>
<head></head>
<body>
<img src="abap1.gif" height="23" width=<%= input %> >
<img src="abap2.gif" height="23" width='<%= input %>' >
</body>
</html>

Listing 6.13 Varianten, um Attributwerte in HTML darzustellen


<%@page language="abap"%>
<% DATA: input TYPE string.
  input = request->get_form_field( 'input' ).
%>
<html>
<head></head>
<body>
<a href="<%=input%>" name="link">My link</a>
</body>
</html>

Listing 6.14 Benutzereingabe in HTML-Attribute, die eine URL beinhalten


<%@page language="abap"%>
<% DATA: input             TYPE string,
         input_encoded     TYPE string.
   input = request->get_form_field( 'input' ).
   CALL METHOD cl_http_utility=>escape_url
      EXPORTING
         unescaped = input
      RECEIVING
         escaped = input_encoded.
%>
<html>
<head></head>
<body>
<a href="<%=input_encoded%>" name="link">My link</a>
</body>
</html>

Listing 6.15 Korrekte Encodierung der Benutzereingabe fr HTML-Attribute, die eine URL enthalten


<%@page language="abap"%>
<% DATA: input TYPE string.
   input = request->get_form_field( 'input' ). %>
<html>
<head></head>
<body>
<script>
  var test='<%=input%>';
  alert(test);
</script>
</body>
</html>

Listing 6.16 Benutzereingabe in JavaScript-Kontext schreiben


<%@page language="abap"%>
<% DATA: input             TYPE string,
         input_encoded     TYPE string.
   input = request->get_form_field( 'input' ).
   CALL METHOD cl_http_utility=>escape_javascript
      EXPORTING
         unescaped = input
      RECEIVING
         escaped = input_encoded.
%>
<html>
<head></head>
<body>
<script>
  var test='<%=input_encoded%>';
  alert(test);
</script>
</body>
</html>

Listing 6.17 Encodierung im JavaScript-Kontext


<form action="change_account.htm">
  <input type="text" name="bname"/>
  <input type="text" name="bcode"/>
  <input type="text" name="bacc"/>
  <input type="submit" />
</form>

Listing 6.18 Beispiel fr Webformular zum ndern von Kontodaten


<%@page language="abap"%>
<% DATA: input             TYPE string,
         input_encoded     TYPE string.
   input = request->get_form_field( 'input' ).
   CALL METHOD cl_http_utility=>escape_url
     EXPORTING
        unescaped = input
     RECEIVING
        escaped = input_encoded.
%>
<html>
<head></head>
<body>
<img src="<%= input_encoded %>">
</body>
</html>

Listing 6.19 Teil einer BSP-Anwendung zum Download von Bildern


<html>
<head></head>
<body>
<img src="https://secure-abap.de/change_account.htm?
 bname=Mybank&bcode=2342&bacc=1337 "/>
</body>
</html>

Listing 6.20 HTML-Seite mit Bild-Tag


<html>
<head></head>
<body>
<form method="POST" name="change_account"
 action=change_account.htm">
  <input type="hidden" name="bname" value="Mybank"/>
  <input type="hidden" name="bcode" value="2342"/>
  <input type="hidden" name="bacc"  value="1337"/>
</form>
<script>
  document.change_account.submit();
</script>
</body>
</html>

Listing 6.21 XSRF-Angriff ber POST-Anfragen


POST /sap(bD1lbiZjPTAwMQ==)/bc/bsp/sap/zvf_flights/
  login.htm HTTP/1.1
Host: www.secure-abap.de:8000
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB;
  rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5
Accept: text/html,application/xhtml+xml,
  application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.secure-abap.de:8000/sap(bD1lbiZjPTAwMQ
  ==)/bc/bsp/sap/zvf_flights/login.htm
Cookie: sap-appcontext= c2FwLXNlc3Npb25pZD1TSUQlM2FBTk9OJTN
  hd3d3X0EwMV8wMCUzYXFMZlQ5Y2hHWVdEcU1rS3dDMUFzNkZEbE1fZThS
  aEhEMWRjcTFhSUstQVRUN3Q%3d%3d; sap-usercontext=sap-client
  =001
Content-Type: application/x-www-form-urlencoded
Content-Length: 76

name=john&password=geheim&return_to_url=&OnInputProcessing%
  28select%29=LoginHTTP/1.1

Listing 6.22 HTTP-Body mit POST-Daten


<form action="zshop.do" method="POST">
  <img src="BOOKPIC.jpg" height="200px" width="150px">
  Price: 60,00 EUR.<br />
  Amount: <input type="text" name="amount" value="1"><br />
  <input type="hidden" name="price" value="60"/>
  <input type="hidden" name="articleID value=2342" />
  <input type="submit" name="add" value="Add to basket" />
</form>

Listing 6.23 Formular mit Hidden Fields


<form action="http://secure-abap.de/sap/bc/bsp/zshop.do"
 method="POST">
  <img src="BOOKPIC.jpg" height="200px" width="150px">
  Price: 60,00 EUR.<br />
  Amount: <input type="text" name="amount" value="1"><br />
  <input type="hidden" name="price" value="1"/>
  <input type="hidden" name="articleID value=2342" />
  <input type="submit" name="add" value="Add to basket" />
</form>

Listing 6.24 Formular mit manipuliertem Hidden Field und genderter Action


<!-- https://secure.secure-abap.de/frameset.htm -->
<% DATA: input             TYPE string,
         input_encoded     TYPE string.
   input = request->get_form_field( 'input' ).
   CALL METHOD cl_http_utility=>escape_url
      EXPORTING
         unescaped = input
      RECEIVING
         escaped = input_encoded.
%>
<html>
    <frameset>
    <frame src="<%= input_encoded %>" />
  </frameset>
</html>

Listing 6.25 Generisches Frameset einer HTML-Seite


HTTP/1.1 200 OK
Date: Sun, 22 Mar 2009 13:06:51 GMT
Server: Microsoft-IIS/6.0
X-AspNet-Version: 2.0.50727
Set-Cookie: client=57cfa4a7-fb37-4628-b97c-86124df2185d;
  domain=.sap.com; expires=Tue, 21-Apr-2009 12:06:51 GMT;
  path=/
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 21578

Listing 6.26 Beispiel fr einen HTTP-Header


[...]
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 21578

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
  Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/
  xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
[...]

Listing 6.27 Ausschnitte aus Header und Body einer HTTP-Nachricht


* Handler OnInitialization:
DATA url TYPE string.
url = request->get_form_field( name = 'url' ).
response->set_header_field( name  = 'Location'
                            value = url ).
response->set_status( code = '302' reason = 'moved' ).

Listing 6.28 BSP-Handler fr Umleitungsfunktion


* Handler OnInitialization:
DATA: value TYPE string,
      name  TYPE string.
name = request->get_form_field( name = 'name' ).
value = request->get_form_field( name = 'value' ).
response->set_header_field( name  = name
                            value = value ).

Listing 6.29 Setzen von HTTP-Headern


myfilter = request->get_form_field( 'myfilter' ).
OPEN DATASET 'c:\test.txt'
  FOR INPUT
  IN BINARY MODE
  FILTER myfilter.

Listing 7.1 Betriebssystemkommandos ber FILTER ausfhren


<htmlb:content forceEncode="ENABLED">
...
</htmlb:content>

Listing 7.2 Sichere Verwendung von HTMLB


<%@page language="abap" %>
<html>
  <% data: style type string.
  style = request->get_form_field( 'style' ). %>
  <a href="menu.htm?style=<%= style %>">Men</a>
</html>

Listing 7.3 Manuell erstellte HTML-Struktur




