Skip to content

権限

コマンドは既定で所有者専用です。それより広い権限は意図して開きます。

所有者専用が既定

go
func (m *Weather) CommandMetas() map[string]goroku.CommandMeta {
	return map[string]goroku.CommandMeta{
		"weather": {OnlyOwner: true},
	}
}

OnlyOwner は本人かどうかだけを見ます。sudo、一時的な付与、グループのマスクは 無視します。アカウント・ファイル・シェルに触れるものはこれを使ってください。

権限マスク

他の人にも使わせるコマンド向けに、Goroku はビットマスクの仕組みを持っています。 マスクは所有者が実行時に .security で割り当てます。既定で構わなければ、モジュール 側で宣言することは何もありません。

定数与える相手
OWNERアカウント所有者
SUDOsudo リストの利用者
GROUP_OWNERグループの作成者
GROUP_ADMIN任意の管理者
GROUP_ADMIN_BAN_USERSBAN 権限のある管理者
GROUP_ADMIN_DEL_MSGS削除権限のある管理者
GROUP_ADMIN_PIN_MSGSピン留め権限のある管理者
GROUP_ADMIN_ADD_ADMINS管理者を任命できる管理者
GROUP_ADMIN_CHANGE_INFO情報を編集できる管理者
GROUP_ADMIN_INVITE招待できる管理者
GROUP_MEMBER任意のグループメンバー
PM個人チャットの任意の相手
EVERYONE誰でも、どこでも

組み合わせられます。

go
GROUP_ADMIN_BAN_USERS | GROUP_OWNER

EVERYONE は文字どおり全員

EVERYONE は、どのチャットの見知らぬ相手でも、あなたのアカウントに対してその コマンドを実行できるようにします。まず GROUP_MEMBER か、特定の管理者権限を 検討してください。

ハンドラ内で確認する

go
func (m *Mod) DangerousCmd(msg *goroku.Message) error {
	sm := m.Client.GetSecurityManager()
	if sm == nil || !sm.IsOwner(msg.SenderID) {
		return msg.Answer(m.T("owner_only", "🚫 <b>所有者専用です</b>"))
	}
	return m.doIt(msg)
}

宣言的な OnlyOwner のほうが望ましいです。ディスパッチャがコードの実行前に弾く ので、確認を書き忘れる経路が存在しません。

他人が導入するモジュールを書くなら

あなたのモジュールを導入する人は、自分の Telegram セッションとサーバーを預けます。 守るとよいこと。

  • 既定はいちばん狭い権限に。 機能が必要とする範囲だけ広げます。
  • 秘密情報をログに出さない。 設定フィールドに Secret: true を付けてください (設定)。
  • 利用者の入力はエスケープしてから HTML に入れます (応答)。
  • 行動の前に検証する。 利用者から来たチャット ID やパスは確認に値します。
  • 利用者の入力をシェルに渡さない。 コマンドを実行する必要があるなら、引数は スライスで渡してください。シェル用の文字列を組み立ててはいけません。
go
// 問題なし: 引数が分かれており、シェルは介在しない。
exec.CommandContext(ctx, "ffmpeg", "-i", path, out)

// 問題あり: 引用符を含むファイル名がシェルインジェクションになる。
exec.CommandContext(ctx, "sh", "-c", "ffmpeg -i "+path)

リモートのコード

ネットワーク越しに読み込むモジュールは HTTPS のみで、プライベート、ループバック、 リンクローカル、CGNAT のアドレスは拒否されます。しかもホスト名ではなく解決後の IP を検査するので、DNS の細工は通りません。

これが守るのは転送経路です。コードが安全かどうかについては何も言いません。 ネイティブモジュールはあなたのプロセスで動く任意の Go です。導入する前に読んで ください。

Released under the GNU AGPL v3 License.