Fortifyのバグ修正-ログ偽造ログ偽造



Fortify Bug Fixes Log Forging Log Forgery



まず、ログフォージングとは何ですか?

Log Forgingの中国語訳はログ偽造です。つまり、システムのバックグラウンドで出力されるログには、フロントエンドユーザーが入力したコンテンツが含まれます。ユーザーは、特定の記号またはコードを入力して、ログに出力する必要のある通常のコンテンツを改ざんすることができます。

まず、次のコードを見てみましょう。



public void getDemo(HttpServletRequest req, HttpServletResponse resp){ String uri = req.getRequestURI() log.info('get request uri : {}', uri) String requestParams = req.getQueryString() log.info('request query param : {}', requestParams) ... }

このコードは、Fortifyスキャンを実行するときにLogForgingの脆弱性を含むように指示されています。したがって、ServletRequestから取得したパラメータ値は改ざんされている可能性が高いと結論付けることができます。プログラムが検証を実行しない場合は、直接保存されます。ログでは、ログ情報が不正確で不正確になる可能性があります。

次に、Log Forgingの脆弱性の害は何ですか?

まず、脆弱性をスキャンするときにFortifyが脆弱性をどのように説明するかを見てみましょう。



...未確認のユーザー入力をログに書き込みます。これを使用して、攻撃者はログエントリを偽造したり、悪意のあるコンテンツをログに挿入したりできます。たとえば、ユーザーが次の文字列twenty-one%0aINFO:+User+logged+out%3dbadguyを入力すると、1行として出力されるログは、次の2行の情報として出力されます。

情報:val = twenty-oneの解析に失敗しました

情報:ユーザーがログアウトしました= badguy



したがって、ログ改ざんの危険性は、主にシステムログレコードの信頼性と正確性に影響を及ぼし、開発者によるログの解釈を妨げることです。

第三に、ログ偽造の脆弱性を修正する方法は?

3.1Fortifyの推奨事項に従う

特に例外がスローされた場合は、ユーザー入力をログに記録しないでください。例外プロンプト情報をカスタマイズする必要があります。以下は公式の例です。

public static final String NFE = 'Failed to parse val. The input is required to be an integer value.' ... String val = request.getParameter('val') try{ int value = Integer.parseInt(val) } catch(NumberFormatException nfe) { log.info(NFE) }

ご覧のとおり、欠点は明らかです。ログを見ると、hiユーザーが実際に入力した内容を実際に確認することはできません。

3.2特殊文字を置き換える

悪意のあるユーザーがログを改ざんするために使用する方法は、現在、キャリッジリターンまたはラインフィードを入力することでわかっているため、次のコードに示すように、ユーザー入力を印刷するときに特殊文字をフィルタリングする必要があります。

public static String convertValidLog(String log){ List list = new ArrayList() list.add('%0d') list.add(' ') list.add('%0a') list.add(' ') // normalize the log content String encode = Normalizer.normalize(log, Normalizer.Form.NFKC) for(String toReplaceStr : list){ encode = encode.replace(toReplaceStr, '') } return encode } @Test public void convertValidLog(){ String dangerousLogStr = 'this %0d is an %0a apple .' String safeLogStr = 'this is an apple .' assertNotEquals(dangerousLogStr, safeLogStr) assertEquals(FortifyUtils.convertValidLog(dangerousLogStr), safeLogStr) }

このメソッドでは、開発者がユーザー入力を記録するときにこのメソッドを呼び出す必要があります。これは、見逃しやすく面倒です。

もちろん、将来的にログを改ざんする新しい文字が存在する可能性があるため、上記のリストに置き換える必要があることを追加できます。

3.3保存するログコンテンツをコーディングする

ユーザーがログを改ざんする文字を入力する可能性があることがわかっているので、そのようなログを記録するときにユーザーが入力したコンテンツを再エンコードして、ログに実際のユーザー入力を記録し、ログを表示しないようにすることができます。改ざんの問題。次のコードに示すように:

public static void main(String[] args){ String userInput = 'this is an apple.' log.info('user input is : {}', userInput) String encodeStr = '' try{ encodeStr = URLEncoder.encode(userInput, 'utf-8') } catch (UnsupportedEncodingException e){ e.printStackTrace() } log.info('encoded user input is : {}', encodeStr) }

したがって、ログに出力される内容は次のようになります。

user input is : this is an apple. encoded user input is : this+is+an+%0A+apple.

不利な点も明らかです。ユーザーが実際に何を入力しているかを知るには、デコードツールを使用してログ情報をデコードする必要があります。

第四に、まとめ

Log Forgingの脆弱性が高い場合は、上記の提案に基づいて修正するものを合理的に選択することをお勧めします。上記のように修復した後もFortifyスキャンでエラーが報告される場合は、無視してかまいません。

全文が完成しました。