ラベル nikto の投稿を表示しています。 すべての投稿を表示
ラベル nikto の投稿を表示しています。 すべての投稿を表示

2025年12月19日金曜日

Python のプロジェクトでやっておくべきセキュリティテスト

Python のプロジェクトでやっておくべきセキュリティテスト

概要

簡単にできるのでとりあえず入れておいて損はしないはず

環境

  • macOS 15.7.2
  • Python 3.12.11
    • bandit 1.9.2
    • safety 3.7.0
    • sqlmap 1.8.2

bandit

  • pipenv install -d bandit
  • pipenv run bandit -r .

セキュアコードのチェックをしてくれます
os.system などインジェクションの危険があるコードを検知できます
random (セキュリティ用途) や assert などの使い方でも警告してくれます

safety

  • pipenv install -d safety
  • pipenv run safety scan

ライブラリなどのセキュリティチェックをしてくれます
アカウント登録が必要なのが辛いです
執筆時点では safety check が DEPRECATED ですが一応使えてこれならアカウント登録不要で使えます

zaproxy

Web アプリであれば導入しましょう
実際にアプリを起動してアプリに対してペネトレーションテストを実行してくれます

https://hawksnowlog.blogspot.com/2025/07/run-zaproxy-with-docker-penetration-test.html

nikto

こちらも Web アプリ用のペネトレーションテストです
zaproxy と結果が異なるので一応入れておいてもいいかもです

https://hawksnowlog.blogspot.com/2025/07/penetration-test-with-nikto-on-docker.html

sqlmap

SQLインジェクションに特化したペネトレーションテストです
公式の docker イメージなどはないようですが parootsec のスポンサードイメージがあるのでそれを使うのが簡単です

--level 5 --risk 3 --batch オプションを追加してもいいかもです

trivy

生成した docker イメージなどに対して行います
インストールされているモジュールやツールが脆弱性を含むバージョンでないかをチェックしてくれます

https://hawksnowlog.blogspot.com/2022/12/trivy.html

Metasploit

Python アプリと言うよりかはホストマシン側のペネトレーションテストです

https://hawksnowlog.blogspot.com/2025/08/how-to-run-metasploit-on-docker.html

fuzzing

特定の関数に対してメモリのオーバフローテストができます

https://hawksnowlog.blogspot.com/2025/12/python-fuzzing-test.html

Python 自体のユニットテスト

ユニットテストやシステムテストでインジェクション系のクエリを投げてテストします

mport pytest
from markupsafe import escape

def test_xss_prevention():
    """ユーザー入力が正しくエスケープされるか"""
    user_input = "<script>alert('xss')</script>"
    result = escape(user_input)
    assert "<script>" not in result
    assert "&lt;script&gt;" in result

def test_sql_injection_prevention(db):
    """SQLインジェクション対策の確認"""
    # SQLAlchemy のバインドパラメータを使用しているか
    malicious_input = "1' OR '1'='1"
    result = db.session.execute(
        text("SELECT * FROM users WHERE id = :id"),
        {"id": malicious_input}
    ).fetchall()
    # 結果は期待値と一致するか確認
    assert len(result) == 0

def test_password_hashing():
    """パスワードがハッシュ化されているか"""
    from werkzeug.security import check_password_hash, generate_password_hash
    password = "test_password_123"
    hashed = generate_password_hash(password)
    assert hashed != password
    assert check_password_hash(hashed, password)

def test_file_upload_validation():
    """ファイルアップロードが検証されるか"""
    from pathlib import Path
    import io
    # 許可されていないファイル型
    fake_pdf = io.BytesIO(b"not a real pdf")
    filename = "malicious.pdf"
    # バリデーション処理が拒否するか確認
    assert not validate_upload(fake_pdf, filename)

flask なら以下のような感じです

import pytest
from flask import Flask
from app import create_app

@pytest.fixture
def client():
    app = create_app()
    app.config['TESTING'] = True
    with app.test_client() as client:
        yield client

def test_csrf_protection(client):
    """CSRF トークン検証"""
    response = client.get('/form')
    assert 'csrf_token' in response.data.decode()
    
    # CSRF トークンなしで POST → 403 エラー
    response = client.post('/form', data={'field': 'value'})
    assert response.status_code == 403

def test_authentication_required(client):
    """認証なしで保護されたエンドポイントアクセス"""
    response = client.get('/dashboard')
    assert response.status_code == 302  # リダイレクト
    assert '/login' in response.location

def test_path_traversal_prevention(client):
    """パストラバーサル攻撃の防止"""
    response = client.get('/files?file=../../etc/passwd')
    assert response.status_code == 403 or response.status_code == 404

def test_injection_attacks(client):
    """SQLインジェクション攻撃の防止"""
    malicious = "1' OR '1'='1'; DROP TABLE users; --"
    response = client.get(f'/search?q={malicious}')
    # 結果が期待通りで、テーブルが削除されていないか確認
    assert response.status_code == 200
    assert 'results' in response.json

有料もしくはアカウント登録必要

SonarQube

Web GUI でテストできます
導入が面倒そうです

Burp Suite

クライアント GUI でテストできます
ペネトレーションテストツールです
かなり複雑な攻撃までできるようです

SBOM (snyk)

trivy のように CLI でチェックできます

最後に

セキュリティ系のテストは一つではなく複数を組み合わせてやることで強度が増します

2025年11月1日土曜日

Gitlab CI で nikto を動かし DAST 的なことをする

Gitlab CI で nikto を動かし DAST 的なことをする

概要

前回 Gitlab CI のサービスを使って Web アプリを起動しそのアプリにテストする方法を紹介しました
今回は nikto を実行してみます

環境

  • Gitlab 18.2.6
  • Gitlab Runner 18.2.2
  • Python 3.12.11

.gitlab-ci.yml

stages:
  - build   # ビルドステージ
  - test    # テストステージ
  - pentest # ペネトレーションテストステージ

build:
  stage: build
  image:
    name: moby/buildkit:rootless  # BuildKit を使用するための Docker イメージ
    entrypoint: [""]  # デフォルトのエントリーポイントを無効化
  variables:
    BUILDKITD_FLAGS: --oci-worker-no-process-sandbox  # BuildKit の設定
  before_script:
    # Docker 認証情報を設定
    - mkdir -p ~/.docker
    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > ~/.docker/config.json
  script:
    # BuildKit を使用して Docker イメージをビルドし、GitLab Container Registry にプッシュ
    - |
      buildctl-daemonless.sh build \
        --frontend dockerfile.v0 \
        --local context=. \
        --local dockerfile=. \
        --output type=image,name=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA,push=true

app:
  stage: test
  services:
    # ビルドした Docker イメージをサービスとして起動
    - name: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
      alias: testapp  # サービスに "testapp" というホスト名を割り当て
  script:
    # サービスが起動するまで待機
    - echo "Waiting for the service to be ready..."
    - >
      for i in {1..30}; do
        curl -s http://testapp:5000 && break || sleep 1;  # サービスが応答するまで最大 30 秒間リトライ
      done
    - echo "Service is ready."  # サービスが起動したことを確認

validate:
  stage: test
  image: curlimages/curl:latest  # curl を使用するための軽量イメージ
  services:
    # ビルドした Docker イメージを再度サービスとして起動
    - name: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
      alias: testapp  # サービスに "testapp" というホスト名を割り当て
  script:
    # サービスに対してレスポンスを検証
    - echo "Running validation tests..."
    - |
      RESPONSE=$(curl -s http://testapp:5000)  # サービスにリクエストを送信しレスポンスを取得
      if [ "$RESPONSE" = "Hello, World!" ]; then
        echo "Validation passed!"  # レスポンスが期待通りの場合
      else
        echo "Validation failed: Expected 'Hello, World!' but got '$RESPONSE'"  # レスポンスが期待と異なる場合
        exit 1  # ジョブを失敗させる
      fi

pentest:
  stage: pentest
  image:
    name: ghcr.io/sullo/nikto:latest
    entrypoint: [""]
  services:
    - name: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
      alias: testapp
  script:
    - echo "Running Nikto penetration test..."
    - mkdir -p reports  # レポートを保存するディレクトリを作成
    - nikto.pl -h http://testapp:5000 -F htm -o reports/report.html
    - echo "Nikto scan completed. Report saved to reports/report.html."
  artifacts:
    paths:
      - reports/report.html  # レポートをアーティファクトとして保存
    expire_in: 1 week  # レポートの保存期間を 1 週間に設定

最後に

Gitlab Ultimate に登録していない場合に DAST が使えないので自分で .gitlab-ci.yml にペネトレーションテスト的なことを記載する必要があります
またレポートも自分で保存する必要があるので artifact を使って保存するようにしましょう

2025年7月31日木曜日

nikto を使ってペネトレーションを実行する方法

nikto を使ってペネトレーションを実行する方法

概要

前回 zaproxy を使ってペネトレーションテストを実行しました
今回は nikto というツールを使ってみます

環境

  • macOS 15.5
  • docker 28.3.2
  • Nikto v2.5.0

実行

docker run --rm -v $(pwd):/tmp ghcr.io/sullo/nikto:latest -h http://host.docker.internal:9292 -F htm -o /tmp/report.html

レポートは open report.html で開きます

最後に

nikto を docker で実行し自分のアプリにペネトレーションを実施する方法を紹介しました
zaproxy と仕組みも全然違し結果も全然違うので別のペネトレーションテストで脆弱性チェックすることで更に堅牢なアプリにすることができます

参考サイト