- 投稿日:2022-02-25T22:51:16+09:00
【翻訳】php_filter_float()の脆弱性について(CVE-2021-21708)
元記事 今回は、こちらの記事を翻訳してみました。 誤訳等ありましたら、コメント欄にて教えていただけますと幸いです。 本編 PHPを利用されている方々は、現在自分が利用しているPHPバージョンが最新かどうか確認しましょう。 PHP7.4 -> 7.4.28 PHP8.0 -> 8.0.16 PHP8.1 -> 8.1.3 上記、PHP最新バージョンが2022-02-17にリリースされました。 最新バージョンでは、php_filter_float関数が原因のuse-after-free脆弱性1(CVE-2021-21708)を含む、複数のメモリ管理に関するバグが修正されています。 脆弱性検証の結果、この脆弱性を突いた攻撃を受けることで、PHPのプロセスが破壊される可能性があります。 また、DoS攻撃(Denial of Service/サービス拒否)2を受ける可能性もあります。 当然、Mozillaがセキュリティアップデートで、脆弱性について定期的に更新しており、 脆弱性が修正された際には、メモリ管理の不整合についても証拠を示していました。 従って、あなた方はそれらの脆弱性が悪用され、悪意のあるコードが実行されるかもしれないと想定しておくべきでした。 外部から送信されたデータを基に行われるリモートコード実行は、一般的にネットワークへの侵入、情報漏洩、マルウェアの増殖を引き起こし、あなたのコンピューター上のプログラムを破壊するだけでなく、プログラム自体の権限を掌握することも可能です。 無効なバリデーションコード 皮肉なことに、PHPのフィルター関数は外部からのデータを検証するために実装されています。 例えば、ユーザーに数値変換が期待通り行われない可能性のある文字列(例:3.14159, 3/16 inch)ではなく、確実に数値(例:5,7,11)を送信してもらうことができます。 今回のCVE-2021-21708は、正しい浮動小数点数(実数・デシマルと呼ばれたりもします。)かどうか検証するコードの一部に原因がありました。 浮動小数点は一般的にドット(国によってはカンマのところもある)を用いて、整数部と小数部を区切ります。 例えば、2.5は「2と10分の5」または「2と0.5」といったように表すことができます。 PHPの数値フィルター関数は外部から受け取った数値が正しいかだけでなく、2.718283より大きくないことや-1と1の間の数値であることも判定することができます。 もし、受け取った数値が既に浮動小数点数(またはデシマル)である場合、下記に示すコードを利用してデータを検証します。 画像左側が古いPHPバージョン(8.1.2)で右側が新しいPHPバージョン(8.1.3)のコードです。 そのコードにバグはありません。 従って、古いバージョンでも新しいバージョンでも、正しく動作します。 もし、あなたがC言語について知らなかったとしても心配無用です。 ここで覚えておくべきことは、以下の3つの動作が行われているということです。 エラーのチェックを行う。 PHPで使用されているメモリを値保持のために解放する。 解放したメモリを検証した値に再度割り当てる。 疑問に思ってる方がいらっしゃるかもしれませんが、zval_ptr_dtor()という関数は、PHPの内部メモリポインターデストラクターの短縮形です。 4 道を渡ることに例えると、下記の順序です。 左右安全確認(エラーチェック) 安全確認後、道路横断開始(メモリ解放) 安全に横断完了(メモリ再割り当て) もし、受け取った数値が小数点を含まない整数の場合、バリデーションに使用されるコードが少し異なります。 下記を見ていただけるとわかるように、「エラーチェック→メモリ解放->メモリ再割り当て」の順序が、古いPHPバージョンでは間違っています。 古いPHPバージョンでの順序は、下記の通りです。 PHPで使用されているメモリを値保持のために解放する。 エラーのチェックを行う。 解放したメモリを検証した値に再度割り当てる。 上記順序では、解放したメモリ領域に本来入るべきでない値やコードが割り当てられてしまいます。 その結果、use-after-free1攻撃に繋がります。 仮にエラーなく検証が完了した場合、検証済の値保持には、解放したメモリ領域ではなく、新しい領域が割り当てられます。 この順序を道を渡ることに例えると、下記のようになります。 道路横断開始(メモリ解放) 左右安全確認(エラーチェック)<-- 危ない 安全に?横断完了(メモリ再割り当て) PHP8.1.3のコードでは、その順序は正しく修正されています。 しかし、デストラクター5とアロケーター6の呼び出しを一本化する関数(例えば、dtor_and_alloc_in_one_go())があれば、より安全なコードになることでしょう。 なぜなら、未来のプログラマーたちが順序を誤ってコードを書き込むことが無くなるからです。 PHP8.1.3のコードの順序は、以下の通りです。 左右安全確認(エラーチェック) 安全確認後、道路横断開始(メモリ解放) 安全に横断完了(メモリ再割り当て) Visual Studio Codeで作成されたコード差分を見ると、左側(PHP8.1.2)の赤い線で示された処理(メモリ解放)が、右側(PHP8.1.3)では、緑の線下部に移動していることがわかります。 4 PHP8.1.2(左側・脆弱性あり) 道路横断開始(メモリ解放) 左右安全確認(エラーチェック)<- 危ない!!!! 安全に?横断完了(メモリ再割り当て) PHP8.1.3 (右側・脆弱性修正済) 左右安全確認(エラーチェック) 安全確認後、道路横断開始(メモリ解放) 安全に横断完了(メモリ再割り当て) あなたができる事 もし、あなたがPHPを使っている場合 PHPを最新バージョンに更新しましょう。 PHP7.4 -> 7.4.28 PHP8.0 -> 8.0.16 PHP8.1 -> 8.1.3 もし、PHPをあなたの代わりに管理してくれるLinuxディストリビューションを利用している場合は、各ディストリビューションの詳細を確認してください。 もし、あなたがプログラマーの場合 今回のようなわかりづらい脆弱性にいち早く気付くためにも、 C言語で書かれているコードは常にメモリを気にかける必要があることを覚えておいてください。 もし、あなたがプログラマーの場合 コードを書く際には、後発のプログラマーがエラーを誘発する可能性が少ないコーディングを心がけてください。 開放したメモリに対して(脆弱性により)再びアクセス、実行することが可能となることを悪用した攻撃のこと。 ↩ ↩2 1台の機器から、対象の機器に過剰な負荷をかける攻撃 ↩ ネイピア数は、数学定数の一つであり、自然対数の底である。ネーピア数、ネピア数とも表記する。記号として通常は e が用いられる。その値は e = 2.71828 18284 59045 23536 02874 71352 … と続く超越数である。 ↩ 左側がPHP8.1.2 右側がPHP8.1.3 ↩ ↩2 オブジェクト指向プログラミング言語でオブジェクトを削除する際に呼び出されて後処理などを行なう関数あるいはメソッドのこと。C++やDelphiにおいてサポートされている。 ↩ オペレーティングシステムの構成要素の一つで,プログラムの実行に際してメモリや周辺装置などの割り当てを行なうルーチン ↩
- 投稿日:2022-02-25T20:44:31+09:00
【WordPressセキュリティ対策】投稿者アーカイブを無効化してWordPressのユーザ名を隠す方法
WordPressで構築したサイトのアクセスログを見ると、ページには表示させていないのに何故かログインアカウントでアタックされている場合があります。 これはWordPressが自動生成する投稿者アーカイブが有効になっているからです。攻撃者はこの機能を悪用して不正ログインを試みます。 投稿者アーカイブとは 投稿者アーカイブとは、WordPress が自動生成する投稿者ごとの投稿をまとめる機能のことです。 ちょっと技術的なことを言うと、テーマのauthor.phpに規定されているページのことです。 初期状態のWordPressでは投稿者ごとに投稿者アーカイブが作成されます。そのため、WordPressのユーザー名が閲覧者にバレてしまい、大いなるセキュリティの穴となることがあります。 投稿者アーカイブを見る方法 WordPressサイトで、以下のようなURLにアクセスすると、対象ユーザーが作成した投稿の一覧ページが表示されます。 http://example.com/author/ユーザー名/ また、以下のように?author=1を付けてアクセスすると、ユーザーIDが1のユーザーの投稿者アーカイブにリダイレクトされます。 リダイレクト先のURLには管理者のユーザー名が含まれるので、WordPressのログインIDがわかってしまいます。 http://example.com/?author=1 投稿者アーカイブのURLの危険性 投稿者アーカイブのURL内にログインアカウント名が公開されていることになります。 ユーザー名は管理画面のログインに必要となる重要なデータです。不正ログインを試みるには大きな手掛かりになります。あとはパスワードさえ突破すれば不正ログインに成功です。 ブルートフォースアタック(総当たり攻撃)という攻撃手法を用いて、手あたり次第パスワードを利用してログインを試されたら、簡単なパスワード「1111」「1234」「password」などではあっという間にログインされてしまいます。 ちなみに、投稿者のニックネームを設定していても変わりません。 ニックネームを設定していると、投稿ページをはじめとしたフロントページではユーザー名は表示されないので安心なのですが、投稿者アーカイブのURLに限っては、ニックネームで上書きされることはなくユーザー名のままとなります。 また、投稿ページやフロントページに投稿者アーカイブへのリンクを載せない場合もあるでしょう。 しかし、投稿者アーカイブが存在している以上、URLから直接アクセスされたらユーザー名はバレてしまいます。 投稿者アーカイブを無効化する 投稿者アーカイブは次のいずれかの方法で無効化することができます。 author.phpを使用する方法 functions.phpを使用する方法 プラグインを使用する方法 今回は、「author.phpを使用する方法」と「functions.phpを使用する方法」を紹介します。 functions.phpを使用する方法 functions.phpを利用すると簡単に無効化することが出来ます。 適用しているテーマのfunctions.phpに以下のコードを追加します。コピペでOKです。 add_filter( 'author_rewrite_rules', '__return_empty_array' ); function disable_author_archive() { if( preg_match( '#/author/.+#', $_SERVER['REQUEST_URI'] ) ){ wp_redirect( esc_url( home_url( '/404.php' ) ) ); exit; } } add_action('init', 'disable_author_archive'); 上記のコードをfunctions.phpに追加すると、投稿者アーカイブにアクセスすると404エラーにリダイレクトされるようになります。 これで、投稿者アーカイブが無効化されます。 リダイレクト先を404エラーから変更する場合には、wp_redirect()で指定しているURLを変更してください。 例えば、以下のように記述した場合には、投稿者アーカイブにアクセスするとトップページにリダイレクトされるようになります。 wp_redirect( esc_url( home_url('/') ) ); author.phpを使用する方法 投稿者アーカイブのテンプレートauthor.phpを使用して投稿者アーカイブを無効化する方法もあります。 適用しているテーマのauthor.phpに以下のコードを追加します。コピペでOKです。投稿者アーカイブにアクセスさせないようにすることで無効化する方法です。 add_filter( 'author_rewrite_rules', '__return_empty_array' ); テーマによってはauthor.phpがない場合があります。 適用しているテーマにauthor.phpがない場合には、author.phpを作成してください。 最後に ログインIDがバレても問題ない、そんなことよりパスワードを強化すべきだ、という意見もあります。 もちろん、パスワードを強化することも非常に重要です。 投稿者アーカイブを無効化したら不正ログインに防げる訳ではないので、セキュリティ強度の高いパスワードを設定することも併せて対応するようにしてください。 また、投稿者アーカイブを無効化しても、WordPress標準のXMLサイトマップ機能で出力されるXMLサイトマップには、投稿者アーカイブのURLも含まれています。 現時点では標準のXMLサイトマップ機能は細かい制御ができないため、投稿者アーカイブのURLだけ除外したりすることが出来ません。 投稿者アーカイブを無効化する処理と一緒に、標準のXMLサイトマップ機能を無効化する処理も実装しておくのがお勧めです。 標準のXMLサイトマップ機能を無効化する方法は、以下の記事で紹介しています。 WordPress5.5で標準搭載されたXMLサイトマップ機能を無効化する方法
- 投稿日:2022-02-25T20:41:47+09:00
WordPress5.5で標準搭載されたXMLサイトマップ機能を無効化する方法
WordPress5.5からXMLサイトマップを出力する機能が標準で追加されました。 Google XML Sitemapsとか別のプラグインを使ってXMLサイトマップを出力している場合が多いと思います。 そういったすでに使っている機能が重複しないよう、標準のXMLサイトマップ機能を無効にする方法をまとめておきます。 追加されたXMLサイトマップ機能 はじめに、新たに標準搭載されたXMLサイトマップ機能についての説明です。 XMLサイトマップ機能はWordPress5.5から自動で有効になっていて、wp-sitemap.xmlというファイル名でアクセスできます。 $ドメイン/wp-sitemap.xmlというURLにアクセスすると、下記のようなサイトマップが表示されます。 補足事項 wp-sitemap.xmlは正確にはサイトマップインデックスファイルです。 固定ページや投稿、著者といった種類別に分割された別のサイトマップファイルへのリンクが一覧表示されます。 何の用意をしなくてもXMLサイトマップが出力されるので便利そうにも感じますが、 標準のXMLサイトマップ機能にはごく基本的な機能しかなく、例えば以下のようなカスタマイズは出来ません。 「このページはサイトマップに含めたくない」といったページやアーカイブ毎の指定ができない。 lastmod や changefreq、priority といった要素を設定できない。 このような細かい制御もしたい場合には、現状ではプラグインでXMLサイトマップ機能を実装する必要があります。 プラグインを使用する場合には、機能が重複する標準のXMLサイトマップ機能は無効にしておきたいところです。 以下、無効化する方法について説明します。 標準のXMLサイトマップ機能を無効化する方法 標準のXMLサイトマップ機能を無効化するには、functions.phpに下記コードを追記します。 add_filter( 'wp_sitemaps_enabled', '__return_false' ); 上記のコードを追加後にwp-sitemap.xmlにアクセスすると、404ページとなりXMLサイトマップが表示されなくなります。 上記のコードでは、見た目上ではXMLサイトマップが見られなくなりますが、XMLサイトマップ機能は有効になっています。 以下のコードを追記するとXMLサイトマップ機能自体を無効化することが出来ます。 remove_action( 'init', 'wp_sitemaps_get_server' ); 上記のコードを追加後にwp-sitemap.xmlにアクセスすると、404ではなくTOPページが表示されるようになります。 標準のXMLサイトマップ機能の危険性 標準のXMLサイトマップ機能で出力されるXMLサイトマップには、投稿者アーカイブのURLも含まれています。 投稿者アーカイブのURL内にログインアカウント名が含まれているため、XMLサイトマップでログインアカウント名が公開されていることになります。 現時点では標準のXMLサイトマップ機能は細かい制御ができないため、投稿者アーカイブのURLだけ除外したりすることが出来ません。 ユーザー名は管理画面のログインに必要となる重要なデータです。不正ログインを試みるには大きな手掛かりになります。 あとはパスワードさえ突破すれば不正ログインに成功です。 WordPressセキュリティ対策の観点からみても、標準のXMLサイトマップ機能は無効化しておいた方が良いと思います。 ちなみに、投稿者アーカイブにアクセスできないように無効化する処理を実装しても、標準のXMLサイトマップ機能では投稿者アーカイブのURLも含まれた情報が出力されてしまいます。 参考 New XML Sitemaps Functionality in WordPress 5.5
- 投稿日:2022-02-25T19:58:20+09:00
【WordPress】前後記事のさらに前後記事データを取得して出し分けをする方法
はじめに Web制作会社のエムハンドでエンジニアをしてる@yokinoです。 WordPressで前後記事のさらに前後記事データを取得して出し分けをする方法について書きます。 WordPressの記事ページに、前後記事へのリンクを設置することがありますが、 たまに記事によっては「直接外部サイトに飛ばしたい」「PDFに飛ばしたい」といった要望があります。 それらはカスタムフィールドを用いて実装することができますが、 要望にあるような記事にはデータは存在するものの、記事ページでは本文が空っぽになっています。 できれば前後記事リンクではそういった記事ページは飛ばして、通常の記事ページをリンク先に設定したいですよね。 この記事では、前後記事が「外部サイトへ飛ばす記事」か「PDF記事」のとき、 さらに前後記事を取得して通常の記事をリンク先に設定する方法をまとめます。 カスタムフィールドの設定 プラグインAdvanced Custom Fieldsで「外部URL」と「PDF」フィールドを作成します。 フィールド名はそれぞれ、post_url, post_pdfとします。 ベースのhtml ベースになるhtmlを書きます。 <ul class="c-pager02"> <li class="c-pager02__prev"><a href="">前へ</a></li> <li class="c-pager02__next"><a href="">次へ</a></li> <li class="c-pager02__all"><a href="">一覧へ</a></li> </ul> phpとhtml php $main_post = $post; //$postを入れておく $prev_post = get_previous_post(); // 前の記事を取得 $next_post = get_next_post(); // 次の記事を取得 //前の記事があるか if ( $prev_post ) { while(true) { //外部URLとPDFがないならその記事を設定すればいいので必要なデータを返し、ループを終了 if ( !get_field( 'post_url', $prev_post->ID ) && !get_field( 'post_pdf', $prev_post->ID ) ) { $prev_flag = true; $prev_url = get_permalink( $prev_post->ID ); break; //外部URLとPDFのどちらか一方が存在するとき、さらに過去の記事のデータを見に行く } elseif ( get_field( 'post_url', $prev_post->ID ) || get_field( 'post_pdf', $prev_post->ID) ) { $prev_flag = false; $post = $prev_post; //前の記事をグローバル$postに上書き $prev_post = get_previous_post(); //上書きしたpost(前の記事)の前の記事を取得 if ( !$prev_post ) { //前の記事がないなら処理終了 break; } } } } //次の記事があるか if ( $next_post ) { while(true) { //外部URLとPDFがないならその記事を設定すればいいので必要なデータを返し、ループを終了 if ( !get_field( 'post_url', $next_post->ID ) && !get_field( 'post_pdf', $next_post->ID) ) { $next_flag = true; $next_url = get_permalink( $next_post->ID ); break; //外部URLとPDFのどちらか一方が存在するとき、さらにあとの記事のデータを見に行く } elseif ( get_field( 'post_url', $next_post->ID ) || get_field( 'post_pdf', $next_post->ID) ) { $next_flag = false; $post = $next_post; //次の記事をグローバル$postに上書き $next_post = get_next_post(); //上書きしたpost(次の記事)の次の記事を取得 if ( !$next_post ) { //次の記事がないなら処理終了 break; } } } } $post = $main_post; //$postをもとに戻す html <ul class="c-pager02"> <?php if ( $prev_post && $prev_flag ) : ?> <li class="c-pager02__prev"><a href="<?php echo $prev_url; ?>">前へ</a></li> <?php endif; ?> <?php if ( $next_post && $next_flag ) : ?> <li class="c-pager02__next"><a href="<?php echo $next_url; ?>">次へ</a></li> <?php endif; ?> <li class="c-pager02__all"><a href="">一覧へ</a></li> </ul> ざっくり解説 まずグローバル変数$postを別の変数に入れておく。 get_previous_post()とget_next_post()はグローバル変数$postにある前後の記事情報を取得してくれる。 つまり$postを前後の情報で上書きした状態でget_previous_post()とget_next_post()を実行すれば、さらに前後の記事情報を取得できる。 取得した記事に「外部URL」または「PDF」が設定されていれば、$postを上書きしてさらに前後の記事を取得する。 通常の記事または記事がなくなるまで処理をさせる。 最後には$postを元に戻すために、予め別の変数に入れておいた$postで$postを上書きする。 さらに 表示上では良い感じになりましたが、外部URLだろうがPDFだろうが、そのための記事ページは存在しています。アクセスできてしまいます。 もしもXML Sitemapsなどでsitemap.xmlに含まれていた場合はクロールの対象になります。 都度除外設定するのは手間がかかるので、そういったページにアクセスがあった場合は一覧ページにリダイレクトさせるか、設定した「外部URL」や「PDF」に飛ばす処理をsingle.phpに入れておきましょう。 ※get_header()よりも前に single.php //一覧にリダイレクトさせる場合 if ( get_field( 'post_url' ) || get_field( 'post_pdf' ) ) { wp_redirect( home_url() . '/xxx/', 301 ); exit; } //外部URLにリダイレクトさせる場合 if ( get_field( 'post_url' ) ) ) { wp_redirect( get_field( 'post_url' ), 301 ); exit; } //PDFにリダイレクトさせる場合 if ( get_field( 'post_pdf' ) ) ) { wp_redirect( get_field( 'post_pdf' ), 301 ); exit; } おわりに 以上が前後記事のさらに前後記事データを取得して出し分けをする方法でした。 WordPressサイトを構築するうえで、よく使う関数が何をやっているのか、実行するとどういったデータを返してくれるのか、 実装することで他にどういった影響があるのかを調べたり考えれるようになると応用がききます。 一つの答えに導いたときの達成感を得ることができます。とても楽しいですね。
- 投稿日:2022-02-25T19:13:59+09:00
【個人開発】教員向け授業計画作成サービスを作ってみた。
はじめに こんにちは、まーです。 【Twitter】 https://twitter.com/KPz234iNYoOQZF5 【今回作成したサービス】 https://teachingplan.msy-a.com/ 今回は、以前Laravel+Vue.jsで作成した授業計画(指導案)作成サービスをご紹介したいと思います。 要件概要 ○導入 日々多忙な教員にとって毎回の授業内容(指導案)をスピーディーに作成することはとても重要になります。 特に、教育実習生や教員になったばかりの先生は、授業の経験値がなく、毎時間授業の計画を考えることは大きな負担です。自分自身の教育実習に行った経験、教員の友人からのヒアリングから間違いないと思います。 授業計画を効率的に作成することは、授業の質に関わり、それは授業を受ける子どもたちの成長にも関わってきます。 ○そもそも?(問題点) 世の中にタスク管理アプリはたくさんありますが、 「指導案を作成する」ことに特化したサービスはありません。現場の先生方は、効率的に指導案を作成することができていません。 ○なぜなら?(問題点の裏付け) 指導案を作るために、紙やWordの雛形に毎回書き込んでいるのが現場の現状です。 (ひと昔前の教育実習生は、手書きで書いた指導案がボツになり、指導教官に目の前で破り捨てられ、書き直しさせられたなんて話も…) ○だから?(課題) そのため、WEBサービスを利用し、 「効率的に指導案を作成するべき」だと考えます。 ○そこで!(改善策) 効率的に指導案が作成できるサービスがあったらどうだろうか?と考えサービスを作成しました。 サービス概要 1.授業を登録 ユーザー登録後にマイページから授業を登録します。 単元名、日付、時限、本時の目標を登録します。 2.授業の詳細を登録 授業詳細画面で、授業計画を作成していきます。 デフォルトで、「導入」、「展開」、「まとめ」の構成になっています。 追加ボタンを押してタスクを追加していきます。 3.タスクの注意事項を確認 タスクにはそれぞれ、学習活動、時間、留意点が登録できます。 今回は、サクッと授業計画を作ることが目的なので最低限のものだけにしました。 使用技術 PHP 7.4.12 Laravel 5.8.38 JavaScript Vue.js 2.5.17 CSSフレームワーク Bootstrap フロントライブラリ jQuery axios lodash chart.js vue-chartjs vuedraggable テスト PHPUnit mocha テーブル設計 工夫した点 非同期処理でユーザビリティを上げる Vue.jsでaxiosを使用し、タスクの登録・削除を行なっています。 非同期で処理を行うことでサクサク動き、ユーザーにストレスを与えないようにしました。 ドラッグ&ドロップで直感的な操作 タスクをドラッグ&ドロップで移動できるようにしました。 vuedraggableを使って、ドラッグ&ドロップされるたびに、タスクの並び順を非同期通信で書き換えています。 授業の計画を変更したい場合にも、直感的に変更できます。 授業の時間配分をグラフで可視化 「導入」、「展開」、「まとめ」の時間配分を円グラフで可視化しています。 vue-chartjsを使用し、タスクを登録・削除・移動したときにリアルタイムでグラフが描画されます。 おわりに 最後までお読みいただきありがとうございました! ITには社会の問題を解決する力があると思っています。 これからも学んで色んな問題を解決できたらと思います。 それでは!
- 投稿日:2022-02-25T17:24:10+09:00
Magentoのセキュリティは、サニタイズの脆弱性を修正するための追加パッチが必要です
本記事は2022年2月24日に@developersteveが公開した英語ブログMagento security requires additional patch to fix sanitization vulnerabilityを日本語化した内容です。 なお本ブログは、CVE-2022-24086 Magento Ecommerce を使用しているウェブサイトに対する脆弱性警告で発表した内容から更新されている情報について記載しています。 私たちはしばしば、技術者として、デプロイされたコードの修正、インフラストラクチャーコンポーネントの更新、コードのパッチ適用などのプレッシャーにさらされることがあります。多くの場合、それはほとんど知らされることはなく、5分前に実行する必要があります。このような「ゼロターンアラウンド」は、テストやチェックに時間をかけることなく、今すぐ修正だけすることを急ぐという、ある種の賭けのようなものです。 先日、多く利用されている電子商取引プラットフォーム「Magento」にセキュリティ研究者によって重大な問題が発見され、Magento Ecommerce、Magento Open Source、Adobe Commerceの各バージョンに重要なパッチがリリースされました。CVE-2022-24086で確認された脆弱性では、未認証のユーザーに対して、チェックアウト時にSQLインジェクションやPHPオブジェクトインジェクションの悪用を可能とする方法が確認されました このため、Adobeのセキュリティ部門が初期パッチを展開し、迅速に修正プログラムを実行に移しました。数日後、研究者がこのパッチではコードの緩和が不十分であることを発見し、新たにCVE-2022-24087が起こり、2回目のパッチが生成されることになったのです。 新たに確認された脆弱性については、Adobe社からの最新のセキュリティ警告でパッチが提供されています。この新しいパッチは、元のCVE-2022-24086のパッチに追加して適用する必要があります。 私がアプリケーションセキュリティの領域で好きなことの1つは、デプロイメント、ライブラリ、およびプラットフォームのエンドユーザーに影響を与える可能性のあるあらゆるものに対するデューデリジェンスです。そこで、最新のパッチを調べて、何が変わったのかを見てみましょう。 CVE-20220-24087 パッチ適用を熟読する 新しいパッチであるMDVA-43443に触れる前に、オリジナルのパッチであるMDVA-43395を再確認し、その内容を理解しましょう。 ここで重要なのは、どちらの脆弱性も Magento Open Source と Adobe Commerce の 2.3.4 以上 2.4.5-p1 または 2.3.7-p2 未満のバージョンにのみ影響するという点です。 オリジナルのパッチ(MDVA-43395)は、Magentoショップのアプリケーションロジックのチェックアウトフローにおいて、新たに安全なユーザー入力のサニタイズ処理を追加しています。/Email/Model/Template/transDirectiveと VarDirective.phpの両方にpreg_replace()とpreg_match()パターンが追加され、不要なユーザー入力の文字種をサニタイズするのに役立つようになりました。 パッチが配布された後にセキュリティ研究者が発見したのは、攻撃ベクトルを阻止するための緩和措置としては不十分であり、実際にはフレームワークにさらに深い脆弱性が現れる可能性があるということです。 新しいパッチ(MDVA-43443)は、sanitizeValue()という再利用可能なフレームワーク関数を追加するもので、 \MagentoFrameworkTemplateの拡張として加えられ、preg_replaceのサニタイズチェックとマッチングを行います。 sanitizeValue()は、オリジナルのMDVA-43395パッチによって追加されたpreg_match()および preg_replace()のサニタイズコードを置き換えるために使用されます。 sanitizeValue()関数は、サニタイズされたconfigureやカスタム値タイプの読み込みなど、コードベース全体の多くの場所で使用されます。 blockDirective()はサニタイズマジックで、文字のマッチングとサニタイズが追加され、 \Magento\Framework\FilterTemplateコアの一部となります。 resolveBlockDirectiveはpublic関数からprivate関数へ、layoutDirectiveは resolveLayoutDirectiveへと移行しています。 なぜなら、private関数の宣言は、この関数をこの親クラスの中だけで使用できることを意味するからです。public関数は、アプリケーションのどこからでもアクセスすることができます。 どちらのパッチもAPSB22-12 Adobe Security Bulletinから入手可能で、PHP Composerをインストールするか、フォークされたコードベースにマージすることで利用可能です。 両方のパッチを適用する前に安全なバックアップを取ることと、 配備する前にコードをテストすることを忘れないでください。 Snykに登録して、新しい脆弱性アラートを受け取る 私が Magento のような大きなオープンソースプロジェクトでいつも行っていることは、Snyk Dashboard から公開リポジトリを監視することです。 Add Projectをクリックして、パブリックのGitHub リポジトリを監視します。 これは特にプロジェクトのさまざまな開発バージョンにおいて有効で、開発中に潜在的な問題を警告することができるからです。また、開発中に修正すべき問題を特定できるため、プロジェクトに貢献する際にも役立ちます。 Magentoのようなプラットフォームプロジェクトでは、監視プロセスでパッケージマニフェスト、コード、コンテナ、IA 設定をスキャンして、潜在的な問題をハイライトします。最も優れているのは、可能な修正を提案し、検出された問題を段階的に解決する手助けをしてくれることです。 ブログを読んで、Snykを使ってみたい!と思われた方は、ぜひ無料トライアルをお試しください。トライアル中の技術的なご質問は、サポートに日本語でお寄せください。 Snykでは、セキュアなコーディングのための情報や脆弱性の最新情報などを発信しています。ぜひTwitterやFacebookやブログのフォローをお願いします。
- 投稿日:2022-02-25T13:31:56+09:00
Laravel8 Localhostリダイレクトエラーの解決方法が意外と簡単だった件について
エラー内容 Laravelでマルチ認証を追加しようと思い、上記の記事を見ながら 作成していたところ 登録ボタンを押すと、リダイレクトエラーになってしまいました。 初めは、ルーティングやコントローラーなどでコーディングミスをしているのかと 色々調べて、試してみたのですが 一向に解決せず、正直絶望していました。 解決方法 ある時、エラー画面に出ている「Cookieを消去してみてください」という言葉に 従ってCookieを削除してみました。 (以前、同じようなエラーでCookieを消去しても変化がなかったので、試してませんでした) すると、なんとエラーが解決したのです。 考察 おそらく、今回の原因は一つのサーバーから複数アカウントを作成しようと していたからなのかもしれない。 正直、ここは「たぶん」でしかない。 ただ、もう少し原因ドリブンで探ってみようと思います。 検索ワードとしては ・「ユーザー認証 複数 アカウント作成 エラー Laravel」などかなと。 自戒を込めて まず、エラーが出たらエラー文をしっかり読み その通りに実行することを第一とする。
- 投稿日:2022-02-25T12:09:52+09:00
PHPUnitとGitHub ActionsとCoverallsを繋げて自動的に更新されるカバレッジのバッジを生成する
GitHubを見ているとREADMEにコードのカバレッジが書かれたバッジが貼ってあるのをよく見ますが、アレを実際に自分が作っているPHPのライブラリのレポジトリに貼ってみたのでその方法を紹介します。 今回はCoverallsというテストのカバレッジの結果を収集してくれるサービスを利用してバッジを作りました。 また、手作業でカバレッジのレポートを上げるのは効率が悪いので、GitHub Actionsを用いてコードが変更されると自動で上げるようにしました。 用意するもの GitHub Actionsの設定 テストを実行してカバレッジレポートを送信するのに必要です Coverallsのアカウント あらかじめGitHubと連携しておいてください テストされるコードとテストコード Coverallsと対象のレポジトリを接続する Add Reposから対象のレポジトリを接続しておきましょう。トグルをONにしておけば完了です。 PHPUnitの設定を変更する 今回はPHPのプロジェクトを対象に設定するので、PHPUnitの設定にカバレッジ周りの設定を入れていきます。 phpunit.xml.dist <?xml version="1.0" encoding="UTF-8"?> <phpunit> <!-- 以下のcoverageを追加する --> <coverage> <include> <directory suffix=".php">src/</directory> </include> <report> <clover outputFile="build/logs/clover.xml"/> </report> </coverage> </phpunit> 何も設定してなければカバレッジレポートは吐き出してくれないので出力するように設定しておきます。 今回は src/ 以下にカバレッジの計測の対象になるコードが入っている想定で、build/logs/clover.xmlにclover形式のカバレッジレポートを出力するようにしました。 GitHub Actionsの設定を仕込んでおく .github/workflows/coverage.yml name: coverage on: push: branches: # 今回はカバレッジレポートの送信の対象はmainブランチだけにしてあります(適宜変更してください) - main jobs: phpunit: name: PHPUnit (PHP ${{ matrix.php-versions }} on ${{ matrix.operating-system }}) runs-on: ${{ matrix.operating-system }} strategy: fail-fast: false matrix: operating-system: [ ubuntu-latest ] php-versions: [ '8.1' ] steps: - name: Checkout uses: actions/checkout@v2 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-versions }} extensions: mbstring, dom, fileinfo, simplexml coverage: xdebug - name: Get composer cache directory id: composer-cache run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache composer dependencies uses: actions/cache@v2 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: ${{ runner.os }}-composer- - name: Install Composer dependencies run: composer install --no-progress --prefer-dist --optimize-autoloader - name: Test with PHPUnit run: vendor/bin/phpunit --testdox --colors=always - name: Upload coverage results to Coveralls env: COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | composer global require php-coveralls/php-coveralls php-coveralls --coverage_clover=build/logs/clover.xml -v main ブランチに更新があったらカバレッジを計測してCoverallsに結果を送信するようにしました。 ポイントは COVERALLS_REPO_TOKEN ですが、何も設定しなくても secrets.GITHUB_TOKEN から安全に取得できるのでそれを利用しました。(ベタ書きするのは絶対にやめましょう) secrets.GITHUB_TOKEN については、以下の記事が参考になるので、そちらを参照してください。 Automatic token authentication - GitHub Docs [GitHub]secrets.GITHUB_TOKENで実行できる権限について簡単ながらマッピングしてみた | DevelopersIO 完成したバッジを貼り付ける カバレッジレポートが上がると、Coverallsのレポジトリのページからバッジのコードが取れるようになっているので、そこからコピーしてREADMEに貼り付ければ完了です。
- 投稿日:2022-02-25T11:59:07+09:00
CentOS8×PHP7.3「Failed to download metadata for repo 'AppStream'」で怒られる時
現象 Error: Failed to download metadata for repo 'AppStream': Cannot prepare internal mirrorlist: No URLs in mirrorlist 原因 2021年末でCentOS8のサポートが切れたので、ミラーサイトが停止しているご様子でした。? 解決策 リポジトリのダウンロードの向き先をアーカイブに変更します! $ sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* $ sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* PHPのバージョンを変更する場合 CentOS8のデフォルトのPHPバージョンはPHP7.2になります。 別バージョンを使用したい場合は、remiリポジトリを使用する必要があります。 remiリポジトリをインストールして、再度エラーが出る場合は、、、 囲んじゃいましょう。 # 向き先変更 $ sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* $ sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* # remiリポジトリ $ dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm $ dnf -y install https://rpms.remirepo.net/enterprise/remi-release-8.rpm # さらに向き先変更 $ sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* $ sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* 何か良い方法があれば、教えていただきたいです。。。 参考 https://qiita.com/yamada-hakase/items/cb1b6124e11ca65e2a2b https://www.na3.jp/entry/20220213/p1
- 投稿日:2022-02-25T01:37:45+09:00
【PHP】'シングルクォート'と"ダブルクォート"の使い分け
| 概要 PHPで使用する場合 変数とは まとめ | PHPで使用する場合 PHPの学習を進めていると、文字列として文字を扱う時に'シングルクオーテーション'または"ダブルクォーテーション"を使う…