勉強会⑯
Hands-on and Lightning Talks
開催日時 2021年4月17日(土) 7:00-9:00
本日の発表者は私と、koboriさん、nakagawaさんの3人!
発表者 | テーマ | 資料 | 時間 |
---|---|---|---|
Toku | SQLインジェクション(Node.js) | 資料 | 25分 |
Kobori | SQLインジェクション(PHP) | 25分 | |
Nakagawa | Notion でチーム開発用に手順書を作ってみた | 5分 |
各テーマの感想
SQLインジェクション(Node.js)
PHPhtmlspecialchars
のような言語特有の実装方法がないか調べたい。
FWを使うことでどのような対策が行われるか?気になる。
SQLインジェクション(PHP)
エスケープ処理でタグを無効化してみるハンズオン。
htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
特殊文字の機能を無効化する。
言語ごとに対策が違うので常に考えながらの実装が必要。
Notion でチーム開発用に手順書を作ってみた
MarkDown形式のDocumentは他にもたくさんあるので他の皆様の選定基準が気になる。
今年中に日本語化されるとのことなので、使ってみたい。
SQLインジェクション
SQLインジェクションとは??
アプリケーションのセキュリティ上の不備を意図的に利用し、アプリケーションが想定しないSQL文を実行させることにより、 データベースシステムを不正に操作する攻撃方法のこと。
代表的な不正操作の例
- ユーザーログイン画面に対して、不正なSQL文を実行しPasswordを取得する。
- 一覧表示画面に不正なSQL文を流しデータの削除を行う。
- データの改竄などを行う。
イメージがつきやすいように実際にやってみましょう。
実際にやってみる
ログインしてみる
ユーザーIdとPasswordが正しければログインできる画面を作成しました。
画面のレイアウトなどから、おそらく検索用のSQLはWHERE Id = '入力値' AND Password = '入力値'
ではないかと予想。
ユーザーId入力フォームに適当な値+セミコロンを入力してみる
1;
ログインすることができました。
なぜログインできる??
;
を入力することでセミコロン以降のSQLを無効にすることができるためIdのみ一致すればログインすることができる。
WHERE Id = '入力値' AND Password = '入力値' → WHERE Id = '入力値'
となる。
そのため適当なIDを打ちこんでもし一致すれば、Passwordなしでログインすることができる。
ログインIdに関しては、ユーザーネームとして使われることもあるため、人目につきやすく見破られやすい。
そのためSQLインジェクションしやすい。
Idがわからないは '' or 1 = 1;
でログインすることができる。
1 = 1の部分が検索条件が真となるためログイン可能。
一度ログイン成功するとセミコロンを利用して他のSQL文も入力できるようになるため、他のテーブルを検索したり、データの改竄や破壊することもできる。
対策を考えてみる
1. 正規表現でセミコロンが1個以上入力された場合のチェックを入れる。
var regix = /;+/;
2. エスケープ処理をする。
エスケープ処理とは、その文字本来の機能とは違う意味を与えるもしくは付与すること。
今回の場合はセミコロンより後ろのSQLを無効化する機能を別の意味に置き換える。
escape()
"@*_+-./"以外を符号化することができる。
developer.mozilla.org
3. プレースホルダーを使う
パラメーター部分を?等の記号で示し、そこへ実際の値を割り当てる。
`SELECT * FROM User WHERE Id = ? AND Password = ?`, [qsdata.id, qsdata.password]
実際にやってみた感想
※DBの種類によっては';'以外でも無効化できるのと他の攻撃方法もたくさん存在するため、これらの対策だけでは万全ではないため安心できない。
以下を参考にさせていただきました。
https://www.nic.ad.jp/ja/materials/iw/2010/proceedings/s3/iw2010-s3-01.pdf
参考サイト
SQLインジェクション
www.amiya.co.jpSQLインジェクションを防ぐ対策とは|わかりやすく仕組みを解説|セキュリティコラム|株式会社網屋
IPA
https://www.ipa.go.jp/files/000017320.pdf
エスケープ
https://wa3.i-3-i.info/word11732.html
勉強会⑮
Hands-on and Lightning Talks
開催日時 2021年4月10日(土) 7:00-9:00
本日の勉強会から7:00-8:00の時間帯にLTを行うことにします。
言語化能力とプレゼン能力を鍛える場として活用していきたいと思います。
本日の発表者は私と、koboriさんの二人。
発表者 | テーマ | 資料 | 時間 |
---|---|---|---|
Toku | ハッシュについて | 資料 | 25分 |
Kobori | バッチファイルでkintoneのデータをExcelへ反映させる | 資料 | 25分 |
各テーマの感想
ハッシュについて
説明時間が長すぎて時間オーバーしてしまったので、要所にまとめる能力が必要。
ハンズオンの方にどちらかというと注力を置きたかったので、事前準備をもっとする。
聞いてくれていた皆さんは、ハッシュ自体を知らない人やただ何となく行っていたようなので、
なぜハッシュ化が必要なのかを説明できてよかった。
バッチファイルでkintoneのデータをExcelへ反映させる
実際の業務改善経験をまじえての話。
バッチファイルでExcelを開くとこまではkintone側で行い、その後の作業をExcelのVBAで作成する。
背景として、以前は会議に大量の資料を作成→配布していた。
資料を作成する際にコストがかかる。
そこで資料の作成を自動化してPCで見れるようにしたほうが業務の効率化が図れるんじゃないか?とのこと。
実際にExcelに反映させたデータを見る限り問題はなさそうでしたが、説得にコストがかかってる様子。
数字を交えたプレゼン作りも求められるかも?? 例えば、どのくらいの時間と経費が安く済むか等。
全体的な感想
資料の作成から発表まですべて勉強になったので、やってよかったです。
今後も続けていきます。
ハッシュについて
ハッシュとは?
ハッシュとは、英語で細切れにするという意味。
ハッシュ関数から得られた値のことをハッシュ値という。
例えばこんな値みたことありませんか? ハッシュ関数から得られたハッシュ値の例です。
4DFF4EA340F0A823F15D3F4F01AB62EAE0E5DA579CCB851F8DB9DFE84C58B2B37B89903A740E1EE172DA793A6E79D560E5F7F9BD058A12A280433ED6FA46510A
どんな時に用いられるかというと、検索の高速化、データ比較処理の高速化、改竄の検出などしたい時に使われる。 ハッシュ値を比較して同じ値であれば、同一のデータと考えられますね。
なぜパスワード保護に用いられるのか?
ハッシュ関数とは非可逆変換であるため、ハッシュ値から元の値の値を容易に復元できないという特徴がある。
非可逆変換とは元のデータと変換後のデータが完全に一致しないこと。
つまり、パスワードに用いることで容易に元のデータを割り出されないようハッシュ関数が用いられる。
さらに元のデータが同じであれば同じハッシュ値が生成される特徴がある。
なぜハッシュ化が用いられるのかログイン機能で考える
まずパスワードをハッシュ化せずに、素の状態だと誰にでもわかるパスワードですし、流出したらどうしようもないです。
そこで考えられるのが元のデータをハッシュ化してハッシュ値をパスワードとして利用する方法。
1. ユーザーがパスワードを登録する。
2. 登録時にパスワードをハッシュ化してあげると元のデータはユーザーにしかわからない。
3. 仮にハッシュ化したパスワードが流出したとしても非可逆変換な(戻せない)ため、元のデータはわからない。
よく考えてみるとパスワードを忘れた場合に問い合わせを行うと、元のパスワードを教えるのではなく、再登録になりますよね?
パスワードをハッシュ化することで管理者側もわからないのでしょう。(たぶん
※間違えてたらすいません
ハッシュ化するうえで起こる衝突とは?
異なるデータから同じハッシュ値が生成されてしまうこと。
ハッシュ値が短いほど、衝突がおこりやすいため、できるだけ長いものを使用する。
衝突が多いほど元のデータを割り出される可能性も高まるため、衝突を避けたい。
何度もハッシュ化を重ねることでデータの秘匿性を高めることができる。
ハッシュ化してみよう!
ハッシュ化
public class HashCode { public string HashConvert(string password) { // 文字コードを指定して、文字列からバイナリへの変換を行う。 byte[] bytes = Encoding.UTF8.GetBytes(password); // バイナリからハッシュへと変換を行う。 var hash = SHA512.Create().ComputeHash(bytes) ; return ByteArrayToString(hash); } static string ByteArrayToString(byte[] arrInput) { int i; StringBuilder sOutput = new StringBuilder(arrInput.Length); for (i = 0; i < arrInput.Length; i++) { // ハッシュから16進数に変換する。 sOutput.Append(arrInput[i].ToString("X2")); } return sOutput.ToString(); } }
文字コード
文字コード | 説明 |
---|---|
ASCII | アメリカ規格協会が定めた世界中で使用されている文字コード。ほぼすべてのPCで扱うことができる |
Unicode | 世界で使われるすべての文字を共通の文字集合とするために作られた。UTF-8、UTF-16、UTF-32などがある。 |
UTF-8 | ASCIIと互換性があるため、ASCIIで定義されている文字をそのまま使用することを目的として作られた。 |
進数変換
記号 | 説明 |
---|---|
D2 | 10進数2桁 |
X2 | 16進数2桁 |
覚えておきたい用語
- バイナリ 2進数で表されるデータのこと
- 1byte = 8bit データ量、情報量の単位のこと
- 2進数 0と1の2種類の数字の組み合わせによって表現する形式のこと
実行
class Program { static void Main(string[] args) { var password = new HashCode().HashConvert("1"); Console.WriteLine(password); int byteCount = Encoding.GetEncoding("UTF-8").GetByteCount(password); Console.WriteLine(byteCount); } }
結果
// ハッシュコード 4DFF4EA340F0A823F15D3F4F01AB62EAE0E5DA579CCB851F8DB9DFE84C58B2B37B89903A740E1EE172DA793A6E79D560E5F7F9BD058A12A280433ED6FA46510A // byte数 128
ログイン機能
秘匿性をさらに高めるためにハッシュ値に変換したものをさらに変換する。
その後に値を比較する。 値が一致すればログイン成功、一致しなければログイン失敗。
class Program { static void Main(string[] args) { var password = new HashCode().HashConvert("1"); var password2 = new HashCode().HashConvert(password); Console.WriteLine(password); if (password2 == "A0E65FEADC0BAE63AE088C3D8D648C3BBE145442E1D399618404042EE6785495DFA95844AB23CBE082A33467A96A50544DD42329CA55ADA7DF9E8CE7E0D1C740") { Console.WriteLine("ログイン成功"); } else { Console.WriteLine("ログイン失敗"); } } }
結果
4DFF4EA340F0A823F15D3F4F01AB62EAE0E5DA579CCB851F8DB9DFE84C58B2B37B89903A740E1EE172DA793A6E79D560E5F7F9BD058A12A280433ED6FA46510A ログイン成功
参考にしたサイト
ハッシュの種類やアルゴリズムについて参考にしました。
SHA512以外にもたくさん種類があります。
qiita.com
ハッシュ関数とハッシュアルゴリズム ~PKI基礎④~ | マイクロソフ党ブログmicrosoftou.com
ウィキペディア - Wikipedia
脆弱性の記事
古いアルゴリズムだと既に解析が終了しており、脆弱性が高まるため、
まだ解析されていない最新のアルゴリズムを選択したほうが良い。
internet.watch.impress.co.jp
73spica.tech
2021年3月の振り返り
2121年3月の振り返り
Keep(上手くいったこと、継続中なこと)
- 土曜日の勉強会(7:00-9:00)
- AWSクラウドプラクティショナー資格の勉強。
- C#イディオム、定石&パターン(書籍)
- BuildUpで学習記録をつけていく
- アプリ開発サークルでの開発がようやくひと段落
- 個人アプリに時間がさけなかった。
- その代わり、C#をしっかり基礎から学習することで残業が落ち着いてきた!
- 定時で帰れた日はランニングをする
Problem (課題、問題点)
- 結果は出しているはずだが、昇給の話がない 会社に所属する意味とは??
- 将来的にどうしたいのか?? インフラもやりたい
- クラウドプラクティショナーの受験日を決める
- IPAの受験日を決める
- 東京に行って詳細を少し詰めがまだ未定
Try(新たに実践すること・問題や課題の解決策)
- 外部の勉強会に参加(もくもくではなく、ハンズオン
- 主催している勉強会のスタイルを変更したい(LTなど、ハンズオンの時間を入れたい
- Linuxの学習を始める
3月の学習時間
3月のトータル:78.75h
カテゴリー別トータル
今後
4月からは少し余裕ができそうなので可能な限り学習+プライベートの時間を増やしていきたい。
追い込みすぎで周りに心配かけることが多いし、一度きりの人生を楽しみたいので!
東京にてエンジニアさんにキャリアプランの話を少し聞けた
詳細は書けませんが思うことが少しある。将来的なことも考えていきたい(フリーランスなどなど
勉強会⑭
開催日時 2021年4月3日(土) 7:00-9:00
本日もこちらの問題やりました!
Q54-56 https://gist.github.com/kenmori/1961ce0140dc3307a0e641c8dde6701d
正規表現
文字 | 説明 |
---|---|
\w | 大文字のA-Z,小文字のa-z,数字の0-9,アンダースコア |
\s | スペース、タブ、改ページ、改行を含むホワイトスペース文字 |
+ | 直前の文字の 1 回以上の繰り返し |
\b | 単語の区切りにマッチ |
. | 任意の一文字マッチ |
* | 直前の文字の 0 回以上の繰り返しにマッチ |
/\w/
例:a
一文字とマッチ/\w/+
例:abcd1
+をつけることで直前の文字の一回以上の繰り返しとなる。/\w+/s/w+
例:abcd1 abcd1
大文字のA-Z,小文字のa-z,数字の0-9,アンダースコア + スペース + 大文字のA-Z,小文字のa-z,数字の0-9,アンダースコア\babcd1\b
例:abcd1
.*\babcd1\.*b
例:aa abcd1 bb
任意の一文字の繰り返し + 区切り + abcd1 + 区切り+ 任意の一文字の繰り返し
アプリ開発サークル勉強会⑬ 開催日時 2021年3月27日(土) 7:00-8:00
本日もこちらの問題やりました!
Q52-53 https://gist.github.com/kenmori/1961ce0140dc3307a0e641c8dde6701d
正規表現
プログラミングにおいては正規表現を用いたパターンマッチングのことを正規表現と言う。
パターンマッチングとは、データを検索した場合に、特定のパターンが出現するかどうか?またどこに出現するかを特定する方法である。
ja.wikipedia.org
2種類の方法
①値が変化しない場合
var str = /abc/;
正規表現が一定のままの場合、この方法を使うとよいパフォーマンスが得られます。
②値が変化する場合
var tel = new RegExp('abc');
正規表現パターンが変わることがわかっている場合や、パターンがわからない場合、ユーザーが入力するなど別のソースからパターンを取得する場合は、コンストラクタ関数を使用してください。 MDN
電話番号
0-9の3桁 + ハイフン + 0-9の4桁 + 0-9の4桁
var tel = /[0-9]{3}-[0-9]{4}-[0-9]{4}/;
ただしこの形だと部分一致となるため「0000-1111-1111」このように最初を4桁にしてもマッチングしてしまいます。
なので完全一致にする場合は先頭に「^」末尾に「$」をつけてあげる。
修正版
var tel = /^[0-9]{3}-[0-9]{4}-[0-9]{4}$/;
vscode拡張機能
Ctrl + Alt + Mで起動
TestRegexを押すと→の画面に書いてある正規表現のパターンがマッチングしているかがわかる。
testメソッドで確認しなくて済むので便利です。