commons.sqlescape のソースコード

# coding: utf-8
# 20260802 Sample/Server/Commons/SqlEscape.py(Sample C-030で新設)をフレームワークへ移設
"""
検索条件フック(setSql系)が SQL 文字列リテラルへ値を埋め込む際のエスケープ処理。

■ なぜ通常の「' を '' へ置換」では効かないか

フックが受け取るリクエスト値は、Controller 層の特殊文字変換
(HaluServer commons/specialcharconvert.py editRequestDataToSpecialChar)により
シングルクォート「'」が全角2文字「’’」へ置換済みで、ASCII のクォートは残っていない。
この置換は SQL 文の組み立てが終わったあとに database.py(doGenerateSql)の
editSqlDataToNormalChar が「’’」→「'」へ復元する。

そのためフックが値をそのまま文字列リテラルへ埋め込むと、復元の時点でリテラルが閉じ、
SQL の構造が変わる(SQLインジェクションが成立する)。実測では検索値
「x' OR 'a' LIKE 'a」で WHERE 句が常に真となり全件が返った(C-030)。

■ 対策

リテラルへ埋め込む前に「’’」を2倍化しておくと、復元後に「''」
(SQL標準のエスケープ済みシングルクォート)になり、リテラル内の1文字として扱われる。
ユーザーが全角の「’」を2文字入力した場合も同じ経路で復元されるため、本処理で同時に塞がる。

■ 適用範囲

本処理は「フックが自分で文字列リテラルを組み立てる」場合に必要なもの。
sql.json の input/バインド変数(fieldtype: char / doublequote)経由で埋め込む値は
フレームワーク側が処理するため、本処理を通す必要はない。

利用方法は `from commons.sqlescape import escapeSqlLiteral`(アプリのフックからそのまま
import可能。フレームワークと同一プロセスで動作しLibrariesがsys.path上にあるため)。
"""

# Controller 層の特殊文字変換後における、シングルクォートの表現(全角2文字)
# specialcharconvert.py editRequestDataToSpecialChar の変換表と一致させること
CONVERTED_QUOTE = '’’'


[ドキュメント] def escapeSqlLiteral(value): """ SQL文字列リテラルへ埋め込むリクエスト値をエスケープする Parameters ---------- value : str リクエストデータから取り出した値(Controller層の特殊文字変換済み) Returns ------- escaped : str リテラルへ安全に埋め込める値 """ if value is None: return '' return str(value).replace(CONVERTED_QUOTE, CONVERTED_QUOTE * 2)