2009-08-17 13 views
5

私はASP.netでURL書き換えを実装しています。私のURLは私に世界の問題を引き起こしています。ASP.Net URLエンコーディング

URLは、部門のデータベース&のカテゴリから生成されます。私は従業員がサイトに侵入することなく適切な文字があればデータベースにアイテムを追加できるようにしたいと考えています。

私はURLを構築する前にデータをエンコードしています。それはそれは不可能適切に「/」それで使って何を解析すること、.NETに到達する前に

いくつかの問題があります...

  1. IISは、URLをデコードします。
  2. ASP.netは、私は私のローカルIISサーバー(XPマシン)とエンコード&(%26)を含む任意のURLにテストサーバーで構築から移行
  3. 特定のページに無用のURLづくり「〜」で混乱してしまいます私に「Bad Request」エラーが表示されます。
  4. UrlEncodeは、一部の改行文字に '。'

私はこの問題に関する2つの関連記事を掲載しました。私は "Bad Request"問題を解決するためにいくつかのレジストリを見つけましたが、共有ホスティング環境に展開してそれを役に立たないようにするつもりです。私はこれが何らかのセキュリティ上の問題のための修正であることも知っていますので、私は開かれているワームの何ができるかを知らずに必ずバイパスしたくありません。

.netに生のURLを渡すようにするのではなく、最初に本当に安全なURLを作成したいと考えています。

私は、AntiXss.URLEncode、HttpUtility.URLEncode、URI.EscapeDataStringを試してみました。私はダブルURLEncodngのような愚かなことを試みました。私が必要とするものを行うユーティリティはありますか、本当に自分自身をロールバックする必要がありますか?私はHackyのような何かを、珍しい文字列で置き換えるようなことを検討しています。最初の場所でURL書き換えを使用する点であっても、結果は少なくとも読み取り可能でなければなりません。

申し訳ありませんが、私は必要なすべての詳細が含まれていることを確認したいと思っていました。私はこれに関する関連情報を見つけることができないようで、よくある問題のように思えます - 多分私は大きなものを見逃しています。あなたの助けに感謝し、長い説明と忍耐を!明確にするため


編集:

私はURLは私が何を意味するか、データベースから構築されていると言うディレクトリ構造は、私のデータベース内の部門およびカテゴリからcontstructedされていることです。

いくつかの例のURL -

ディレクトリのmystore /冷凍/バー+ Fridge.aspx
ディレクトリのmystore /料理+ Equipment.aspx
ディレクトリのmystore /キッチン/カット+ Boards.asxpx

問題がでてきます私は、 "Beverage & Bar"や "Pastry/Decorating"のような部門を使って自分のURLを作ります。最初に符号化されているにもかかわらず、これらは前述の問題を引き起こす。

私のハンドラは既に実装されており、特殊文字エンコーディングの問題を除いて正常に動作しています。

+0

を探していると思います私の他の関連posts-ある http://stackoverflow.com/questions/1274669/ url-encoding-being-lost-before-processing-asp-net - 同様の質問ですが、元のリンクにエンコードを固定するのではなく、.netに元のURLを付けるようにしていました。 http://stackoverflow.com/questions/1194900/asp-net-path-problems-caused-by-encoded-urls 「〜」問題を修正しようとするうちに、より大きな問題が発生することがわかりました。 –

答えて

4

カテゴリー/部門テーブルの表を各カテゴリーごとに一意のURLにすることを検討する必要があります。その後、特別なルーチンを使用してURLを生成することができます。これはSQLスカラー関数またはCLR関数にすることができますが、WebのURLを正規化することの1つになります。 「Beverage & Bar」を「Beverage-And-Bar」に、「Pastry/Decorating」を「Pastry-Decorating」に変換できます。主に、ルーチンは無効なHTTP URL文字をすべて別のものに置き換える必要があります。例はこれです:

public static class URL 
{ 
    static readonly Regex feet = new Regex(@"([0-9]\s?)'([^'])", RegexOptions.Compiled); 
    static readonly Regex inch1 = new Regex(@"([0-9]\s?)''", RegexOptions.Compiled); 
    static readonly Regex inch2 = new Regex(@"([0-9]\s?)""", RegexOptions.Compiled); 
    static readonly Regex num = new Regex(@"#([0-9]+)", RegexOptions.Compiled); 
    static readonly Regex dollar = new Regex(@"[$]([0-9]+)", RegexOptions.Compiled); 
    static readonly Regex percent = new Regex(@"([0-9]+)%", RegexOptions.Compiled); 
    static readonly Regex sep = new Regex(@"[\s_/\\+:.]", RegexOptions.Compiled); 
    static readonly Regex empty = new Regex(@"[^-A-Za-z0-9]", RegexOptions.Compiled); 
    static readonly Regex extra = new Regex(@"[-]+", RegexOptions.Compiled); 

    public static string PrepareURL(string str) 
    { 
     str = str.Trim().ToLower(); 
     str = str.Replace("&", "and"); 

     str = feet.Replace(str, "$1-ft-"); 
     str = inch1.Replace(str, "$1-in-"); 
     str = inch2.Replace(str, "$1-in-"); 
     str = num.Replace(str, "num-$1"); 

     str = dollar.Replace(str, "$1-dollar-"); 
     str = percent.Replace(str, "$1-percent-"); 

     str = sep.Replace(str, "-"); 

     str = empty.Replace(str, string.Empty); 
     str = extra.Replace(str, "-"); 

     str = str.Trim('-'); 
     return str; 
    } 
} 

あなたは、このSQL機能を強化させる、または別のプロセスとしてURLの生成を実行することができます。次に、マッピングを実装するには、URL全体を直接カテゴリIDにマップします。このアプローチは、長期的にはいくつかの理由でより優れています。まず、URLを生成するとは限りません。一度やり直すと静的になり、手続きの変更について心配する必要はなく、GoogleBotは古いURLを見つけることができません。また、衝突が発生した場合、重複する可能性のあるカテゴリ名に気付くことがあります。これは、衝突が特殊文字によってのみ異なるためです。最後に、マッピング機能を実行することなく、いつでもデータベースからURLを見ることができます。

+1

これは絶対に完璧です。本当にありがとう、私が認めるよりも時間を節約しました。 –

1

私はいくつかのセキュリティを持っているので、認証された要求を開始するにはglobal.asaxファイルにURLを書き換えます。これは、私が生のURLを取得し、dbルックアップを行います。これは、aspxページへのパスを書き換え、すべてのパラメータはクエリ文字列を渡されます。エンコーディングは必要ありません。

しかし、実際にデータを変更するためにURLを使用している場合は、http GETを使用してデータベースを変更すると大きな問題が発生することがわかります。それは通常、悪いイデオットに似合っています。

私は、任意のデータベース操作を行うために投稿要求を使用します。これは、すべてのデータがページ形式であるため、URLをきれいに保ちます。

唯一の問題は、ほとんどの場合は生のURLであるpage.form.actionに正しいURLを設定することでした。

問題の原因となっているカテゴリ名の場合は、名前をアルファベット文字のみに制限し、スペースを " - "にスワップする必要があります。 IISは、 "。"それはファイル名を探すためです。

P.S. IISはチルダ "〜"を認識しません。これはコンパイラが理解できるものです。したがって、アンカータグで使用すると期待どおりに機能しないので、チルダの代わりにアプリケーションルートを使用する必要があります。

編集:

OK、それはIISのような特定の文字の問題を持つ問題のように見えます。 /および&。たとえあなたがurlencodeを行っても、これらのIISは依然として独自の意味を実装しようとします。

飲料&バーになるBeverageBar

は洋菓子/装飾はPastryDecorating次のようになります。このように ので、それらを削除することを検討します

これはあなたのURLをきれいに保ちますが、データベース内に余分な列があることを意味します。したがって、この短縮されたカテゴリ名に対してURLを騙すことができます。

+0

申し訳ありませんが私は明確にされている必要があります - 私は自分のURLでデータベースの操作をしていません。私の店は部門とカテゴリーに分かれています。ハードコーディングされるのではなく、ディレクトリ構造はデータベースから構築されます。さまざまなメニューには、Mystore/DepartmentまたはMystore/Department/Categoryの形式のリンクがあります。これらのリンクは、要求がIISのhttpHandlerに戻ってくる前に、IISによってエンコードされ、技術的に正しいものが壊れています。 –

+0

それは最高の解決策になるかもしれません。私はちょうど大規模に複雑すぎることがあったかもしれない。私の唯一の関心事は、URLからアイテムを参照できるようにする必要があることです。これは不可逆的なエンコード方法で複雑になる可能性があります。 私の唯一のアイデアは、Uri.EscapeDataString(b).Replace( "%"、 "_")を使用してプログラマの地獄を非難してしまうことです。 あなたの高速応答とこれに助けていただきありがとうございます..私はこれが動作するかどうか見るために私のコードをもう一度見ています。 –

+0

ありがとうございました。これは、複数の回答を受け入れることができないという深刻な不満を抱いている時代の1つです。あなたは正しい方向に私を指摘し、これでトラックに戻ってきた...ありがとう! –

1

私はまったく同じ問題を抱えています。とてもうまく書いてくれてありがとう。それは実際問題をより良く理解するのに役立ちました。

しかし、私はいくつかの考慮事項がありました。私が持っている目標の1つは、記事のタイトルに基づいてURLにあるすべての文字の可能性をサポートすることです。さらに、私は、エンコーディングと2方向エンコード/デコード処理の一意性を確保したいと考えています。

この問題を解決するために手動でエンコードしました。これはエンコード率を完全に排除するものではありませんが、エンコード率を大幅に低下させ、ユーザーがアクセスできないURLを生成しないようにします。私のプロセスは、Server.URLEncode関数を使用して開始します。しかし、これはURLの問題を解消するものではありません。 IISはURLをデコードしてアプリケーションに渡すため、特定の文字は危険なリクエスト例外で破損します。これらの文字には、+, &, /, !, *, ., ()が含まれます。だから、それらの文字に加えて、私はより読みやすくするために他の文字を使用して、私はより便利なURLの二重エンコーディングを行います。エンコードは、URLに許可される文字の数が限られているため、難しいものです。だから私はすべての文字を大文字にした後、小文字でエンコーディングしました。これは完全に解読できないようにしますが、一致させたい値を大文字にすることで、データベースやコード内で簡単に一致させることができます。

さて、ここに私のコードです。フィードバックは高く評価されます。ああ、これはVBで、しかし物事はC#に十分に簡単に転送する必要があります。

Dim strReturn As String = Trim(strStringToEncode) 
strReturn = Server.UrlEncode(strReturn) 

strReturn = strReturn.Replace("-", "dash").Replace("+", "-") 

strReturn = strReturn.Replace("%26", "and"). 
        Replace("%2f", "or"). 
        Replace("!", "excl"). 
        Replace("*", "star"). 
        Replace("%27", "apos"). 
        Replace("(", "lprn"). 
        Replace(")", "rprn"). 
        Replace("%3b", "semi"). 
        Replace("%3a", "coln"). 
        Replace("%40", "at"). 
        Replace("%3d", "eq"). 
        Replace("%2b", "plus"). 
        Replace("%24", "dols"). 
        Replace("%25", "pct"). 
        Replace("%2c", "coma"). 
        Replace("%3f", "query"). 
        Replace("%23", "hash"). 
        Replace("%5b", "lbrk"). 
        Replace("%5d", "rbrk"). 
        Replace(".", "dot"). 
        Replace("%3e", "gt"). 
        Replace("%3c", "lt") 

Return strReturn 
+0

すでに問題が見つかりました。 URLスキャンは、単一のスマート・クォートを拒否します。 – Nate

+0

urlscanを怒らせるような引用が多数見つかりました。これはそれを修正するのに役立ちます。置換( "%e2%80%99"、 "rsquo")。 ( "%e2%80%98"、 "lsquo")を置き換えます。 ( "%e2%80%9d"、 "rdquo")を置き換えます。 ( "%e2%80%9c"、 "ldquo")を置き換えます。 ( "%e2%80%9b"、 "lsrquo")を置き換えます。 ( "%e2%80%9f"、 "ldrquo")を置き換えます。 – Nate

+0

'requestFiltering allowDoubleEscaping =" true "'(http://stackoverflow.com/a/1453287/1178314)や 'httpRuntime requestValidationMode =" 2.0 "relaxedUrlToFileSystemMapping =" true "のようなweb.configパラメータを見てくださいrequestPathInvalidCharacters =" " '。私のユースケースでは、URLでもっと多くの文字をサポートすることができます。 –

0

は、私はあなたがここに完全な情報開示の関心はHttpUtility.UrlEncodeHttpUtility.HtmlDecode

string url = "http://www.google.com/search?q=" + HttpUtility.UrlEncode("Example"); 
+1

情報をお寄せいただきありがとうございます。問題はurlencode/decodeがasp.netまたはiisのいずれかがまだエンコードされたURLを拒否しているために機能しなかったことです。私は代わりに代わりのスキームを使用して終了したと思うが、これはしばらく行っていたので、少しばかげている。 –

関連する問題