日本語

HTML、chmod、コンテナ、および cron

4 つのユーティリティの背後にある理由: HTML エディターにホワイトリストとサンドボックスが必要な理由、chmod 文字列の大文字の S が重要な理由、compose で docker run コマンドが表現できない内容、および誰もが引っかかる 2 つの cron ルール。

HTML エディター: フィルターではなく許可リスト

エディターは HTML を生成します。テキスト ボックスからの HTML は、存在する最も古いインジェクション ベクターです。ここでは 2 つの異なる質問が混同されているため、これらを分離することが重要です。 1 つ目は、「このエディターを騙して、表示するページでコードを実行するマークアップを発行できるか?」というものです。 2 つ目は、「これは信頼できないソースから敵対的な HTML をクリーンアップする安全な方法ですか?」です。このツールは、最初の質問には「はい」、2 番目の質問には「いいえ」と答えます。また、そうでないと思わせるのではなく、パネルにその旨を表示します。

このメカニズムはホワイトリストです。要素のリストは許可されます。他のすべての要素はラップされていないため、テキストは残りますが、タグは残りません。属性のリストは要素ごとに許可されます。それ以外はすべて破棄されます。これにより、すべてのイベント ハンドラーが単にブロックされるのではなく、不可能になります。属性名はテスト前に小文字にされるため、oNeRrOr と ONERROR は onerror と同じ拒否された名前になります。 HTML パーサーが内容を生のテキストとして扱う要素 (script、style、textarea、iframe、title) は、内容とともに削除されます。これは、これらの要素をラップ解除すると、スクリプト ソースがマークアップとしてドキュメントに貼り付けられるためです。

リンク アドレスは独自のチェックを受けます。スキームが読み取られる前に、値はエンティティでデコードされ、空白文字と制御文字が取り除かれます。ブラウザがナビゲートするときにこれが行われるためです。javascript:alert(1) と java ascript:alert(1) は両方とも同じ場所に到達します。 http、https、mailto、tel、ftp、および相対アドレスのみが残ります。ツールが解決できない文字参照 (: が古典的です) は、アドレス全体が通過せずに拒否されます。これは、ブラウザーよりも入力を理解できないフィルターは穴のあるフィルターであるためです。

画像ボタンはなく、img は許可リストにありません。許可されるイメージ タグは、ドキュメントが送信される場所からのアウトバウンド リクエストであり、onerror サーフェスです。散文を生み出す編集者にとっても、それは価値がありません。

これが完璧であることに依存しない守備がプレビューです。これは、スクリプト、フォーム、同一オリジン アクセスなど、まったく何も許可しないサンドボックス属性を持つ iframe でレンダリングされます。ペイロードがホワイトリストに残っていたとしても、ブラウザはそこでのペイロードの実行を拒否します。これはコードに関する約束ではなく、構造上の保証です。

正直な制限: これは文字列ベースのサニタイザーであり、完全な HTML5 パーサーではありません。パーサーの差分 (ブラウザーがこのトークナイザーとは異なるツリーを構築する入力) は、この方法で構築されたすべてのサニタイザーの既知の弱点です。出力については、このエディターで自分で生成しても問題ありません。見知らぬ人から届いた HTML をクリーニングするには、自分が制御するサーバー上で実際のパーサーに対して実行されるサニタイザーを使用します。

Chmod: 大文字がメッセージ全体です

Unix ファイル モードは 12 ビットです。所有者、グループ、その他のそれぞれに 3 つの許可ビット、さらに setuid、setgid、スティッキー ビットがあります。 8 進形式はこれらのビットを直接読み取るため、4 + 2 + 1 = 7 は読み取り、書き込み、実行を意味します。

ls が出力するシンボリック形式では、特殊ビットが興味深いものになります。これは、特殊ビットが独自の列を取得しないためです。 setuid は所有者実行文字を置き換え、setgid はグループ実行文字を置き換え、sticky は他の実行文字を置き換えます。基礎となる実行ビットも設定されている場合、文字は小文字になり、設定されていない場合は大文字になります。

したがって、4755 は rwsr-xr-x (実行可能な setuid プログラム) であり、4644 は rwSr--r-- (誰も実行できない setuid ファイル) です。大文字の S は、ビットが不活性であることを示すシステムであり、ほとんどの場合、選択ではなく間違いです。同じことが 1644 にも当てはまります。これは rw-r--r-T を示します。これは、他の実行ビットがクリアされている通常のファイル上のスティッキー ビットであり、最新のカーネルではまったく何も行われません。

さらに 2 つの違いを明確にしておきます。 ls が出力する 9 文字の文字列は、chmod が受け取る引数ではありません。chmod は、u=rwx,g=rx,o=rx,u+s のような割り当てリストを必要とします。そして、ディレクトリとファイルでは、同じビットでも意味が異なります。execute は「入って横断できる」ことを意味し、setgid は「新しいファイルはこのグループを継承する」ことを意味し、スティッキー ビットは「誰でも作成でき、所有者だけが削除できる」ことを意味します。これが、/tmp が 1777 である理由です。

docker run で作成: 解析、および変換されないもの

コンバーターは、このツール用に作成された引用符対応トークナイザーを使用してコマンドを分割します。何も実行、評価、またはシェルに渡されません。バッククォート、$(...)、またはセミコロンを含むコマンドは、このツールが入力に対して行うことは読み取りだけであるため、リテラル文字として読み取られます。

ほとんどのフラグはきれいにマッピングされます。ポート、ボリューム、環境、ラベル、再起動ポリシー、機能、ヘルスチェック、リソース制限、DNS、および追加のホストはすべて、同じ意味の構成キーを持っています。名前付きボリュームとユーザー定義ネットワークにはサービス参照だけでなくトップレベルの宣言も必要なので、ネットワーク上では external: true を使用して出力に宣言が含まれます。これは、ネットワーク Docker 実行がすでに存在するネットワークに参加できるためです。

一部のフラグには相当する構成がないため、通常、コンバータが静かに失敗するのはこの部分です。 --rm はサービス プロパティではありません。構成サービスは終了時に削除されません。 -d は、サービスの内容ではなく、CLI の呼び出し方法を説明します。 --link はレガシーで、--mount はこのツールでは記述できない長い形式が必要です。--gpus はドライバーに依存します。これらはそれぞれ、消えるのではなく、名前付きの警告を生成します。不明なフラグも警告を生成し、値を受け取らないものとして扱われます。これは、フラグが値を受け取ったと推測すると、イメージ名が引数になり、確実に間違ったファイルが生成されるためです。

出力には、トップレベルの version: キーが含まれません。 Compose v2 はこれを無視し、現在のバージョンはそれについて警告します。 Compose 仕様によって古いファイル形式バージョンが置き換えられて以来、この形式は廃止されました。

引用は表面的なものではありません。引用符なしで 8080:80 として記述されたポート マッピングは、YAML 1.1 パーサーによって数値として読み取られ、yes、no、on、off は同じ方言のブール値となります。誤読される可能性のあるものはすべて引用されています。文字列として正しく読み取られるものはすべてそのまま残されるため、ファイルは読み取り可能な状態のままになります。

Cron: 誰もが引っかかる 2 つのルール

1 つ目は日のルールです。月日と曜日の両方が * 以外に設定されている場合、cron は両方が一致する場合ではなく、どちらかが一致する場合にジョブを実行します。つまり、 0 0 13 * 5 は、年に 1 ~ 2 回の「13 日の金曜日」ではなく、月に約 5 回ある「13 日の午前 0 時と毎週金曜日の午前 0 時」です。ジェネレーターは、両方のフィールドが制限され、作成される文に「and」ではなく「or」が表示されるたびに警告を出します。

2 つ目はタイムゾーンです。 Cron は、それが実行されているマシンのゾーンを使用します。多くの場合、これはサーバー上の UTC ですが、crontab を作成している人のゾーンであることはほとんどありません。したがって、次回実行のプレビューでは、ユーザーのゾーンを想定するのではなく、どのゾーンを使用するかを尋ねられます。時間はそのゾーンの実時間として計算されるため、毎日のジョブは夏時間の変更後も 1 時間ずれることなく同じ現地時間に留まります。また、毎年春にスキップされる 1 時間に存在しない現地時間は、cron も実行されないため、リストから除外されます。

構文自体は小さいです: 星、数字、範囲 a ~ b、リスト a、b、c、ステップ */n または a-b/n,、月と日の名前 JAN-DEC および SUN-SAT。 0 と 7 はどちらも日曜日を意味します。分フィールドの 5/15 など、ステップ付きのベア値は、「5 から範囲の終わりまで、15 ごと」、つまり分 5、20、35、および 50 を意味します。

検証は意図的に厳密に行われています。 60 * * * * 分は 59 で停止するため拒否されます。 * * * * 日付フィールドが 7 で停止しているため、8 は拒否されます。 */0 * * * * は、ゼロのステップは何も一致しないため拒否されます。 6 つのフィールドは通常、最初のフィールドが秒である Quartz または systemd 式を意味するため、エラーは単にカウントするのではなく、そのことを示します。構文的には有効だが決して実行できないスケジュール (0 0 30 2 * 2 月 30 日を要求する) は受け入れられ、フラグが立てられます。これを拒否するのは間違いであり、沈黙を続けることのほうが悪いためです。

貼り付けたものはどうなりますか

  • すべての変換、ハッシュ、デコード、差分はブラウザーのタブで実行されます。ページが読み込まれるとサーバーは関与しないため、入力はサーバーにアップロード、記録、または保存されません。
  • ハッシュはブラウザー独自の Web Crypto 実装から取得され、UUID は暗号的に安全なランダム ジェネレーターから取得されます。どちらもネットワーク通話を必要としません。
  • 入力した内容はローカル ストレージや Cookie に書き込まれません。ページをリロードするとページは破棄されます。タブを閉じると破棄されます。
  • サイト全体の分析は、構成された正規実稼働ホスト上でのみ実行され、プライバシー ポリシーで開示されます。ローカルホストとプレビューホストはそれを拒否します。貼り付けられた値、トークン、URL、およびファイルの内容は、ToolAcre 独自の分析イベントから除外されます。現在の構成では広告は無効になっています。
  • つまり、JWT または API キーはライブ認証情報です。安全な習慣は、この主張を含め、その主張がどれほど信頼できるものであっても、自分が書いていない Web ページに貼り付けることは決してしないことです。

質問

敵対的な HTML をエディタに貼り付けてクリーンアップできますか?

ペーストしても何も実行されません。ペースト ハンドラーは、何かが挿入される前にクリップボード ペイロードをサニタイズし、プレビューは許可スクリプトのないサンドボックス化された iframe になります。ただし、その結果を信頼できない入力に対するセキュリティ制御として使用しないでください。これは、汎用 XSS フィルターではなく、ある編集者自身の出力に対する文字列ベースのホワイトリストであり、ブラウザーのパーサーは、このようなトークナイザーとは異なるツリーに到達できます。信頼できないコンテンツについては、実際の HTML5 パーサーを使用してサーバー上でサニタイズします。

エディターが私の画像と表を削除するのはなぜですか?

許可リストに載っていないからです。イメージは送信リクエストとエラー時のサーフェスです。テーブルは単にこのエディタの対象外です。テキストの内容は残りますが、タグは残りません。これはバグではなくホワイトリストが機能しているということですが、これは複雑な既存のドキュメントを編集するのに適切なツールではないことを意味します。

chmod 4644 で大文字の S が表示されるのはなぜですか?

setuid が設定されているが、所有者実行ビットが設定されていないためです。大文字は、特殊ビットが何も作用しないことを意味します。つまり、実行できない setuid ファイルです。小文字の s は、両方のビットが設定されていることを意味します。同じルールにより、setgid には S、スティッキー ビットには T が与えられます。これを逆に取得することは、モード計算で最も一般的なエラーです。

Docker コンバーターは私のコマンドを実行しますか?

いいえ、それはできません。コマンドは、引用符のみを理解するトークナイザーによって分割されます。 eval、シェル、子プロセスはありません。ページには eval、シェル、子プロセスを開始する方法がありません。貼り付けたものはすべてタブ内に残ります。

コンバーターが処理できないフラグをドロップするだけでなく、警告を発するのはなぜですか?

作成ファイルが元のコマンドよりも少ない処理をサイレントに実行することは、まったく出力しないよりも悪いためです。本番環境でそれがわかります。表現されていないすべてのフラグには名前が付けられ、それに対する対処方法が示されます。警告が表示されない場合は、何も失われていません。

次回の cron の実行がサーバーの実行と異なるのはなぜですか?

ほぼ常にタイムゾーンです。 Cron は、それを実行しているマシンのゾーンを使用します。プレビューでは、ドロップダウンで選択したゾーンが使用されます。それをサーバーのゾーン (多くの場合 UTC) に設定すると、サーバーは同意するはずです。もう 1 つの候補は日ルールです。日と曜日の両方が設定されている場合、cron はどちらかで実行されますが、これはほとんどの人が意図しているよりも頻繁に実行されます。

制限事項

  • HTML サニタイザーは、このエディター自身の出力の許可リストであり、完全な HTML5 パーサーではなく文字列トークナイザーとして実装されています。これは汎用 XSS フィルターではないため、そのまま使用しないでください。
  • エディターには画像、表、色、フォント コントロールがなく、それらを追加する方法もありません。ホワイトリスト外のものはすべて削除されます。
  • 編集画面では document.execCommand が使用されますが、これは非推奨であり、代替機能は実装されていません。ブラウザは引き続きそれをサポートします。動作は、特にリストのネスト周りで若干異なります。
  • chmod 計算機は、12 の許可ビットのみをカバーします。アクセス制御リスト、拡張属性、SELinux コンテキスト、umask 算術演算、および Windows ACL はすべて範囲外です。
  • docker コンバーターは、単一の docker run コマンドを単一のサービスに変換します。 Dockerfile を読み取らず、イメージを解決せず、--mount、--gpus、--device、--link、または --volumes-from を表現できません。それぞれの場合、代わりに名前付きの警告が生成されます。
  • コンバーターが認識しないフラグは値をとらないものとして扱われます。そのようなフラグが実際に値を受け取った場合、その値は誤って読み取られることになります。警告にはその旨が示されており、フラグを削除することで修正されます。
  • cron ジェネレーターは、5 フィールドの crontab 形式のみを読み取ります。 6 フィールドの Quartz および systemd 式、@reboot、および非標準の L、W、#、および ?演算子は推測されるのではなく拒否されます。
  • 次回の実行時間は、ブラウザー独自のタイムゾーン データベースから国際経由で取得されます。これらはプレビューであり、保証ではありません。cron を実行しているマシンには、異なるゾーン、異なるデータベース バージョン、または時期が来たときに実行されていなかったデーモンが存在する可能性があります。