APEX_ESCAPEパッケージには、データがそれ以降の処理に適するように、文字列内の特殊文字をエスケープする機能が用意されています。
APEX_ESCAPEパッケージでは、次の定数が使用されます。
c_ldap_dn_reserved_chars constant varchar2(8) := '"+,;<=>\'; c_ldap_search_reserved_chars constant varchar2(5) := '*()\/'; c_html_whitelist_tags constant varchar2(255) := '<h1>,</h1>,<h2>,</h2>,<h3>,</h3>,<h4>,</h4>,<p>,</p>,<b>,</b>,<strong>,</strong>,<i>,</i>,<ul>,</ul>,<ol>,</ol>,<li>,</li>,<br />,<hr/>';
このファンクションは、HTML環境でコンテキストが変更される可能性のある文字をエスケープします。これは、既知のsys.htf.escape_scの拡張バージョンです。
ファンクションの結果は、apex_escape.set_html_escaping_modeを使用して定義されるエスケープ・モードによって異なります。デフォルトのエスケープ・モードは「拡張」ですが、これは、手動でset_html_escaping_modeをコールするか、アプリケーションのセキュリティ属性「HTMLエスケープ・モード」を「基本」に設定することで上書きできます。モードが「基本」の場合、ファンクションはsys.htf.escape_scと同様に動作します。そうでない場合は、次のルールが適用されます。
次の表(表10-1)に、このファンクションによって変換されるASCII文字と、その文字がエスケープされた値を示します。
表10-1 変換されるASCII文字がエスケープされた値
| 実際のASCI文字 | 戻されるエスケープされた文字 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
' |
|
|
|
|
構文
APEX_ESCAPE.HTML (
p_string IN VARCHAR2 )
return VARCHAR2;
パラメータ
表10-2に、HTMLファンクションで使用可能なパラメータを示します。
例
この例では、基本(B)モードおよび拡張(E)モードでエスケープをテストします。
declare
procedure eq(p_str1 in varchar2,p_str2 in varchar2)
is
begin
if p_str1||'.' <> p_str2||'.' then
raise_application_error(-20001,p_str1||' <> '||p_str2);
end if;
end eq;
begin
apex_escape.set_html_escaping_mode('B');
eq(apex_escape.html('hello &"<>''/'), 'hello &"<>''/');
apex_escape.set_html_escaping_mode('E');
eq(apex_escape.html('hello &"<>''/'), 'hello
&"<>'/');
end;
このファンクションを使用すると、HTMLのエンティティ属性の値がエスケープされます。これによって、英数字以外および「,」、「.」、「-」、「_」のすべての文字が、16進数でエスケープされます。
構文
APEX_ESCAPE.HTML_ATTRIBUTE (
p_string IN VARCHAR2 )
return VARCHAR2;
パラメータ
表10-3に、HTML_ATTRIBUTEファンクションで使用可能なパラメータを示します。
例
「HTML_TRUNCファンクション」を参照してください。
HTML_TRUNCファンクションは、HTMLをエスケープし、戻される文字列をp_length文字に制限します。このファンクションは、入力CLOBの最初のp_length文字を戻し、それらの文字をエスケープします。このファンクションは、入力CLOBが大きすぎてvarchar2変数に適合できず、入力CLOBの一部の表示のみで十分な場合に使用できます。
構文
APEX_ESCAPE.HTML_TRUNC (
p_string IN CLOB,
p_length IN NUMBER DEFAULT 4000 )
return VARCHAR2;
パラメータ
表10-4に、HTML_TRUNCファンクションで使用可能なパラメータを示します。
例
この例では、タイトルおよびテキスト本文のHTMLリストを生成します。HTMLのエンティティ属性はHTML_ATTRIBUTEを使用して、通常のテキストはHTMLおよびHTML_TRUNCを使用してエスケープされます。
begin
htp.p('<ul>');
for l_data in ( select title, cls, body
from my_topics )
loop
sys.htp.p('<li><span class="'||
apex_escape.html_attribute(l_data.cls)||'">'||
apex_escape.html(l_data.title)||'</span>');
sys.htp.p(apex_escape.html_trunc(l_data.body));
sys.htp.p('</li>');
end loop;
htp.p('</ul>');
end;
HTML_WHITELISTファンクションは、ホワイトリストに指定されているタグを除き、入力テキストのすべての文字でHTMLエスケープを実行します。このファンクションは、入力テキストに単純なHTMLマークアップが含まれる場合に、攻撃者によってクロスサイト・スクリプティングを目的とした悪質なタグが使用されないようにするために有用です。
構文
APEX_ESCAPE.HTML_WHITELIST (
p_html IN VARCHAR2,
p_whitelist_tags IN VARCHAR2 DEFAULT c_html_whitelist_tags )
return VARCHAR2;
パラメータ
表10-5に、HTML_WHITELISTファンクションで使用可能なパラメータを示します。
表10-5 HTML_WHITELISTファンクションのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
フィルタ処理されるテキスト文字列。 |
|
|
|
例
次の例に、HTML_WHITELISTを使用して、ホワイトリストのタグを保持しながら、文字列から不要なHTMLマークアップを排除する方法を示します。
begin sys.htp.p(apex_escape.html_whitelist( '<h1>Hello<script>alert("XSS");</script></h1>')); end;
JS_LITERALファンクションは、JavaScript文字列のエスケープおよび(オプションで)クォートを行います。このファンクションは、影響を受ける文字を\xHHまたは\uHHHHと同等のものに置換します。結果は、<script>タグまたはインライン(「javascript:xxx」)内のJavaScriptコードに挿入できます。影響を受けない文字には、aからz、AからZ、0から9、コンマ「,」、ピリオド「.」および下線「_」が含まれます。
構文
APEX_ESCAPE.JS_LITERAL (
p_string IN VARCHAR2,
p_quote IN VARCHAR2 DEFAULT "" )
return VARCHAR2;
パラメータ
表10-6に、JS_LITERALファンクションで使用可能なパラメータを示します。
表10-6 JS_LITERALファンクションのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
エスケープされるテキスト文字列。 |
|
|
NULL以外の場合、この文字列は結果の左および右に配置されます。引用文字は、一重引用符または二重引用符である必要があります。 |
例
ここでは、JS_LITERALを使用して、l_string変数内の特殊文字をエスケープする方法を示します。
declare
l_string varchar2(4000) := 'O''Brien';
begin
sys.htp.p('<script>'||
'alert('||apex_escape.js_literal(l_string)||');'||'</script>');
end;
このファンクションは、特殊文字をすべてエスケープしたp_stringを戻します。
構文
APEX_ESCAPE.JSON (
p_string IN VARCHAR2 )
RETURN VARCHAR2;
パラメータ
戻り値/発生するエラー
例
次の例では、{ "name": "O\u0027Brien"}と出力します
declare
l_string varchar2(4000) := 'O''Brien';
begin
sys.htp.p('{ "name": "'||apex_escape.json(l_string)||'"}');
end;
LDAP_DNファンクションは、RFC 4514に従って、LDAP識別名の予約文字をエスケープします。RFCでは、"+,;<=>\は予約文字であると説明されています(p_reserved_charsを参照)。これらは、バックスラッシュによってエスケープされます(「becomes \」など)。印字できない文字ASCII 0 - 31およびコード> 127を持つ文字(p_escape_non_asciiを参照)は、\xx(xxは16進文字コード)としてエスケープされます。文字列の先頭または末尾のスペース文字および先頭の#も、バックスラッシュでエスケープされます。
構文
APEX_ESCAPE.LDAP_DN (
p_string IN VARCHAR2,
p_reserved_chars IN VARCHAR2 DEFAULT c_ldap_dn_reserved_chars,
p_escaped_non_ascii IN BOOLEAN DEFAULT TRUE )
return VARCHAR2;
パラメータ
表10-9に、LDAP_DNファンクションで使用可能なパラメータを示します。
表10-9 LDAP_DNファンクションのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
エスケープされるテキスト文字列。 |
|
|
|
|
|
TRUEの場合、 |
例
この例では、l_nameの文字をエスケープし、結果をl_escapedに移動します。
declare
l_name varchar2(4000) := 'Joe+User';
l_escaped varchar2(4000);
begin
l_escaped := apex_escape.ldap_dn(l_name);
htp.p(l_name||' becomes '||l_escaped);
end;
LDAP_SEARCH_FILTERファンクションは、RFC 4515に従って、LDAP検索フィルタの予約文字をエスケープします。RFCでは、*()\/は予約文字であると説明されています(p_reserved_charsを参照)。これらの印字できない文字(ASCII 0 - 31)およびコード> 127を持つ文字(p_escape_non_asciiを参照)は、\xx(xxは16進文字コード)としてエスケープされます。
構文
APEX_ESCAPE.LDAP_SEARCH_FILTER (
p_string IN VARCHAR2,
p_reserved_chars IN VARCHAR2 DEFAULT c_ldap_search_reserved_chars,
p_escape_non_ascii IN BOOLEAN DEFAULT TRUE )
return VARCHAR2;
パラメータ
表10-10に、LDAP_SEARCH_FILTERファンクションで使用可能なパラメータを示します。
表10-10 LDAP_SEARCH_FILTERファンクションのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
エスケープされるテキスト文字列。 |
|
|
|
|
|
TRUEの場合、 |
例
この例では、l_nameのテキストをエスケープし、結果をl_escapedに移動します。
declare
l_name varchar2(4000) := 'Joe*User';
l_escaped varchar2(4000);
begin
l_escaped := apex_escape.ldap_search_filter(l_name);
htp.p(l_name||' becomes '||l_escaped);
end;
p_stringを変更せずに戻します。このファンクションは、SQLインジェクションのdbms_assert.noopと同様、インジェクションの自動検出テストをサイレントで実行する場合に使用します。
構文
APEX_ESCAPE.NOOP (
p_string IN VARCHAR2)
return VARCHAR2 deterministic;
パラメータ
表10-11に、NOOPファンクションで使用可能なパラメータを示します。
例
次の例に、NOOPを使用して、テキストをエスケープしないという開発者の意図を明示的に表す方法を示します。
begin
sys.htp.p(apex_escape.noop('Cats & Dogs'));
end;
このファンクションは、正規表現のコンテキストを変更する可能性がある文字をエスケープします。ユーザー入力を保護するために使用してください。次に、このファンクションによってバックスラッシュ(\)でエスケープされるASCII文字を示します。
\.^$*+-?()[]{|
構文
APEX_ESCAPE.REGEXP (
p_string IN VARCHAR2);
パラメータ
表10-13に、APEX_ESCAPE_REGEXPファンクションで使用可能なパラメータを示します。
例
次の例では、必ずMary-Annの特殊文字"-"がエスケープされ、正規表現エンジンによって無視されます。
declare
l_subscribers varchar2(4000) := 'Christina,Hilary,Mary-Ann,Joel';
l_name varchar2(4000) := 'Mary-Ann';
begin
if regexp_instr(l_subscribers,'(^|,)'|| apex_escape.regexp(l_name)||'($|,)')>0
then
sys.htp.p('found');
else
sys.htp.p('not found')
endif;
end
SET_HTML_ESCAPING_MODEプロシージャは、wwv_flow_escape.htmlのHTMLエスケープ・モードを構成します。
構文
APEX_ESCAPE.SET_HTML_ESCAPING_MODE (
p_mode IN VARCHAR2);
パラメータ
表10-13に、SET_HTML_ESCAPING_MODEプロシージャで使用可能なパラメータを示します。
表10-13 APEX_ESCAPE.SET_HTML_ESCAPING_MODEプロシージャのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
|
例
例は、「HTMLファンクション」を参照してください。