要約
- ロケールは「型 → 文字列変換」のときだけ効く
- HtmlEncodeすると型が失われる
- 日付・数値はエンコード不要
- XSS対策は「出力時」「文字列のみ」
背景
ASP Classic / VBScript の既存システムを、
海外向け環境へのリプレイス作業をしていた際に、
日付の表示が壊れる状況に直面しました。
正確には、HTMLEncordにてエスケープ処理をすると、
海外サーバーの場合日付の表示順が、MM/DD/YYYYとなる内容になります。
はじめに
自己の立場を軽く記載します。
新卒から2年目までWEB系のバック、フロントエンドをRubyで経験。
4年異業種を経験し、再度IT職のSESへ転職しました。
そこでVue、REACTなどモダンな言語を数カ月経験した後に、
現在のASPclassicにアサインという流れになります。
発生した現象
問題のコード
xxEntdate = HtmlEncode(RS("entdate").Value)
同じコードなのに環境によって日付表示が変わってしまいます。
- 日本環境:
2026/01/06 - 海外環境:
1/6/2026
結論:なぜこの問題が起きるのか
ロケールは、
「型 → 文字列」に変換される瞬間にしか効かないためになります。
ロケールが効くタイミング
Classic ASP(VBScript)では
- DBからDATETIME型で取得
- ASP内部でも「日付型」として保持
- 出力時にロケール(LCID)に従って文字列化
<%= RS("entdate") %>
エスケープなしの場合:
- DATETIME型のまま
- 出力直前に変換
- LCID(例:1041 日本)が適用
→結果:2026/01/06
HtmlEncodeが引き起こすこと
HtmlEncode(RS("entdate").Value)
内部ではこうなっています:
- DATETIME型
- (ここでVBScriptが文字列化)
-
"1/6/2026"のような文字列 - HtmlEncode(文字列処理)
→ この時点で、日付型ではなくなってしまうことが要因になります。
なぜ海外環境で壊れるのか
- すでに文字列になってしまう
- ASP側が関与できない
- 表示はブラウザ任せられてしまう
→ HtmlEncodeの時点で、VBScriptにより文字列化され固定されてしまいます。
→そのためASPのロケール(LCID)が適用されるタイミングを失い、
結果として環境依存の表示になってしまいます。
結果:
- 日本:2026/01/06
- 海外:1/6/2026
クロスサイトスクリプティング(XSS)の対策としては?
そもそもXSSとは
ユーザー入力がそのままHTMLとして
実行されてしまう脆弱性のことを指します。
<script>alert('XSS')</script>
上記のコードを例にすると、
入力、DB保存、そのまま表示時に実行という流れになります。
→ 「文字列」として扱うべきものを「HTMLとして解釈させてしまう」
脆弱性のことです。
対策としては
表示時にHTMLエスケープすることで解決します。
データの種類ごとの扱い
| データ | HtmlEncode | 理由 |
|---|---|---|
| ユーザー入力文字列 | ✅ 必須 | XSS対策 |
| 日付(DATETIME) | ❌ 不要 | 型が壊れる |
| 数値 | ❌ 不要 | フォーマット崩れ |
なぜ日付はEncode不要なのか
-
<>'"が含まれない - スクリプトにならない
- DBのDATETIME型
→ XSSリスクはほぼゼロ
対処法
① XSS対策
- 対象:ユーザー入力
- 方法:出力時にHtmlEncode
② ロケール問題
- 対象:日付・数値
- 方法:明示的に日本ロケールを指定
学び
- ロケールは「型 → 文字列変換」のタイミングでしか適用されないです
- HtmlEncodeは文字列処理であり、型の情報を失わせてしまいます
- XSS対策は「出力時」「ユーザー入力の文字列に対してのみ」行うべきです