Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Node.js のセキュリティの話
Search
Yosuke Furukawa
PRO
June 14, 2014
Programming
18
10k
Node.js のセキュリティの話
Production (セキュリティ編)ということで疎かになりがちなセキュリティの話
Yosuke Furukawa
PRO
June 14, 2014
Tweet
Share
More Decks by Yosuke Furukawa
See All by Yosuke Furukawa
デザインシステムが必須の時代に
yosuke_furukawa
PRO
2
130
Node.js, Deno, Bun 最新動向とその所感について
yosuke_furukawa
PRO
10
4.2k
Welcome JSConf.jp 2024
yosuke_furukawa
PRO
1
4.2k
tc39 x jsconf.jp Panel Discussion 2024
yosuke_furukawa
PRO
0
260
Removing Corepack
yosuke_furukawa
PRO
9
1.7k
JavaScript Runtime とはなにか
yosuke_furukawa
PRO
15
2.8k
Strip Types と Storage
yosuke_furukawa
PRO
4
420
Module Harmony について
yosuke_furukawa
PRO
3
1.7k
LTのやり方
yosuke_furukawa
PRO
16
2.7k
Other Decks in Programming
See All in Programming
1から理解するWeb Push
dora1998
7
1.8k
HTMLの品質ってなんだっけ? “HTMLクライテリア”の設計と実践
unachang113
4
2.8k
意外と簡単!?フロントエンドでパスキー認証を実現する WebAuthn
teamlab
PRO
2
730
Ruby×iOSアプリ開発 ~共に歩んだエコシステムの物語~
temoki
0
270
為你自己學 Python - 冷知識篇
eddie
1
350
さようなら Date。 ようこそTemporal! 3年間先行利用して得られた知見の共有
8beeeaaat
3
1.4k
テストコードはもう書かない:JetBrains AI Assistantに委ねる非同期処理のテスト自動設計・生成
makun
0
250
「待たせ上手」なスケルトンスクリーン、 そのUXの裏側
teamlab
PRO
0
490
Vue・React マルチプロダクト開発を支える Vite
andpad
0
110
MCPとデザインシステムに立脚したデザインと実装の融合
yukukotani
4
1.4k
Ruby Parser progress report 2025
yui_knk
1
430
RDoc meets YARD
okuramasafumi
4
170
Featured
See All Featured
The Cost Of JavaScript in 2023
addyosmani
53
8.9k
4 Signs Your Business is Dying
shpigford
184
22k
VelocityConf: Rendering Performance Case Studies
addyosmani
332
24k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.9k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
Context Engineering - Making Every Token Count
addyosmani
1
35
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
131
19k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3k
Building Better People: How to give real-time feedback that sticks.
wjessup
368
19k
jQuery: Nuts, Bolts and Bling
dougneiner
64
7.9k
Music & Morning Musume
bryan
46
6.8k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Transcript
Node.jsͷݐલͱຊԻ @yosuke_furukawa
@yosuke_furukawa Node.jsϢʔβʔάϧʔϓද / DeNAॴଐ
։࠵༧ఆΠϕϯτ: 6/23 : ౦ژNodeֶԂ13࣌ݶ 7/3 : socket.io meetup 7/11 :
ఱԼҰΫϥΠΞϯταΠυJSϑϨʔϜϫʔΫಆձ
։࠵༧ఆΠϕϯτ: 6/23 : ౦ژNodeֶԂ13࣌ݶ 7/3 : socket.io meetup 7/11 :
ఱԼҰΫϥΠΞϯταΠυJSϑϨʔϜϫʔΫಆձ ʊਓਓਓਓਓਓਓʊ ʼɹશ෦౦ژʂʂɹʻ ʉ:?:?:?:?:?:?:ʉ
ࣄͰͬͯΔ͜ͱ 1. WebήʔϜ࡞ͬͨΓ 2. ϥΠϒϥϦ࡞ͬͨΓ 3. ։ൃϝϯόʔͷޚ༻ฉ͖ ΠϯϑϥपΓଟগޱΛग़͢ɺαʔόαΠυΤϯδχΞɺ Backbone +
marionetteͰ։ൃͯͯ͠ΫϥΠΞϯταΠυͬͯΔ ͍ΘΏΔϑϧελοΫ(স)ΤϯδχΞ
ݐલ×ຊԻ
ݐલฤ
Productionʹ͢Δ࣌ʹͬͨ ΄͏͕ྑ͍͜ͱ(securityฤ)
Don’t run as root
Α͋͘ΔγνϡΤʔγϣϯ port൪߸Λ80/443Ͱ͍͔͋͛ͨΒɺͱ͍ͬͯ rootͰىಈ͢Δͷྑ͘ͳ͍ɻ
WebΞϓϦαʔόʔ WebΞϓϦαʔόʔ ඞཁҎ্ͷݖݶΛ༩͑Δ͖͡Όͳ͍ɻ ສ͕Ұ fs.unlink Λ࣮ߦ͞ΕͪΌͬͨΒ? ͦΕҎ֎ʹຊདྷಡΊͳ͍ϑΝΠϧ͕ fs.readFileͰಡΊͪΌͬͨΒ??
Cross Site Request Forgery
Α͋͘ΔγνϡΤʔγϣϯ ࣗͷαʔόʔ͔Β֎෦ͷαʔόʔΛ౿·͞ Εͯɺ֎෦αʔόʔ͔ΒউखʹϦΫΤετ͕ ൃߦ͞ΕΔɻ
csrfରࡦ (tokenํࣜ) // express var express = require(‘express'); var csrf
= require(‘csurf'); ! var app = express(); app.use(csrf()); ! ! // html ͷ form xhr Ͱ ϦΫΤετͷதʹ tokenΛೖΕͯૹΔ <input type=“hidden” name=“_csrf” value=“{{csrftoken}}”>
csrfରࡦ (xhr͔Ͳ͏͔Λ֬ೝ͢Δ) // express var express = require(‘express'); ! var
app = express(); app.use(function(req, res){ if (req.xhr) { // => X-Requested-With ͕͍ͭͯΔͱreq.xhrtrue // xhrsame origin policy͕ద༻͞ΕΔͨΊɺผυϝΠϯ͔Β // ϦΫΤετൃߦͰ͖ͳ͍ } // … }); !
XSSରࡦ
Α͋͘ΔγνϡΤʔγϣϯ socket.ioͱ͔ͰσʔλΛchatͰΓͱΓ chatʹhtml͕ॻ͚Δͱҙͷjavascript Λ࣮ߦ͞Εͯ͠·͏ɻ
tweetdeck ͞Μ……
αχλΠζ var validator = require(‘validator'); ! socket.on(“message”, function(data){ // <script>alert(“hoge”);</script>
// <script>alert("hoge");</script> validator.escape(data); });
secure session app.use(express.session({ secret: “dontusethisone", cookie: { // ສ͕ҰXSS͕ൃੜͯ͠javascript͔Β //
cookieΛऔΕͳ͍Α͏ʹ͢Δ httpOnly: true, secure: true }, }));
disable x-powered-by
Α͋͘ΔγνϡΤʔγϣϯ ߈ܸऀͷཱ͔Β͢ΔͱେମόοΫΤϯυͷαʔ ό/ϦόʔεϓϩΩγ͕Կ͔Λ࠷ॳʹ֬ೝ͢Δɻ x-powered-by߈ܸऀʹͱͬͯ߈ܸͷώϯ τΛ༩͑ΔࣄʹͳΔɻ
x-powered-byΛফ͢ // express var express = require(‘express'); var app =
express(); app.disable(‘x-powered-by’); ! // ͜͏͢Δ͜ͱͰ // ߈ܸऀʹόοΫΤϯυͷαʔόʔ͕Կ͔͑ͳ͍ɻ
https
جຊhttpsʹ͢Δ httpͩͱϦΫΤετϨεϙϯεͷ༰͕ฏจ ͰΠϯλʔωοπۭؒΛྲྀΕΔ ϦΫΤετղੳ͞ΕͯϢʔβʔͷॏཁͳใ ͕࿙ΕͨΒݏɻ
mozaic.fm #4 CCS ࣭ͯ͠Έͨ: Q. https͕ࠓޙओྲྀʹͳΔΜͰ͠ΐ͏͔? A. ओྲྀ͔Ͳ͏͔ͱ͔͘ɺൺ্͕͕Δͷؒҧ ͍ͳ͍ɻେखͷαʔϏε΄΅httpsʹͳ͍ͬͯͩ͘ Ζ͏
httpsͰexpress var express = require(‘express’); var https = require('https'); var
fs = require('fs'); ! var options = { key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'), cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem') }; ! express.createServer(options); ! // ·͊ͰϦόʔεϓϩΩγͱ͔ͰhttpsΛhttpʹม͢Δ͜ͱͷํ͕ଟ͍͔
ϦόʔεϓϩΩγͰղܾ͢Δख͋Δ OHJOY OPEFKT IUUQ IUUQT
Denial of Service
Node.jsͷDoS γϯάϧεϨουͳͷͰ CPUෛՙ͕͔͔ΔΑ͏ͳॲཧΓۤख
JSON.parse/JSON.stringify // JSON.parse/JSON.stringifyಉظతͳॲཧ // ڊେͳJSON͕དྷΔͱͦͷparse/stringifyͷλΠϛϯάͰॲཧ͕ࢭ·Δɻ // ͳͷͰɺϦΫΤετͷίϯςϯταΠζΛݟͯͪΌΜͱ͘Α͏ʹͨ͠΄͏͕ྑ ͍ɻ ! var
length = +req[‘content-length’]; if (length > 100000) { throw new Error(“Max content size is exceeded”); } ! // ͪͳΈʹexpress/body-parser 100kb ·ͰͰσϑΥϧτ੍ݶ͞ΕͯΔɻ // ࠓ JSON.parse/stringifyʹasync͕͔͘Ͳ͏͔ݕ౼͞ΕͯΔ // https://github.com/joyent/node/issues/7543
Evil regex https://speakerdeck.com/ckarande/top-overlooked-security-threats-to-node-dot-js-web-applications ਖ਼نදݱϚονCPUίετߴ͍
Evil regex ͳΜͰਖ਼نදݱͰݕࠪ͠ͳ͍ ਖ਼نදݱΛ͏ͱ͖ϓϩͷํʹϨϏϡʔͯ͠Β͏
ͪΖΜɺ͜ͷଞʹ
• ͪΌΜͱϩάΛऔΔ • ΞΫηεղੳΛߦͬͯෆ৹ͳΞΫηε͕ͳ͍ ͔ௐΔ • ೝূ/ೝՄͷΈΛݕ౼͢Δ • ສ͕ҰDoSͰԠෆೳʹͳͬͨΒαʔϏεΛ ࠶ىಈͤ͞Δ
• Ωϟον͞Εͳ͍ྫ֎ϩάΛు͍͔ͯΒࢮ ͵Α͏ʹ͢Δɻ
ࢀߟࢿྉ https://speakerdeck.com/ckarande/top-overlooked-security-threats-to- node-dot-js-web-applications https://gist.github.com/cerebrl/6487587 http://blog.kotowicz.net/2011/03/html5-websockets-security-new-tool- for.html
ݐલฤ
ຊԻฤ
!!!!!CAUTION!!!!! ফ͠·ͨ͠
ຊԻฤ
ͳΜͰฉ͍͍ͯͩ͘͞ :D