From f89de15b4d4acffd03357b30d70ad4b39d1b9914 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl Date: Wed, 10 May 2017 21:13:16 -0700 Subject: [PATCH] Make cookies secure --- main.py | 60 ++++++++++++++++++++++++++---------------- main.pyc | Bin 10489 -> 10964 bytes showlocal.ps1 | 1 + templates/login.html | 4 +++ templates/signup.html | 4 +++ 5 files changed, 47 insertions(+), 22 deletions(-) create mode 100644 showlocal.ps1 diff --git a/main.py b/main.py index 8b78ddb..f0de0f3 100644 --- a/main.py +++ b/main.py @@ -21,14 +21,24 @@ def render_str(self, template, **params): def render(self, template, **kw): self.write(self.render_str(template, **kw)) - +def valid_cookie(raw_cookie): + arr = raw_cookie.split("|") + cookie_value = arr[0] + provided_hash = arr[1] + test_hash = hashlib.sha256(cookie_value).hexdigest() + return test_hash == provided_hash + class WelcomeHandler(Handler): def get(self): self.post() def post(self): - username = self.request.cookies.get('username') - self.render("welcome.html", username=username) + hsh = self.request.cookies.get('username') + if valid_cookie(hsh): + arr = hsh.split("|") + self.render("welcome.html", username=arr[0]) + else: + self.redirect("/logout") def valid_username(username): USER_RE = re.compile(r"^[a-zA-Z0-9_-]{3,20}$") @@ -42,6 +52,11 @@ def valid_email(email): EMAIL_RE = re.compile(r"^[\S]+@[\S]+.[\S]+$") return not email or EMAIL_RE.match(email) +def get_hashed_cookie(cookie_key, cookie_value): + hsh = str(hashlib.sha256(cookie_value).hexdigest()) + hashed_cookie = "%s = %s|%s" % (cookie_key, cookie_value, hsh) + return str(hashed_cookie) + class User(db.Model): username = db.StringProperty(required = True) pwd_hash = db.StringProperty(required = True) @@ -90,7 +105,7 @@ def post(self): new_user = User(username = username, pwd_hash = pwd_hash, email = email) new_user.put() - self.response.headers.add_header('Set-Cookie', 'username=%s' % str(username)) + self.response.headers.add_header('Set-Cookie', get_hashed_cookie('username', username)) self.redirect("/welcome") @@ -131,7 +146,7 @@ def post(self): if have_error: self.render('login.html', **params); else: - self.response.headers.add_header('Set-Cookie', 'username=%s' % str(username)) + self.response.headers.add_header('Set-Cookie', get_hashed_cookie('username', username)) self.redirect("/welcome") @@ -149,10 +164,6 @@ def post(self): class MainPage(Handler): def get(self): self.redirect("/signup") - - - -##### blog def blog_key(name = 'default'): @@ -164,6 +175,9 @@ def render_str(template, **params): return t.render(params) class BlogPost(db.Model): + #TODO make author required after clean up db + author = db.StringProperty() + likes = db.IntegerProperty() subject = db.StringProperty(required = True) content = db.TextProperty(required = True) created = db.DateTimeProperty(auto_now_add = True) @@ -183,25 +197,27 @@ def get(self): self.render('newpost.html') def post(self): - subject = self.request.get('subject') - content = self.request.get('content') - if subject and content: - newpost = BlogPost(subject=subject, content=content) - newpost.put() - - p = db.GqlQuery('SELECT * from BlogPost ORDER BY created DESC LIMIT 1') - self.redirect('/blog/%s' % str(p.get().key().id())) - else: - self.redirect('/blog/newpost') + hsh = self.request.cookies.get('username') + if valid_cookie(hsh): + arr = hsh.split("|") + username = arr[0] + subject = self.request.get('subject') + content = self.request.get('content') + if subject and content: + newpost = BlogPost(author=username, subject=subject, content=content) + newpost.put() + + p = db.GqlQuery('SELECT * from BlogPost ORDER BY created DESC LIMIT 1') + self.redirect('/blog/%s' % str(p.get().key().id())) + else: + self.redirect('/blog/newpost') class PermalinkHandler(Handler): def get(self, post_id): - #key = db.Key.from_path('Post', int(post_id), parent=blog_key()) post = db.GqlQuery('SELECT * from BlogPost ORDER BY created DESC LIMIT 1') if not post: - self.write('no') - #self.error(404) + self.error(404) return self.render("permalink.html", post = post.get()) diff --git a/main.pyc b/main.pyc index 98eebbea0ffa5c967ffdd6b11570130b66f76312..2dac4d174ca4b034d211cfb6e84452c82b35ad4f 100644 GIT binary patch delta 3968 zcmb7HOKcn06}@jrQQ}9Yz7!?uLrS7Wo01hLwqrZC>_k>RPGi{54HDBu1WGfKNPQ^H zjI6kjKok@yWRVA#=FC#t0o$y;B!P$xPS98DDvf z%+b1Z%$JUnWl%XwCYWJbGRVx5mD0>{vU)T#LDraNa%7Ea<^);enmI|f!T7s}QHvM`L-hpxz36-{-f24}AV?%j+IrUHHm+v9xh& z^S%tiO6_c^5J*Ub1L5GJ0NaAcz%z@-c@AWks7$=wzMwrpyRf4{{dMc>jso4MY|>NRN|eq*ya74&9#!Ne%6t_ljEVwUSt<{<`*lK z)sp1~Ff7`(8^fNFxM4_K%W?H6hXHBgXoN2Kx7SNy zjgnd0BMD81w*_TKnH;A>&%pc3?oAd;DB%onE?hFAeuqyhmFNXyPgS=*}{s#BtXg5 zy5Y8gZabE}QCzoV4{yTQ?0APgwc@U?X_%c>NT=5-%a!c~H^&2)iEV9d10&6Qcseoz zxg2KF%Y>2DyV#alvaLlo$5)cPuQtbuvmysDI1KUAJ~T3o=`lPtSbIeb&<+^d>aq(H zvYUzCIIVt}?)JcqH&z(I{D?Z+_Km?&aQe8f-ky{5a_;c9L;g$JYMy250Oi%`@Eg$y z-i+UqC)BsXc|SJ(7fy+3Xbh|Kk(WQC^>*Z>ul0{evicNWcG#8KM;6)IJm5#0`8*gG zUoRH4sl8b6jLf!0Flh@f1t`H`gE69o1DRL5p^?fu>C5S?vzv9i_+Z=}*OrNwz{ox( z?5y4-du%NtR;~Lo#k0pjbYyTqATGT5!-!2a5bMMX@L?S?zW&n?>eN6YCAw8_^pkFF zgf_@Gcf4qm)9TOBGe^vJ4l0*aG4}At4BPsey4yY|-hKFHdtQho_5QKzGcIa`#$_K7 zVUXZ>=pnPK;q~k(HzXfGPJ*}`1@|nwv~(Y5_UvnC@{zv)`m$?0gm28r|mmvcNk1U5t@pJ#FiZ?>OKJd*DqUu2@4-nT%GH`GZ;UI%xk z;SrtIl z5yP|3e_OqmeDL|2ryCaKqkIQXEypAtCsp3Wd*4*?fdkQWij$4C`4r#fwK>s{@UnSR z68_x$dkd=XtCiH(y-W4^%jwFnfVwh|tn)oJGq`=^+MHBAQ2!pxSGT}fXtsoIh;(;Q z2x=Z>4f0S;ZbGdU5>aT=k}x$S5iNg}ON z-T~+RD`-di81pr>lOo4q+*Ft_B6$HsXPe@-yHc@T)_G~ewU#aWrd`>zZ1=wIVAe{j zmLo5!9}Z`tclpIjOfIXx4A*MNU}NXkG4&B1hZ~HL5fd?09Qo_G4hfDsT?{-g2X047 z?4ca+h*t`Na8>$Zb_K5ViOOd_^gubZ;7@o#&rKFNpg88ZYnWyEr-yo(-yP{?(7$+1 zA!l)Xbw9%;5bdBZ(GAUB3-^fj&uO=XDR4AHToBR!K#ryd@_h>IK^UTP2s{Zi0p+$T znQ#;=*{YX>qqK3)xQjUy5Ns0F6zL3oyPyOfv4xXj2D)LLE z#J;$wel(G}tJ_;{D!r2Am3|&_fzjuErD9rZk{cMwl~;0_mz-PWEheuq>13kq%W)(b z9a&b>xoIz&mi^o4EO}|YVs5WlGXRbpt`!LP`p4)nG9qL2N5id&SU9LZE&ZXysl`+q`y7UlITf9@ekT(KJmc+0c)i45dZ)H delta 3416 zcmbVOO>A355T1Q@oY;=z#E$>%B#!fACrt`!8%iPluS6-dWUH1otq3OjlGt&6>i62J zRjMGR0;#PiWz`-iAmD&F@Y523)C=teB#^iu?p)x&fkVXsxFBZs*-m1)fwt~`+5O(` z?Ci|!?EG}(?~$1850C5U5B}rhQ2OV>zdNxRJ=bD)BDxPI7zig^1Xuz%KI#YIqQSM_ z!;5-74MY@H)QDB4w}Xh6g(NC$2Z**Z+g@RlAUeuyvch(Pu0cKp0y}Y-&_JX>kEl); z=zi?%0nrV5Qc*picc@M;=$)#Q20f}e8PH?YnQQ>j2f7!Q7#r;Z!QgPZfBBeJ&)Beh z+1BqVn7OgjhF% zHiMJ}7GP=Wa36u6K*fF1&Tf-8-3QjJxbN<>Rybbb}6CHtuk@A#eKLORv$4xonkEY04N+CW-y-orzf|5-;^FH~8Ken!2DB8BlU;I169giAl11MsX zywv)swb9m^u2+X1$C<0IBwdX37H5v*<-Rd^x9&TBMjPhW9j0i)s@C|DUyuU6gBY2A7X@X&Zy^vNpK*4q*R~)C@McL^T-+^d45h(U&vgY_y8V9Qr z#se-oxo|?h9Ugjg7w$q4SveH>(Y>Pnuxt;6*Nq*zQ&;3f^zuWkB6Z)ChhlNZ|4d|i zals{dH+B(~si-vc;3&I+^Gi{t()Q}q`JY*HA1=QBR^oN*;HjFssGCU7+Ss&y?mhW^ z;`F*^qG#emdA_Zm9hdKV+V?v^0O)qCK-g%#dYADnWo5=$X0$Tn0%4JMXTkr;5r?$QqPvfQ4DQkru8zB}8)yGoF$29ZB~g>h=?CknePqa(P#6 z;m_f;kFcq<=a5aw-@4TGsCxO1;*{z@UMEG|CW)51UiR?rJA%t^$$OojTXv~kA*fvR z6>YStJfO>4$wfDDP$>`A)CQ_x!192q1r4x5C|;u6glLv)2K-8|31}B=yJ5iwc^eg* z46|~+j$BDg?MggGf*s6ySinzMYoP1~g-$~C95IkDG{ovTM}_zy`CZq^0=+V;auvCO zKS_YCl%X)`Sm{T-9T=pj8$eE^RfbY|$P$PwZVxc4pPipGOnwmi)y~>q+x>Kn?_e{U z5rFyd*NDZ6OY^b~+9Q@MFQTL`k z!OFowd9^p%Ov+WCV|(p$P!jqUn+jvlyqbe~G`sfjp?3m>d?Q8rJk~}(rw1IWk{Xh} z%o5AU8=2$?RT0*!VmLogin + + +
+
diff --git a/templates/signup.html b/templates/signup.html index e8480fc..45ff706 100644 --- a/templates/signup.html +++ b/templates/signup.html @@ -65,6 +65,10 @@

Signup

+ + +
+