プログラミングBlog

Node.jsでhttpメソッド② PUTとDELETE

前回の続きです。

HTMLのinputタグはPUTとDELETEをサポートしていないため、 XMLHttpRequest を使用します。 https://getbootstrap.jp/

XMLHttpRequestについて

developer.mozilla.org

今回はDELETEとPUTメソッドが実際にサーバー側に送信ができているかの
確認のみ行いたいと思います。Google Chromeの検証ツール、Networkを使用。

POSTとPUTとPUTCHの違い

POST

リソースの作成、送信を行う。

PUT

PUTは更新対象のリソースが無い場合は新しく作成する。   更新対象のリソースが存在する場合はすべて置換(更新)を行う。
何度リクエストを繰り返しても同じ結果となる特徴を持っている。

PUTCH

PUTCHは部分的な置換(更新)を行う。
どのような置換(更新)を行うかの選択ができる。

PUTとDELETEのハンズオン

index.js

const http = require('http');
const fs = require('fs');

const hostname = "127.0.0.1";
const port = 3000;

const indexhtml = fs.readFileSync('./index.html', 'utf-8');
const sendjs = fs.readFileSync('./send.js', 'utf-8');

const server = http.createServer(function (request, response) {
    switch (request.url) {
        case "/":
            response.end(indexhtml);
            break;
        case "/?get=getValue":
            response.end(indexhtml);
            break;
        case "/user":
            response.end(indexhtml);
            break;
        case "/send.js":
            response.end(sendjs);
            break;
        case "/delete":
            response.end(indexhtml);
            break;
        case "/put":
            response.end(indexhtml);
            break;
        default:
            break;
    }
});

server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);
});

send.js

var sendDeleteMethod = document.getElementById('sendDeleteMethod');

sendDeleteMethod.addEventListener('click', function () {
    var request = new XMLHttpRequest();
    request.open("DELETE", "/delete", true);
    request.send("delete");
});

var sendPutMethod = document.getElementById('sendPutMethod');

sendPutMethod.addEventListener('click', function () {
    var request = new XMLHttpRequest();
    request.open("PUT", "/put", true);
    request.send("put");
});

new XMLHttpRequest()で生成。
openでメソッドとURLと真偽値で非同期か同期を選択。
sendでサーバー側に送信します。
Deleteボタン押下時はDELETEメソッドを生成後にサーバーへ送信。
Putボタン押下時はPUTメソッドを生成後にサーバーへ送信。

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <form action="/" method="GET">
        <input name="get" value="getValue">
        <input type="submit" value="GET送信" />

    </form>
    <form action="/user" method="POST">
        <input name="post" value="postValue">
        <input type="submit" value="POST送信" />
        <input type="hidden" name="_method" value="put / delete">
    </form>

    <button id="sendDeleteMethod">delete</button>
    <button id="sendPutMethod">put</button>

    <script type="text/javascript" src="./send.js"></script>
</body>

</html>

値の更新や、削除は次回行う予定。

参考サイト

XMLHttpRequest XMLHttpRequest についてのメモ - Qiita

POST、PUT、PUTCHの違い architecting.hateblo.jp

勉強会⑱

Hands-on and Lightning Talks

開催日時 2021年4月29日(木) 7:00-9:00
本日の発表者は私と、koboriさんとNakagawaさんの3人!

発表者 テーマ 資料 時間
Toku サーバーとは?Node.jsで立ててみる。 発表用資料 25分
Nakagawa チーム開発振り返り 5分
Kobori dockerでアプリケーションサーバーを起動させる 20分

各テーマの感想

サーバーとは?Node.jsで立ててみる。

GETとPOSTを実装。
DELETEとPUTに関しては後日実装予定。
サーバー間のやりとりについて復習したい。

チーム開発振り返り

1週間の振り返り。
学習コストについて考慮していない。 タスクの粒度が細分化されていない。
その結果、スケジュールが大幅に遅れてしまった。

dockerでアプリケーションサーバーを起動させる

アプリケーションサーバーは問題ないが、DBサーバーを立ち上げるときにエラーとなっていた。
解決方法。
knowledge.sakura.ad.jp
リモートとローカルのストレージがマウンティングしていなかった??

Node.jsでhttpメソッド① GETとPOST

HTTPメソッドとは?

クライアントからサーバーに対して送られる要求のこと。
HTTPメソッドでサーバーに何をしてほしいかを伝えることができる。

メソッドの種類

MDNによると全部で9種類。
developer.mozilla.org

今回は代表的な4つのメソッドについて調べました。
GET、POST、PUT、DELETEこれらの4つのメソッドで
データ操作するうえで基本となるCRUDの性質を満たしています。
まずは4つのメソッドを学んでいきましょう。

メソッド名 CRUD 説明
GET READ 読み込み
POST CREATE 作成
PUT UPDATE 更新
DELETE DELETE 削除

GETとPOSTのハンズオン

index.js

const http = require('http');
const fs = require('fs');

const hostname = "127.0.0.1";
const port = 3000;

const server = http.createServer(function (request, response) {
    fs.readFile('./index.html', 'utf-8', readIndex);
    function readIndex(error, data) {
        console.log(request.method);
        console.log(request.url);
        response.end(data);
    }
});

server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);
});

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <form action="/" method="GET">
        <input name="get" value="getValue">
        <input type="submit" value="GET送信" />

    </form>
    <form action="/" method="POST">
        <input name="post" value="postValue">
        <input type="submit" value="POST送信" />
    </form>
</body>

</html>

inputボタンを押下時に、サーバー側に送られたRequestを 検証ツールとログに確認を行う。
HTMLのinputタグは、GETとPOSTのみサポートしているため、DELETEとPUTは別の方法を考えたい。

勉強会⑰

Hands-on and Lightning Talks

開催日時 2021年4月24日(土) 7:00-9:00
本日の発表者は私と、koboriさんとNakagawaさんの3人!

発表者 テーマ 資料 時間
Toku サーバーとは?Node.jsで立ててみる。 資料 25分
Kobori kintone のJavaScriptカスタマイズをプラグイン化したお話 資料 20分
Nakagawa 初めてのレビュー 5分

各テーマの感想

kintone のJavaScriptカスタマイズをプラグイン化したお話  

  • 内容はテーブルにレコードを作成する時の自動化プラグインを作ってみた話。
  • マニフェストファイルに設定を記述してnpmからpackage化するモジュールをinstallして、プラグインを作成していく。
  • 渡すデータはJSON形式で記述することが多いため、pushではなく、mergeを利用すると良い。 Object.assign()

サーバーとは?Node.jsで立ててみる。

  • サーバーって何?
  • Node.jsでWEBサーバーを立てる際の動きの確認。
  • requestとresponseで何をしているか?
  • httpプロトコルの役割等。

初めてのレビュー

  • GitHubでのレビューの仕方
  • ツールの使い方や、観点など。
  • 最終的には褒めることが大事。否定的にならない。

サーバーとは?Node.jsで立ててみる。

サーバーとは?

サーバーはクライアントからの要求(リクエスト)に応じて、何らかのサービス(処理)を提供する側の機能あるいはシステムである。

ja.wikipedia.org
サーバーについて調べて満たしたが、かなり抽象的な言葉だと感じました。
リクエストとレスポンスの話をよく聞きますが、リクエストに対してレスポンス(データを提供)していればコンピューターだけではなくプログラムもサーバーになりうる??
さらに分類していくと、物理サーバーと仮想サーバーに分けられる。

物理サーバー とは?

物理サーバーとは物理的に存在する1台のサーバーのこと。
ハードウェア上で、原則1つのOSを利用する。

仮想サーバー とは?

仮想サーバーとは1台の物理サーバー上で、専用のソフトウェアを使い、複数の仮想的なサーバーを構築すること。
CPUやメモリは物理サーバーのリソースを利用する。分割することで複数のOSと複数のサーバーを動作させることが可能。

サーバーの用途

提供するサービスはサーバーの種類によって異なり、WEBサーバー、メールサーバー、FTPサーバー、DBサーバー、SSHサーバー等がある。
今回はWEBサーバーについてふれていきたい。

WEBサーバーとは?

サーバーの種類の一つで、クライアント(ブラウザ)側からの要求(リクエスト)に対して、文書や画像などをの表示を提供するサーバーのこと。

特徴

  • クライアントとサーバーがやり取りを行う際にHTTPという通信プロトコル(ルール)を使用する。
  • プロトコル(通信の決まり事)があることで、異なる機器同士のデータ交換を可能としている。
  • HTTP(プロトコル)は主にhtmlなどのファイルを送信、受信する際に使う。

Node.jsでWEBサーバーを立ててみる

公式ページのサンプルを参考にしました。
nodejs.org

ハンズオン①

WEBサーバーを立てていきます。

// httpモジュール
const http = require('http');

// port番号
const port = 3000;
// hostname
const hostname = '127.0.0.1'

// サーバーを建てる
var server = http.createServer(function (request, response) {
    // requestURLの確認
    console.log(request.url);
    // requestが正常に終了したかの確認
    console.log(response.statusCode);
    // 表示
    response.end('hello');

});
// portとipを設定
server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);
});

ハンズオン①の結果を見てみる。

ブラウザを立ち上げてURL欄にhttp://127.0.0.1:3000/を打ち込む。
ちなみに打ち込むURLの説明をすると、httpの部分が通信プロトコル
127.0.0.1の部分がローカル・ループバック・アドレスと呼ばれ、自分自身のこと。
3000の部分がport番号となります。
request.urlの部分でurl欄に入れたクエリが表示される。
http://127.0.0.1:3000/の場合だと/が表示される
response.statusCodeでrequestが成功したことがわかる。(成功レスポンスの200が表示される。
response.end('hello')ここで文字列をブラウザ側に提供していることがわかる。

ハンズオン②

次はcontentTypeとstatusCodeを指定してみる。

// httpモジュール
const http = require('http');
var fs = require('fs');

// port番号
const port = 3000;
// hostname
const hostname = '127.0.0.1'

// サーバーを立てる
var server = http.createServer(function (request, response) {
    // File読込
    fs.readFile('./cat.png',
        function (err, data) {
            // statusとcontentTypeを指定
            response.writeHead(200, { 'Content-Type': 'image/png' });
            // 送信後、終了
            response.end(data);
        }
    );
})

// portとipを設定
server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);
});

ハンズオン②の結果を見てみる。

fs.readFile('./cat.png',にてcat.pngファイル(画像)を読み込んでいます。
response.writeHead(200, { 'Content-Type': 'image/png' });この箇所でステータスコード200(成功)とContent-Typeを指定してみました。
ブラウザ側に返された情報がどんなものなのかをContent-Typeで伝えています。

参考サイト

httpについて

qiita.com

プロトコル

通信プロトコルのHTTPとは何かわかりやすく解説します! | 押さえておきたいWeb知識

サーバー

www.rworks.jp
developer.mozilla.org

勉強会⑯

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文を実行させることにより、 データベースシステムを不正に操作する攻撃方法のこと。

ja.wikipedia.org

代表的な不正操作の例

  • ユーザーログイン画面に対して、不正なSQL文を実行しPasswordを取得する。
  • 一覧表示画面に不正なSQL文を流しデータの削除を行う。
  • データの改竄などを行う。

    イメージがつきやすいように実際にやってみましょう。

実際にやってみる

ログインしてみる

ユーザーIdとPasswordが正しければログインできる画面を作成しました。

f:id:Tokuty:20210416200651p:plain
画面のレイアウトなどから、おそらく検索用のSQLWHERE Id = '入力値' AND Password = '入力値'ではないかと予想。

ユーザーId入力フォームに適当な値+セミコロンを入力してみる

1;
f:id:Tokuty:20210416200253p:plain

ログインすることができました。

f:id:Tokuty:20210416200301p:plain

なぜログインできる??

;を入力することでセミコロン以降のSQLを無効にすることができるためIdのみ一致すればログインすることができる。
WHERE Id = '入力値' AND Password = '入力値' → WHERE Id = '入力値'となる。
そのため適当なIDを打ちこんでもし一致すれば、Passwordなしでログインすることができる。
ログインIdに関しては、ユーザーネームとして使われることもあるため、人目につきやすく見破られやすい。
そのためSQLインジェクションしやすい。

Idがわからないは '' or 1 = 1; でログインすることができる。

f:id:Tokuty:20210416200410p:plain

1 = 1の部分が検索条件が真となるためログイン可能。

f:id:Tokuty:20210416200301p:plain
一度ログイン成功するとセミコロンを利用して他の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