ホームページ  >  記事  >  バックエンド開発  >  パスインジェクション攻撃を実行および検出する方法

パスインジェクション攻撃を実行および検出する方法

DDD
DDDオリジナル
2024-10-19 12:33:29901ブラウズ

Cómo Realizar y Detectar Ataques de Path Injection

まず、私はその分野の専門家ではありません。AI ツールを使って学び、楽しんでいます。

そうは言っても…私は友人のために開発を行っていたのですが、彼は銀行取引記録が含まれた 100 枚の PDF を持っていました。後で処理できるように、これらのレコードを Excel に保存する必要があります。

Github コパイロットを使用して、Python といくつかのライブラリを使用してデータ抽出用のスクリプトを作成しました...3 回のドリトス後...そして朝食、昼食、夕食のシステムとして、スクリプトを提供するフラスコ サーバーを構築しました純粋でシンプルな HTML、CSS、JS を使用したフロントのエンドポイントを介して。

Copilot との対話プロセス中に、コードの一部に「パス インジェクション」タイプの脆弱性があるというアラートが生成されました。このアラートは非常に興味深いです :D

そして、コンピューターのセキュリティについてもっと学びたいと思っているので、この旅の記録を残すためにここにブログを書いています...

ここで AI が話し始めます。

攻撃者はユーザー入力を操作して、サーバーのファイル システム上の未承認のファイルまたはディレクトリにアクセスすることにより、パス インジェクションの脆弱性を悪用する可能性があります。これを行う方法の例を次に示します。

パスインジェクションの例

Flask アプリケーションに、ユーザーがファイルをアップロードしてサーバーに保存できるルートがあるとします。ファイル名を検証またはサニタイズしないと、攻撃者が悪意のあるファイル名を送信して、システム上の機密ファイルにアクセスしようとする可能性があります。

脆弱なコード

@app.route('/upload', methods=['POST'])
def upload():
    file = request.files['file']
    filename = file.filename  # Nombre del archivo proporcionado por el usuario
    save_path = os.path.join('uploads', filename)

    # Guardar el archivo sin validar el nombre del archivo
    with open(save_path, 'wb') as f:
        f.write(file.read())

    return 'File uploaded successfully'

パスインジェクション攻撃
攻撃者は、../../etc/passwd などの悪意のあるファイル名を使用してリクエストを送信する可能性があります。これにより、次のルートが生成される可能性があります:

アップロード/../../etc/passwd

サーバーがファイル名を検証またはサニタイズしない場合、ファイルは望ましくない場所に保存され、攻撃者がシステム上の機密ファイルを上書きする可能性があります。

解決策: エントリを検証してサニタイズします
このような種類の攻撃を回避するには、ファイルを保存する前にファイル名を検証し、サニタイズする必要があります。コードの安全なバージョンは次のとおりです:

安全なコード

import os
import re
from flask import Flask, render_template, request, send_file
import requests
from datetime import datetime

app = Flask(__name__)

def sanitize_filename(filename):
    # Eliminar caracteres no permitidos del nombre del archivo
    return re.sub(r'[^a-zA-Z0-9_\-\.]', '', filename)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/upload', methods=['POST'])
def upload():
    file = request.files['file']
    response = requests.post('http://127.0.0.1:5001/pdf-to-excel', files={'file': file})

    # Obtener la fecha actual
    current_date = datetime.now().strftime("%Y%m%d")

    # Obtener el nombre original del archivo sin la extensión
    original_filename = os.path.splitext(file.filename)[0]

    # Sanitizar el nombre del archivo
    sanitized_filename = sanitize_filename(original_filename)

    # Crear el nuevo nombre del archivo con la fecha al final
    output_filename = f'{sanitized_filename}_{current_date}.xlsx'

    # Crear la ruta completa del archivo
    save_path = os.path.join('uploads', output_filename)

    # Asegurarse de que la ruta sea absoluta
    save_path = os.path.abspath(save_path)

    # Guardar el archivo Excel resultante localmente con el nuevo nombre
    with open(save_path, 'wb') as f:
        f.write(response.content)

    # Enviar el archivo Excel de vuelta al usuario con el nuevo nombre
    return send_file(save_path, as_attachment=True, download_name=output_filename)

if __name__ == '__main__':
    app.run(port=5000, debug=True)

安全なコードの説明
ファイル名のサニタイズ: sanitize_filename 関数は、正規表現を使用してファイル名から不正な文字を削除します。

完全なファイル パスの作成: os.path.join 関数を使用して、宛先ディレクトリ (アップロード) とサニタイズされたファイル名 (output_filename) を組み合わせた完全なファイル パスを作成します。

パスが絶対パスであることを確認します。os.path.abspath 関数は、相対パスによる操作を避けるためにパスを絶対パスに変換します。

ファイルの保存: 最後に、ファイルは指定したパスに保存されます。

概要
パス インジェクション: 攻撃者はユーザー入力を操作して、未承認のファイルまたはディレクトリにアクセスできます。
検証とサニタイズ: パス インジェクション攻撃を回避するために、ユーザー入力を常に検証してサニタイズします。
絶対ルート: 相対ルートによる操作を回避するには、絶対ルートを使用します。
これらの実践に従うことで、アプリケーションをパス インジェクション攻撃から保護し、システム全体のセキュリティを向上させることができます。

ここで私は彼に攻撃方法を尋ねました。さらに、これらのケースをデバッグできるようにログを登録しておきました。

パス インジェクション攻撃からアプリケーションを保護するには、これらの攻撃がどのように実行されるかを理解することが役立ちます。ここでは、攻撃者がアプリケーションを悪用しようとする方法と、ログ内のこれらのアクティビティを検出する方法を説明します。

1.ブラウザから

HTML フォームの操作
攻撃者は HTML フォームを操作して悪意のあるファイル名を送信する可能性があります。

ステップバイステップ:

  • ファイルアップロードフォームのある Web ページを開きます。
  • ブラウザの開発者ツール (F12) を使用してフォームを検査します。
  • ファイルフィールドの値を変更して、悪意のあるパス (../../etc/passwd など) を含めます。
  • フォームを送信してください。
  • ログの検出: 受信したファイルの名前をログに記録します。
@app.route('/upload', methods=['POST'])
def upload():
    file = request.files['file']
    filename = file.filename  # Nombre del archivo proporcionado por el usuario
    save_path = os.path.join('uploads', filename)

    # Guardar el archivo sin validar el nombre del archivo
    with open(save_path, 'wb') as f:
        f.write(file.read())

    return 'File uploaded successfully'

2. Postman などのツールの使用

操作された HTTP リクエストの送信
攻撃者は Postman を使用して、細工した HTTP リクエストをサーバーに直接送信できます。

ステップバイステップ:

  • Postman を開き、http://127.0.0.1:5000/upload への POST リクエストを設定します。
  • リクエストの本文で、form-data を選択し、../../etc/passwd という名前のファイルを含むファイル フィールドを追加します。
  • リクエストを送信します。
  • ログの検出: 受信したファイルの名前をログに記録します。

3. 自動スクリプトを使用する

Python スクリプトの使用
攻撃者は Python スクリプトを使用して悪意のある HTTP リクエストを送信する可能性があります。

Python スクリプトの例:

import os
import re
from flask import Flask, render_template, request, send_file
import requests
from datetime import datetime

app = Flask(__name__)

def sanitize_filename(filename):
    # Eliminar caracteres no permitidos del nombre del archivo
    return re.sub(r'[^a-zA-Z0-9_\-\.]', '', filename)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/upload', methods=['POST'])
def upload():
    file = request.files['file']
    response = requests.post('http://127.0.0.1:5001/pdf-to-excel', files={'file': file})

    # Obtener la fecha actual
    current_date = datetime.now().strftime("%Y%m%d")

    # Obtener el nombre original del archivo sin la extensión
    original_filename = os.path.splitext(file.filename)[0]

    # Sanitizar el nombre del archivo
    sanitized_filename = sanitize_filename(original_filename)

    # Crear el nuevo nombre del archivo con la fecha al final
    output_filename = f'{sanitized_filename}_{current_date}.xlsx'

    # Crear la ruta completa del archivo
    save_path = os.path.join('uploads', output_filename)

    # Asegurarse de que la ruta sea absoluta
    save_path = os.path.abspath(save_path)

    # Guardar el archivo Excel resultante localmente con el nuevo nombre
    with open(save_path, 'wb') as f:
        f.write(response.content)

    # Enviar el archivo Excel de vuelta al usuario con el nuevo nombre
    return send_file(save_path, as_attachment=True, download_name=output_filename)

if __name__ == '__main__':
    app.run(port=5000, debug=True)

ログの検出: 受信したファイルの名前をログに記録します。

検出用ログの実装
以下は、疑わしいファイル名を検出するためのログ記録を含む完全な実装です:

@app.route('/upload', methods=['POST'])
def upload():
    file = request.files['file']
    filename = file.filename  # Nombre del archivo proporcionado por el usuario
    save_path = os.path.join('uploads', filename)

    # Guardar el archivo sin validar el nombre del archivo
    with open(save_path, 'wb') as f:
        f.write(file.read())

    return 'File uploaded successfully'

概要
ブラウザから: HTML フォームを操作するか、ブラウザ開発ツールを使用します。
Postman などのツールの使用: 細工された HTTP リクエストをサーバーに直接送信します。
自動スクリプトの使用: Python、Bash、またはその他の言語のスクリプトを使用して、悪意のある HTTP リクエストを送信します。
ログ検出: 受信したファイルの名前とその他の不審なアクティビティをログに記録し、攻撃の可能性を検出します。
これらの対策を実装することで、アプリケーションのセキュリティを向上させ、攻撃の試みを示す可能性のある不審なアクティビティを検出できます。

結論: AI を使用したペア プログラミングを行う学習と開発の状況では、プラットフォーム上のこの種のアラートが脆弱性を検出するのに非常に役立つことがわかりました。今日、目が覚めて Heroku を再デプロイしようと思ったのですが、ここでさまざまな脆弱性を発見していることに気づきました :D

コーディングを楽しんでください!

以上がパスインジェクション攻撃を実行および検出する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。