Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ProtocolBuffers/gRPCを安全に書き進めるためのエトセトラ

Avatar for nwiizo nwiizo
April 27, 2022

 ProtocolBuffers/gRPCを安全に書き進めるためのエトセトラ

OWASP Fukuoka Meeting #6
https://owasp-kyushu.connpass.com/event/244388/
#owaspfukuoka

Avatar for nwiizo

nwiizo

April 27, 2022
Tweet

More Decks by nwiizo

Other Decks in Technology

Transcript

  1. 3&45GVM"1*ͷ͓͞Β͍ w 3&45GVM"1*͸3&45ͱݺ͹ΕΔͭͷઃܭࢥ૝ʹै͏"1*ͷ͜ͱ w ঢ়ଶ؅ཧΛߦΘͣʹɺ΍ΓͱΓ͞ΕΔঢ়ଶ͸ͦΕࣗମͰ׬݁ͯ͠ղऍ͢Δ͜ͱ͕Ͱ͖Δ w ৘ใΛૢ࡞͢Δ໋ྩͷମܥ͕༧Ίఆٛɾڞ༗͞Ε͍ͯΔ w શͯͷ৘ใ͸൚༻తͳߏจͰҰҙʹࣝผ͞ΕΔ w

    ৘ใͷҰ෦ͱͯ͠ɺผͷ৘ใ΁ͷϦϯΫΛؚΊΔ͜ͱ͕Ͱ͖Δ w Ұൠతʹ͸γϯϓϧͳ8FCͷόοΫΤϯυΠϯλʔϑΣʔεͷҙͰ࢖ΘΕΔ w εςʔτϑϧͰ͋Γ w (&5 1045ͳͲͷ)551ϝιουΛར༻͠ w 63-63*ͰશͯͷϦιʔεΛҰҙʹࣝผ͢Δ  )551ϝκοτ 
 ೚ҙͷϑΥʔϚοτ
  2. 3&45GVM"1*ͷ͓͞Β͍ w 3&45GVM"1*ͷྑ͍ͱ͜Ζ w 63-63*ͷن཯͕͋ΔͷͰɺར༻͠΍͍͢ w 3&45ΫϥΠΞϯτΛར༻ͨ͠Ϧιʔεͷࢀর͕؆୯ w )551ඪ४ͷϝιουΛར༻͓ͯ͠Γɺ౷ҰతͳΠϯλʔϑΣʔεʹͳΔ w

    ঢ়ଶ؅ཧΛߦΘͳ͍ͨΊɺૄ݁߹ͳγεςϜΛ࣮ݱ͢Δ͜ͱ͕Ͱ͖Δ w 3&45GVM"1*ͷ՝୊ w ͋͘·Ͱઃܭࢥ૝Ͱ͋ΔɺϓϩτίϧͰ͸ͳ͍ w ϝλσʔλ΍εΩʔϚ৘ใΛผ్υΩϡϝϯτͱͯ͠࡞੒͕ඞཁ 
  3. H31$ͷಛ௃ w )551ʹΑΔߴ଎ͳ௨৴ w 1SPUPDPMCV ff FST w ॊೈͳετϦʔϛϯάܗࣜ 

    ͪͳΈʹɺH31$ +40/΍)551 QSPUPCVGͷΑ͏ͳ૊Έ߹Θͤ΋ՄೳͰ͕͢ɺ 
 είʔϓ͕େ͖͘ͳΓ͗͢ΔͷͰҎ߱͸ग़͖ͯ·ͤΜɻ
  4. H31$ͷಛ௃ w 1SPUPDPMCV ff FST w 1SPUPDPM#V ff FST͸(PPHMF͕։ൃͨ͠ ೥ʹΦʔϓϯιʔεԽ

    
 σʔλϑΥʔϚοτͰɺόΠφϦσʔλΛؚΉσʔλͰ΋ޮ཰తʹѻ͑ Δͷ͕ಛ௃Ͱ͢ɻ w *%- ΠϯλʔϑΣʔεهड़ݴޠ Λ༻͍ͯɺ 
 ೚ҙͷݴޠͷαʔόʔΫϥΠΞϯτ༻ͷίʔυΛࣗಈੜ੒ w QSPUPCVGͷσʔλΛγϦΞϥΠζɾσγϦΞϥΠζ͢Δʹ͸εΩʔϚ ৘ใ͕ඞཁͰ͢ɻH31$͸ٕज़తʹ͸ඞͣ͠΋εΩʔϚґଘͰ͸͋Γ· ͤΜ͕ɺ࣮૷্͸εΩʔϚͳ͠Ͱ࣮૷͢Δͷ͸ࠔ೉Ͱ͢ɻ w ͜ͷٕज़త੍໿ʹΑΓεΩʔϚϑΝʔετ։ൃ͕ڧ੍Ͱ͖Δ͜ͱ͕ QSPUPCVG H31$ͷڧΈͰ͸͋Γ·͢ɻ 
  5. H31$ͷಛ௃ w ॊೈͳετϦʔϛϯάܗࣜ w 6OBSZ31$ w ͭͷϦΫΤετʹରͯ͠ҰͭͷϨεϙϯεΛฦ͢Ұൠతͳ௨৴ Ͱ͢ɻޡղΛڪΕ͵ݴ͍ํΛ͢Δͱ3&45"1*ͷΑ͏ͳڍಈɻ w 4FSWFSTUSFBNJOH31$

    w ΫϥΠΞϯτ͔ΒૹΒΕ͖ͯͨҰͭͷϦΫΤετʹରͯ͠ɺෳ ਺ճʹ෼͚ͯϨεϙϯεΛฦ͢௨৴ํࣜͰ͢ɻ࠷ޙͷϨεϙϯ εΛฦͨ͠ޙ΋೚ҙʹαʔόʔͷ৘ใΛมߋʹԠͯ͡ΫϥΠΞ ϯτʹͦͷ৘ใΛૹΔ͜ͱ͕Ͱ͖·͢ɻ w $MJFOUTUSFBNJOH31$ w ΫϥΠΞϯτ͔ΒϦΫΤετΛ෼ׂͯ͠ૹͬͯαʔόʔ͸͢΂ ͯͷϦΫΤετΛड͚औ͔ͬͯΒϨεϙϯεΛฦ͠·͢ɻେ͖ ͳσʔλΛ1045͍ͨ͠ͱ͖ʹศརͰ͢ɻ w #JEJSFDUJPOBMTUSFBNJOH31$ w ΫϥΠΞϯτ͔ΒϦΫΤετ͕ૹΒΕ͖ͯͨͱ͖ʹαʔόʔͱ ΫϥΠΞϯτ͸ҰͭͷίωΫγϣϯΛཱ͓֬͠ޓ͍ʹ೚ҙͷλ ΠϛϯάͰϦΫΤετͱϨεϙϯεΛૹΓ͋͏͜ͱ͕Մೳʹͳ Γ·͢ɻ  H31$$MJFOU H31$4FSWFS )551$POOFDUJPO SFRVFTU SFTQPOTF
  6. 1SPUPDPM#VGGFSTΛ࢖ͬͨαʔϏεͷఆٛ w ௨৴ํ๏΍αʔϏε͸TFSWJDFʹͯQSPUPϑΝΠϧͰࢦఆ w 31$ϝιουͷҾ਺ͱϨεϙϯεͷํͷલʹATUSFBNAΛ෇͚Δ͜ͱͰɺ 
 ෳ਺ͷϦΫΤετϨεϙϯεͱͳΔΑ͏ʹఆٛՄೳ   

     1BODBLF#BLFS4FSWJDF͸H31$ͷαʔϏεͰ͢ɻೋͭ31$Λఆ͍ٛͯ͠·͢ɻ   TFSWJDF1BODBLF#BLFS4FSWJDF\  #BLF͸ࢦఆ͞ΕͨϝχϡʔͷύϯέʔΩΛমؔ͘਺Ͱ͢ SQD#BLF #BLF3FRVFTU SFUVSOT #BLF3FTQPOTF \^ SQD#BLF4FSWFS4USFBN #BLF4FSWFS4USFBN3FRVFTU SFUVSOT TUSFBN#BLF4FSWFS4USFBN3FTQPOTF \^ SQD#BLF$MJFOU4USFBN TUSFBN#BLF$MJFOU4USFBN3FRVFTU SFUVSOT #BLF$MJFOU4USFBN3FTQPOTF \^ SQD#BLF#JEJ4USFBN TUSFBN#BLF#JEJ4USFBN3FRVFTU SFUVSOT TUSFBN#BLF#JEJ4USFBN3FTQPOTF \^  3FQPSU͸ϝχϡʔ͝ͱʹম͍ͨύϯέʔΩͷ਺Λฦ͠·͢  SQD3FQPSU 3FQPSU3FRVFTU SFUVSOT 3FQPSU3FTQPOTF \^ ^
  7. 1SPUPDPM#VGGFSTΛ࢖ͬͨαʔϏεͷఆٛ w .FTTBHFͷதͷϑΟʔϧυ͸ɺશͯܕΛ࣋ͭඞཁ͕͋Δ  1BODBLF͸ҰຕҰຕͷম͔ΕͨύϯέʔΩΛද͠·͢ɻ NFTTBHF1BODBLF\  FOVN͸ྻڍܕࠓճ͸.FTTBHF಺Ͱఆٛ͢ΔΧελϜܕͱͯ͠.FOVΛఆ͍ٛͯ͠Δ  FOVN.FOV\

      .&/6@6/,/08/@6/41&$*'*&%   .&/6@$-"44*$   .&/6@#"/"/"@"/%@8)*1  ^  JOU  fl PBU͸εΧϥʔܕͱݺ͹ΕΔجຊతͳܕɻܕͷछྨʹؔͯ͠͸ࢀরࢿྉʹγΣϑͷ໊લ  TUSJOHDIFG@OBNF  ઌ΄Ͳఆٛͨ͠ΧελϜܕΛఆ͍ٛͯ͠Δϝχϡʔ  .FOVNFOV  ͸୅ೖͰ͸ͳ͘ɺλάφϯόʔͱ͍͏ϑΟʔϧυͷࣝผࢠͱͯ͠ར༻͞ΕΔম͖۩߹Λද͢είΞͰ͢    fl PBUUFDIOJDBM@TDPSF  8FMMLOPXOUZQFTͱݺ͹ΕɺλΠϜελϯϓ΍&NQUZϝοηʔδΛఆٛͰ͖·͢ম͍ͨ೔࣌  HPPHMFQSPUPCVG5JNFTUBNQDSFBUF@UJNF ^
  8. QSPUPϑΝΠϧΛίϯύΠϧͯ͠ΈΑ͏ w H31$ͷαʔόʔ΍ΫϥΠΞϯτͷ਽ܗͱͳΔιʔείʔυ܈͸ 
 QSPUPϑΝΠϧ͔ΒQSPUPDΛ༻͍ͯੜ੒͢Δ͜ͱ͕Մೳ 
 QSPUPD͸೚ҙͷݴޠຖʹɺQSPUPDHFOYYYͱ͍͏ผͷίϚϯυΛ 
 ݺͼग़͢͜ͱͰɺ೚ҙͷݴޠ΍ϑΝΠϧΛੜ੒͢ΔΑ͏ʹ֦ுͰ͖·͢ 


    (Pͷ৔߹ʹ͸QSPUPDʹQSPUPDHFOHP QSPUPDHFOHPHSQDͱ͍͏ 
 ϓϥάΠϯΛ૊Έ߹ΘͤͯίϯύΠϧ  pancake.proto ੜ੒ϑΝΠϧ͸ԼهͷೋͭʹͳΓ·͢ ɾQBODBLFQBODBLFQCHPϝοηʔδ΍γϦΞϥΠζ ɾQBODBLFQBODBLF@HSQDQCHPH31$ͷαʔόΫϥΠΞϯτ ͜ΕΒΛࢀর࣮ͯ͠૷͍͖ͯ͠·͢ 
 
 αʔόʔଆʹ͸ੜ੒͞Εͨɻ 
 6OJNQMFNFOUFE1BODBLF#BLFS4FSWJDF4FSWFSΛ૊ΈࠐΜͰ࣮૷Λ͠·͢ ֤H13$ʹରͯ͠H13$εςʔλεͷ6OJNQMFNFOUFEΛฦ͢ϝιου 
 1BODBLF#BLFS4FSWJDF4FSWFSͷJOUFSGBDFʹ௥Ճ͠·͢ protoc --go_out=. --go_opt=paths=source_relative \ --go-grpc_out=. --go-grpc_opt=paths=source_relative \ pancake/pancake.proto
  9. ੜ੒͞ΕͨίʔυΛݩʹ(PͰͷಠࣗͷࣗલͷ࣮૷Λ௥Ճ͢Δ w 999999@HSQDQCHPΛݩʹ w 6OJNQMFNFOUFE1BODBLF#BLFS4FSWJDF4FSWFS΍ /FX1BODBLF#BLFS4FSWJDF$MJFOU Λ 
 ૊ΈࠐΜͰαʔόʔ΍ΫϥΠΞϯτͷ࣮૷Λߦ͍·͢ w

    ڍ͛ͨྫͱ͸ҧ͍·͕ͪ͢͜ΒͳͲΛࢀর͍ͩ͘͞ w IUUQTHJUIVCDPNHSQDHSQDHPUSFFNBTUFSFYBNQMFTIFMMPXPSME w ͜ͷޙʹࢦఆ͞ΕͨϝχϡʔͷύϯέʔΩΛম͍ͨ Γɺϝχϡʔ͝ͱʹম͍ͨύϯέʔΩͷ਺Λฦؔ͢ ਺Λ࣮૷͢ΔΜͰ͚͢Ͳͪΐͬͱ͜ͷลͰ 
 ऴΘΓʹ͓͖ͯ͠·͢  QBODBLFQBODBLF@HSQDQCHP $MJFOU 4FSWFS
  10. ͋Εʁ͜Εͬͯӡ༻ʹͷ͍͍ͤͯΜ͚ͩͬʁ w ΄ͳɺ1SPEVDUJPO3FBEZͱҧ͏͔͊ w H31$ͷαʔόʔɾΫϥΠΞϯτ࣮૷ʹඞཁͳجૅ஌ࣝ͸੔͑Δ͜ͱ͕Ͱ͖·ͨ͠ɻ͔͠͠ɺઆ໌ͯ͠ ͖ͨίʔυͷத਎ͷͳ͞Λࠩ͠ஔ͍ͯ΋͜ΕΒΛ࣮ӡ༻͢Δ͜ͱ͸ͱͯ΋Ͱ͖·ͤΜ w ࣗಈςετ͸Ͳ͏͢Δͷʁ w 31$͕ΠϯλϑΣʔεͱͯ͠ఆٛ͞Ε͍ͯΔͷͰɺϞοΫͰ࣮૷

    w ϩά͸ʁ w H31$͸֤ݴޠͰΠϯλʔηϓλʔͱݺ͹ΕΔϦΫΤετॲཧͷલޙʹ೚ҙͷॲཧΛ௥Ճ͢Δ࢓૊ΈΛఏڙ͞Ε͍ͯΔͷͰͦͪΒΛར༻͢Δ w ηΩϡϦςΟ w (Pͷ৔߹BEWBODFEUMT΍QFN fi MFͱ͍͏ύοέʔδΛ࢖͏ͱূ໌ॻ͕ߋ৽͞Εͨࡍͷࣗಈ࠶ಡΈࠐΈ΍N5-4Λൺֱత؆୯ʹ࣮૷Ͱ͖·͢ɻ w ೝূͷ࢓૊Έ͕ͳ͍ w H31$ʹ͸0"VUIτʔΫϯ΍+40/8FC5PLFO +85 Λશͯͷ31$Ͱࣗಈతʹૹ৴͢Δػೳ͕͋Γ·͢ɻ w ϔϧενΣοΫ w HPPHMFHPMBOHPSHHSQDIFBMUIΛݺͼग़࣮ͯ͠ߦ͢Ε͹Α͍ɻ w FUD %FQMPZJO,VCFSOFUFT 1SPNFUIFVT H31$&DPTZTUFN  ࣮ӡ༻ʹ଱͑ΔͨΊʹ͸͞Βʹ͍͔ͭ͘ͷΑΓৄ͍͠಺༰ʹ͍ͭͯ͸ʮH31$6QBOE3VOOJOHʯΛಡΜͰΈ͍ͯͩ͘͞ʂ
  11. VCFSQSPUPUPPM w ೥͙Β͍લ·Ͱʹೖ໳ͨ࣌͠ʹ͸͜Ε͕࠷ڧͷπʔϧͩͬͨ w ͦͷલʹVCFSQSPUPUPPMʹ͍ͭͯ w 1SPUPUPPM͸6CFS5FDIOPMPHJFTʹΑͬͯ։ൃ͞Εͨ1SPUPDPM#V ff FSTͷϢʔςΟ ϦςΟπʔϧͰ͢ɻ1SPUPUPPMʹ͸H31$ͷΤϯυϙΠϯτΛݺͼग़ͤ·͢ɻQSPUPϑ

    ΝΠϧͷੜ੒ɺQSPUPϑΝΠϧʹهड़ϛε͕ͳ͍͔ͷνΣοΫɺQSPUPϑΝΠϧ͔Β֤ ݴޠͷϑΝΠϧΛੜ੒ͳͲͷαϒίϚϯυ͕෇ଐ͍ͯ͠·͢ɻͨͩ͠ɺ͜ͷαϒίϚϯυ ͸GVMMTUPSZEFWHSQDVSMʹେ͖͘ґଘ͓ͯ͠Γɺ࣮࣭H31$VSMͷαϒηοτͱͳͬͯ ͍·͢ɻݱࡏ͸1SPUPDPM#V ff FSTͷϢʔςΟϦςΟπʔϧͱͯ͠#VGΛਪ঑͍ͯ͠· ͢ɻ 
  12. CVGCVJMECVG͕ղܾ͠Α͏ͱ͍ͯ͠Δ՝୊ w "1*ͷઃܭʹ͸Ұ؏ੑΛ࣋ͨͤΔ w อकՄೳͰҰ؏ੑͷ͋Δ1SPUPCVG"1*Λॻ͘͜ͱ͸ɺอकՄೳͳ3&45+40/ϕʔεͷ"1*Λॻ͘͜ͱ΄ Ͳ޿͘ཧղ͞Ε͍ͯͳ͍ɻ w 1SPUP#VGͷύοέʔδϚωʔδϟʔ w ґଘؔ܎ΛίϐϖͰࣦഊ͢Δ͜ͱ΋͋ΔͷͰਏ͍

    w લํɾޙํޓ׵ੑΛڧ੍ͤ͞Δ w ࣮ࡍʹޙํޓ׵ੑͷ͋Δ1SPUPCVG"1*Λҡ࣋͢Δ͜ͱ͸޿࣮͘ફ͞Ε͓ͯΒͣɺڧ੍͢Δ͜ͱ͕೉͍͠ w 4UVCͷ഑෍ʹ͍ͭͯ w 1SPUPϑΝΠϧͷ഑෍ͱੜ੒෺ͷ഑෍͕՝୊ͱͯ͋͠Δ w ݶΒΕͨΤίγεςϜπʔϧ w ϞοΫαʔόੜ੒ɺ'V[[ςετɺυΩϡϝϯςʔγϣϯʹ͍ͭͯ 
  13. "1*ͷઃܭʹ͸Ұ؏ੑΛ࣋ͨͤΔ w "1*ͷઃܭʹ͸Ұ؏ੑ͕ͳ͍ w อकՄೳͰҰ؏ੑͷ͋Δ1SPUPCVG"1*Λॻ͘͜ͱ͸ɺอकՄೳͳ3&45+40/ϕʔεͷ "1*Λॻ͘͜ͱ΄Ͳ޿͘ཧղ͞Ε͍ͯͳ͍ɻඪ४ͷڧ੍ྗ͕ͳ͍ͨΊɺ૊৫ͷ1SPUPCVG "1*ʹҰ؏ੑ͕ͳ͘ɺઃܭ্ͷܾఆ͕"1*ͷকདྷͷ൓෮ੑʹෆ஫ҙʹӨڹ͢ΔՄೳੑ͕͋Γ ·͢ɻ  CVGMJOU

    HPPHMFUZQFEBUFUJNFQSPUP1BDLBHFOBNFHPPHMFUZQFTIPVMECFTV ff i YFEXJUIBDPSSFDUMZGPSNFEWFSTJPO TVDIBT HPPHMFUZQFWQFUWQFUQSPUP'JFMEOBNFQFU*%TIPVMECFMPXFS@TOBLF@DBTF TVDIBTQFU@JEQFUW QFUQSPUP4FSWJDFOBNF1FU4UPSFTIPVMECFTV ff i YFEXJUI4FSWJDF CVGHFOFSBUFCVGCVJME#6'@64&3QFUBQJT
  14. લํɾޙํޓ׵ੑΛڧ੍ͤ͞Δ w લํɾޙํޓ׵ੑ͸ڧ੍͞Εͳ͍ɻલํ͓Αͼޙํޓ׵ੑ͸1SPUPCVGͷ໿ଋ ࣄͰ͕͢ɺ࣮ࡍʹޙํޓ׵ੑͷ͋Δ1SPUPCVG"1*Λҡ࣋͢Δ͜ͱ͸޿࣮͘ ફ͞Ε͓ͯΒͣɺڧ੍͢Δ͜ͱ͸ࠔ೉Ͱ͢ɻ  IUUQTEPDTCVGCVJMEUPVSEFUFDUCSFBLJOHDIBOHFT CVGCSFBLJOHBHBJOTUHJU QFUWQFUQSPUP1SFWJPVTMZQSFTFOUTFSWJDF1FU4UPSFXBTEFMFUFEGSPN fi

    MFQFUW QFUQSPUP'JFMEPONFTTBHF1FUDIBOHFEUZQFGSPNFOVNUPTUSJOHQFUW QFUQSPUP'JFMEXJUIOBNFQFU@JEPONFTTBHF%FMFUF1FU3FRVFTUDIBOHFEPQUJPO KTPO@OBNFGSPNQFU*%UPQFU*EQFUWQFUQSPUP'JFMEPONFTTBHF %FMFUF1FU3FRVFTUDIBOHFEOBNFGSPNQFU*%UPQFU@JE w "1*ͷҟͳΔόʔδϣϯؒͷॏେͳมߋΛݕग़Ͱ͖·͢ɻ
  15. 4UVCͷ഑෍ʹ͍ͭͯ w ελϒ഑෍͸ࠔ೉ͰະղܾͷϓϩηεͰ͢ɻ૊৫ ͸ɺQSPUPDͷϫʔΫϑϩʔΛҰݩԽͯ͠ੜ੒͞Ε ͨίʔυΛ഑෍͢Δ͔ɺ͢΂ͯͷαʔϏεΫϥΠ Ξϯτ͕ಠཱͯ͠QSPUPDΛ࣮ߦ͢Δ͜ͱΛཁٻ͢ Δ͔ɺͲͪΒ͔Λબ୒͠ͳ͚Ε͹ͳΓ·ͤΜɻ QSPUPDʢ͓Αͼؔ࿈͢ΔQSPUPDϓϥάΠϯʣΛ ৴པͰ͖Δํ๏Ͱ࢖༻͢Δʹ͸ٸͳֶशۂઢ͕͋ ΔͨΊɺ૊৫͸1SPUPCVGϑΝΠϧ΍ελϒͷ഑

    ෍ʹۤ࿑͠·͢ɻ w CVG XPSLcHFO ZBNMʹΑͬͯ؆ུԽ͍ͯ͠Δ   ᵓᴷᴷCVGXPSLZBNM ᵓᴷᴷQSPUP ᴹᵓᴷᴷBDNF ᴹᴹᵋᴷᴷXFBUIFS ᴹᴹᵋᴷᴷW ᴹᴹᵋᴷᴷXFBUIFSQSPUP ᴹᵋᴷᴷCVGZBNM ᵋᴷᴷWFOEPS ᵋᴷᴷQSPUPDHFOWBMJEBUF ᵓᴷᴷCVGZBNM ᵋᴷᴷWBMJEBUF ᵋᴷᴷWBMJEBUFQSPUP IUUQTEPDTCVGCVJMEDPO fi HVSBUJPOWCVGZBNM
  16. ࢀߟࢿྉ w 8FC"1*5IF(PPE1BSUT w IUUQTXXXPSFJMMZDPKQCPPLT w (PݴޠͰͷH31$ίʔυੜ੒ ೥݄Ҏ߱൛  w

    IUUQTOPUFDPNEE@UFDICMPHOOCCE w H31$ͷެࣜαΠτ w IUUQTHSQDJP w ΑΓৄࡉͳυΩϡϝϯτ܈ w IUUQTHSQDHJUIVCJP w H31$6QBOE3VOOJOH w IUUQTXXXBNB[PODPNH31$3VOOJOH#VJMEJOH"QQMJDBUJPOT,VCFSOFUFTEQ