モティオの開発備忘録

ITエンジニアとして働いています。

【PHP】関数sort

ソート関数 sort

sort(array &$array [, int $flags = SORT_REGULAR]) : bool

&$array:ソート対象の配列

$flags:比較の方法

 

比較の方法(第2引数)

設定値 概要
SORT_REGULAR 型を変更せずに値をソート
SORT_NUMERIC 数値としてソート
SORT_STRING 文字列としてソート
SORT_LOCALE_STRING 文字列としてソート(現在のロケールに準拠)
SORT_NATURAL 文字列としてソート(自然順)
SORT_FLAG_CASE 文字列ソートで大文字小文字を区別しない。(「SORT_STRING | SORT_FLAG_CASE」のように、SORT_STRING/SORT_NATURALと組み合わせで利用)

 

第2引数は省略可能だが、原則としてSORT_REGULAR以外の値を明示する。

既定のSORT_REGULARでは、'9.5E2'や'0xE'のように数値として解釈できてしまう文字列が正しくソートされない。

SpringBootプロジェクト起動時にjava.lang.UnsupportedClassVersionErrorで怒られた

久々にJava開発しようと思って、SpringBootプロジェクトを入れて起動しようとしたらプロジェクト起動時に以下のエラーで怒られた...。

以下エラー内容。


    Exception in thread "main" java.lang.UnsupportedClassVersionError: org/springframework/boot/SpringApplication has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 60.0
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1010)
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:855)
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:753)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:676)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:634)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:182)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:519)
	at com.example.MyAppApplication.main(MyAppApplication.java:10)
  

原因

確認したら入れたSpringBootのバージョンは3.1.5だった。SpringBoot3系はJAVAのバージョンが最低でも17ないといけないらしい...。

3.1.5のシステム要件は以下参照。

spring.pleiades.io

対応

新しくJdkをインストールし、設定を行った。今回はAmazonCorretto21系をインストールし、Eclipse上で設定を行った。
パッケージ・エクスプローラー内の「JREシステム・ライブラリー」の上で右クリックし、「プロパティ」を選択。

システム・ライブラリーのメニューから「代替JRE」を選択して、自身のインストールした新しいjdkを適用する。

上記設定後、再度起動を試みると起動できた。めでたし、めでたし。

 

以下の記事は参考にさせていただきました。ありがとうございます。

it-jog.com

セッション管理の不備 脆弱性と対策

今回は、Webセキュリティ脆弱性の中のセッション管理に関する部分について、IPAの資料をもとにおさらいする。

セッション管理の不備

セッションIDの発行や管理に不備がある場合、悪意のある人にログイン中の利用者のセッションIDを不正に取得され、その利用者に成りすましてアクセスされてしまう可能性がある。

悪意のある人は、セッションIDの生成規則を割り出し、有効なセッションIDを推測する。また、わなを仕掛けたり、ネットワークを盗聴したり、利用者のセッションIDを盗みんだりする。

推測や盗用以外に、セッション管理の不備を狙ったもう一つの攻撃手法として、「セッションIDの固定化」と呼ばれるものがある。悪意のある人があらかじめ用意したセッションIDを、何らかの方法で利用者に送り込み、利用者がこれに気づかずにパスワードを入力するなどしてログインすると起こりうる問題。この攻撃に成功すると、あらかじめ用意したセッションIDを利用し、利用者に成りすましてウェブサイトにアクセスすることができてしまう。

発生し得る脅威

  • ログイン後の利用者のみが利用可能なサービスの悪用
    不正な送金、利用者が意図しない商品購入、利用者が意図しない退会処理 等
  • ログイン後の利用者のみが編集可能な情報の改竄、新規登録
    各種設定の不正な変更(管理者画面、パスワード等)、掲示板への不適切な書き込み 等
  • ログイン後の利用者のみが閲覧可能な情報の閲覧
    非公開の個人情報を不正閲覧、ウェブメールを不正閲覧、コミュニティ会員専用の掲示板を不正閲覧 等

注意が必要なウェブサイトの特徴

ログイン機能を持つウェブサイト全般に注意が必要な問題。
ログイン後に決済処理等の重要な処理を行うサイトは、攻撃による被害が大きくなるため、特に注意が必要。

  • 金銭処理が発生するサイト
    ネットバンキング、ネット証券、ショッピング、オークション 等
  • 非公開情報を扱うサイト
    転職サイト、コミュニティサイト、ウェブメール 等
  • その他、ログイン機能を持つサイト
    管理者画面、会員専用サイト、日記サイト 等

根本的解決

  1. セッションIDを推測が困難なものにする
    セッションIDは、生成アルゴリズムに暗号論的疑似乱数生成器を用いるなどして、予測困難なものにする。セッション管理の仕組みが提供されるウェブアプリケーションサーバ製品を利用する場合は、その製品が提供するセッション管理の仕組みを利用している限り、自前でセッションIDを生成する必要はない。

  2. セッションIDをURLパラメータに格納しない
    セッションIDをURLパラメータに格納していると、利用者のブラウザが、Referer送信機能によってセッションIDの含まれたURLをリンク先のサイトへ送信してしまう。悪意のある人にそのURLを入手されると、セッション・ハイジャックされてしまう。セッションIDは、Cookieに格納するか、POSTメソッドのhiddenパラメータに格納して受け渡しするようにする。
    ウェブアプリケーションサーバ製品によっては、利用者がCookieの受け入れを拒否している場合、セッションIDをURLに格納する実装に自動的に切り替えてしまうものがある。そのような機能は、製品の設定変更を行うなどによって、自動切り替え機能を無効化することを検討する。

  3. HTTP通信で利用するCookieにはsecure属性を加える
    ウェブサイトが発行するCookieには、secure属性という設定項目があり、これが設定されたCookieHTTPS通信のみで利用される。Cookieにはsecure属性がない場合、HTTPS通信で発行したCookieは、経路が暗号化されていないHTTP通信でも利用されるため、このHTTP通信の盗聴によりCookie情報を不正に取得されてしまう可能性がある。HTTPS通信で利用するCookieにはsecure属性を必ず加える。かつ、HTTP通信でCookieを利用する場合は、HTTPSで発行するCookieとは別のものを発行する。

  4. ログイン成功後に新しくセッションを開始する
    ウェブアプリケーションによっては、ユーザーがログインする前の段階(例えば、サイトの閲覧を開始した時点)でセッションIDを発行してセッションを開始し、そのセッションをログイン後も継続して使用する実装のものがある。しかし、この実装はセッションIDの固定化攻撃に対して脆弱な場合がある。このような実装を避け、ログインが成功した時点から新しいセッションを開始する(新しいセッションIDでセッション管理する)ようにする。また、新しいセッションを開始する際には、既存のセッションIDを無効化する。

  5. ログイン成功後に、既存のセッションIDとは別に秘密情報を発行し、ページの遷移ごとにその値を確認する
    セッションIDとは別に、ログイン成功時に秘密情報を作成してCookieにセットし、この秘密情報とCookieの値が一致することを全てのページで確認するようにする。この秘密情報の作成にも、生成アルゴリズムに暗号論的疑似乱数生成器を用いるなどして、予測困難なものにする。
    次の場合、本対策は不要。
    ・上記根本的解決4の実装方法を採用している場合
    ・セッションIDをログイン前には発行せず、ログイン成功後に発行する実装のウェブアプリケーションの場合

保険的対策

  1. セッションIDを固定値にしない
    セッションIDは、利用者のログインごとに新しく発行し、固定値にしないようにする。

  2. セッションIDをCookieにセットする場合、有効期限の設定に注意する
    Cookieは有効期限が過ぎるまでブラウザに保持される。このため、ブラウザの脆弱性を悪用する等何らかの方法でCookieを盗むことが可能な場合、その時点で保持されていたCookieが盗まれる可能性がある。
    Cookieの有効期限を短い日時に設定し、必要以上の期間、Cookieがブラウザに保存されないようにする等の対策を取る。
    なお、Cookieをブラウザに残す必要が無い場合は、有効期限の設定(expires=)を省略し、発行したCookieをブラウザ終了後に破棄させる方法もある。しかし、この方法は利用者がブラウザを終了させずに使い続けた場合は、期待する効果を得られない可能性がある。

詳しくは以下参照。

www.ipa.go.jp

パス名パラメータの未チェック/ディレクトリ・トラバーサル 脆弱性と対策

今回もIPAの資料をもとにパス名パラメータの未チェックによる脆弱性と対策についておさらいします。

パス名パラメータの未チェック/ディレクトリ・トラバーサル

ウェブアプリケーションには、外部パラメータからのパラメータにウェブサーバ内のファイル名を直接指定しているものがあります。ファイル名指定の実装に問題がある場合、攻撃者に任意のファイルを指定され、ウェブアプリケーションが意図しない処理を行ってしまう可能性があります。

発生し得る脅威

  • サーバ内ファイルの閲覧・改竄・削除
    重要情報の漏洩、設定ファイル・データファイル・ソースコード等の改竄、削除

注意が必要なウェブサイトの特徴

外部からのパラメータにウェブサーバ内のファイル名を直接指定しているウェブアプリケーションに起こりうる問題です。個人情報等の重要情報をウェブサーバ内にファイルとして保存している場合、特に注意が必要です。

サーバ内ファイルを利用するウェブアプリケーションの例

  • ウェブページのデザインテンプレートをファイルから読み込む
  • 利用者からの入力内容を指定のファイルへ書き込む 等

根本的解決

  1. 外部からのパラメータでウェブサーバ内のファイル名を直接指定する実装を避ける
    上記実装では、そのパラメータが改変され、任意のファイル名を指定されることにより公開を想定しないファイルが外部から閲覧される可能性があります。
    外部からのパラメータでウェブサーバ内のファイル名を直接指定する実装が本当に必要か、他の処理方法で代替できないか等、仕様や設計から見直しましょう。


  2. ファイルを開く際は、固定のディレクトリを指定し、かつファイル名にディレクトリ名が含まれないようにする
    例えば、カレントディレクトリ上のファイル「filename」を開くつもりで、open(filename)の形式でコーディングしている場合、open(filename)のfilenameに絶対パスが渡されることにより、任意のディレクトリのファイルが開いてしまう可能性があります。この絶対パス名による指定を回避する方法として、あらかじめ固定のディレクトリ「dirname」を指定し、open(dirname+filename)のような形でコーディングする方法があります。しかし、これだけでは、「../」等を使用したディレクトリ・トラバーサル攻撃を回避できません。これを回避するために、basename()等の、パス名からファイル名のみを取り出すAPIを利用して、open(dirname+basename(filename))のような形でコーディングして、filenameに与えられたパス名からディレクトリ名を取り除くようにします。

保険的対策

  1. ウェブサーバ内のファイルへのアクセス権限の設定を正しく管理する
    ファイルのアクセス権限が正しく管理されていれば、ウェブアプリケーションが任意のディレクトリのファイルを開く処理を実行しようとしても、ウェブサーバ側の機能でアクセスを拒否できる場合があります。

  2. ファイル名のチェックを行う
    ファイル名を指定した入力パラメータの値から、「/」、「../」、「..\」等、OSのパス名解釈でディレクトリを指定できる文字列を検出した場合は処理を中止します。ただし、URLエンコードした「%2F」、「..%2F」、「..%5C」、さらに二重エンコードした「%252F」、「..%252F」、「..%255C」がファイル指定の入力値として有効な文字列となる場合あるので、チェックを行うタイミングで注意します。

 

詳細はこちらのサイトを参照ください。

www.ipa.go.jp

OSコマンド・インジェクション 脆弱性と対策

今回はwebセキュリティの内のOSコマンド・インジェクションについて、IPAの資料を基におさらいします。

OSコマンド・インジェクション

ウェブアプリケーションによっては、外部からの攻撃のよってウェブサーバーのOSコマンドを不正に実行されてしまう問題を持つものがあります。

発生し得る脅威

  • サーバ内ファイルの閲覧・改竄・削除
    重要情報の漏洩、設定ファイルの改竄 等
  • 不正なシステム操作
    意図しないOSのシャットダウン、ユーザーアカウントの追加・変更 等
  • 不正なプログラムのダウンロード・実行
    ウイルス・ワーム・ボット等への感染、バックドアの設置 等
  • 他のシステムへの攻撃の踏み台
    サービス不能攻撃、システム攻略のための調査、迷惑メールの送信 等

注意が必要なウェブサイトの特徴

外部のプログラムを呼び出し可能な関数などを使用しているウェブアプリケーションに注意が必要です。

外部プログラムを呼び出し可能な関数の例:PHP exec(), shell_exec(), system(), popen 等

根本的解決

  1. シェルを利用できる言語機能の利用を避ける
    ウェブアプリケーションに利用される言語によっては、シェルを起動できる機能を持つものがあります。例えば、Perlのopen関数は引数として与えるファイルパスに「|」(パイプ)を使うことでOSコマンドを実行できるため、外部からの入力を引数として利用する実装は危険です。シェルを起動できる言語機能の利用は避けて他関数で代替します。

保険的対策

  1. シェルを起動できる言語機能を利用する場合は、その引数を構成するすべての変数に対してチェックを行い、あらかじめ許可した処理のみを実行する
    シェルを起動できる言語機能の引数を構成する変数に対して、引数に埋め込む前にチェックをかけ、本来想定する動作を実行するように実装します。

 

今日はOS・インジェクションについて軽くおさらいしました。詳しくは以下のサイトを参照してください。

www.ipa.go.jp

 

SQLインジェクション 脆弱性と対策

webのお仕事を普段させていただいていますが、セキュリティ周りは大切だと思っていても、実際どんな脆弱性があってどんな対策をしないといけないのかを忘れてしまうことがあります。繰り返し学びなおす必要があると感じています。今回は、そんな脆弱性とセキュリティ実装のうち、SQLインジェクションについてIPAが出してくれているドキュメントを見かけたのでそちらを参考におさらいしてみます。

SQLインジェクション

SQLインジェクションは、データベースの脆弱性をついた攻撃です。多くのWebアプリケーションは利用者からの入力情報をもとにSQL文を組み立てますが、SQL文の組み立て方に問題がある場合に、不正に利用されてしまう可能性があります。

発生し得る脅威

SQLインジェクション攻撃で以下の問題が発生する可能性があります。

  • データベースの非公開情報の閲覧
    個人情報の漏洩 等
  • データベースの情報の改竄、消去
    ウェブページの改竄、パスワードの変更、システム停止 等
  • 認証回避による不正ログイン
    ログインしたユーザーに許可されている操作を不正に利用される
  • ストアドプロシージャ等を利用したOSコマンドの実行
    システムの乗っ取り、他への攻撃の踏み台としての悪用 等

注意が必要なウェブサイトの特徴

MySQLやPostgresSQL等のデータベースを利用するウェブアプリケーションは注意が必要です。個人情報などの重要情報をデータベースに格納しているウェブサイトは特に注意が必要です。

根本的解決

  1. SQL文の組み立ては全てプレースホルダで実装する
    SQLが通常もっているプレースホルダを用いてSQLを組み立てる仕組みを利用します。SQL文のひな型の中に変数の場所を示す記号(プレースホルダ)を置いて、後で実際の値を機械的な処理で割り当てる(バインド)ものです。後からバインドすることでSQLインジェクション脆弱性を解消できます。

  2. SQL文の組み立てを文字連結により行う場合は、エスケープ処理などを行うデータベースエンジンのAPIを用いて、SQL文のリテラルを正しく構成する
    SQL文の組み立てを文字連結で行う場合は、SQL文中で可変となる値を定数(リテラル)の形で埋め込みます。値を文字列型として埋め込む場合は、特別な意味をもつ文字列のエスケープ処理をし、数値として埋め込む場合は、数値型であることを確実にする処理をしてから埋め込みを行います。
    また、この処理は外部から入力に影響を受ける値のみならず、SQL文を構成するすべての定数で行うべきです。

  3. ウェブアプリケーションに渡されるパラメータにSQL文を直接指定しない
    例えば、formのhiddenパラメータ等にSQL文をそのまま指定したりするのは避けなければいけません。

保険的対策

  1. エラーメッセージをそのままブラウザに表示しない
    データベースのエラーメッセージの内容をそのままウェブアプリケーションの画面上に表示すると、悪用するための有益な情報源となってしまいます。

  2. データベースのアカウントに適切な権限を与える
    ウェブアプリケーションがデータベースに接続する際に使用するアカウントの権限が必要以上に高い場合、攻撃による被害が深刻化する可能性があります。必要な命令文を洗い出し、命令文の実行に必要な最小限の権限をアカウントに付与します。

 

今回はセキュリティの復習としてSQLインジェクションを取り上げました。
詳しい内容は以下のサイトで見ることができます。

www.ipa.go.jp