From 217baaa317b57772f8eaa47d27b2892c64de9e2f Mon Sep 17 00:00:00 2001 From: Mikko Ohtamaa Date: Fri, 19 Jul 2013 01:34:57 +0300 Subject: [PATCH] Added image content type white list with python-magic --- avatar/forms.py | 44 +++++++++++++++++++++++++++++--------- avatar/settings.py | 1 + avatar/testdata/test.tiff | Bin 0 -> 16358 bytes avatar/tests.py | 37 +++++++++++++++++++------------- docs/usage.txt | 24 +++++++++++++-------- 5 files changed, 72 insertions(+), 34 deletions(-) create mode 100644 avatar/testdata/test.tiff diff --git a/avatar/forms.py b/avatar/forms.py index 012ab08..902ec39 100644 --- a/avatar/forms.py +++ b/avatar/forms.py @@ -8,46 +8,70 @@ from django.template.defaultfilters import filesizeformat from avatar.models import Avatar from avatar.settings import (AVATAR_MAX_AVATARS_PER_USER, AVATAR_MAX_SIZE, - AVATAR_ALLOWED_FILE_EXTS, AVATAR_DEFAULT_SIZE) + AVATAR_ALLOWED_FILE_EXTS, AVATAR_DEFAULT_SIZE, + AVATAR_ALLOWED_MIMETYPES) def avatar_img(avatar, size): if not avatar.thumbnail_exists(size): avatar.create_thumbnail(size) - return mark_safe("""%s""" % + return mark_safe("""%s""" % (avatar.avatar_url(size), unicode(avatar), size, size)) + class UploadAvatarForm(forms.Form): avatar = forms.ImageField(label=_(u"avatar")) - + def __init__(self, *args, **kwargs): self.user = kwargs.pop('user') super(UploadAvatarForm, self).__init__(*args, **kwargs) - + def clean_avatar(self): data = self.cleaned_data['avatar'] + + if AVATAR_ALLOWED_MIMETYPES: + try: + import magic + except ImportError: + raise ImportError("python-magic library must be installed in order to use uploaded file content limitation") + + # Construct 256 bytes needed for mime validation + magic_buffer = "" + for chunk in data.chunks(): + magic_buffer += chunk + if len(magic_buffer) >= 256: + break + + # https://github.com/ahupp/python-magic#usage + mime = magic.from_buffer(magic_buffer, mime=True) + + if mime not in AVATAR_ALLOWED_MIMETYPES: + raise forms.ValidationError( + _(u"File content is invalid. Detected: %(mimetype)s Allowed content types are: %(valid_mime_list)s") % + {'valid_mime_list': ", ".join(AVATAR_ALLOWED_MIMETYPES), "mimetype": mime}) + if AVATAR_ALLOWED_FILE_EXTS: (root, ext) = os.path.splitext(data.name.lower()) if ext not in AVATAR_ALLOWED_FILE_EXTS: raise forms.ValidationError( - _(u"%(ext)s is an invalid file extension. Authorized extensions are : %(valid_exts_list)s") % - { 'ext' : ext, 'valid_exts_list' : ", ".join(AVATAR_ALLOWED_FILE_EXTS) }) + _(u"%(ext)s is an invalid file extension. Authorized extensions are : %(valid_exts_list)s") % + { 'ext' : ext, 'valid_exts_list' : ", ".join(AVATAR_ALLOWED_FILE_EXTS) }) if data.size > AVATAR_MAX_SIZE: raise forms.ValidationError( _(u"Your file is too big (%(size)s), the maximum allowed size is %(max_valid_size)s") % { 'size' : filesizeformat(data.size), 'max_valid_size' : filesizeformat(AVATAR_MAX_SIZE)} ) count = Avatar.objects.filter(user=self.user).count() if AVATAR_MAX_AVATARS_PER_USER > 1 and \ - count >= AVATAR_MAX_AVATARS_PER_USER: + count >= AVATAR_MAX_AVATARS_PER_USER: raise forms.ValidationError( _(u"You already have %(nb_avatars)d avatars, and the maximum allowed is %(nb_max_avatars)d.") % { 'nb_avatars' : count, 'nb_max_avatars' : AVATAR_MAX_AVATARS_PER_USER}) - return - + return + class PrimaryAvatarForm(forms.Form): - + def __init__(self, *args, **kwargs): user = kwargs.pop('user') size = kwargs.pop('size', AVATAR_DEFAULT_SIZE) diff --git a/avatar/settings.py b/avatar/settings.py index 12d5db2..8f696dd 100644 --- a/avatar/settings.py +++ b/avatar/settings.py @@ -24,3 +24,4 @@ AVATAR_ALLOWED_FILE_EXTS = getattr(settings, 'AVATAR_ALLOWED_FILE_EXTS', None) AVATAR_CACHE_TIMEOUT = getattr(settings, 'AVATAR_CACHE_TIMEOUT', 60 * 60) AVATAR_STORAGE = getattr(settings, 'AVATAR_STORAGE', settings.DEFAULT_FILE_STORAGE) AVATAR_CLEANUP_DELETED = getattr(settings, 'AVATAR_CLEANUP_DELETED', False) +AVATAR_ALLOWED_MIMETYPES = getattr(settings, 'AVATAR_ALLOWED_MIMETYPES', []) diff --git a/avatar/testdata/test.tiff b/avatar/testdata/test.tiff new file mode 100644 index 0000000000000000000000000000000000000000..c3d899b6075a966450900a7726c3886170f73a6f GIT binary patch literal 16358 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

@rAtYO*6NaizdP9Yk}*;LU$Mm1{-`)g};BgQqf zU~1b~%w}GiL0`v`byRu=e}CmF&qFIRLovBB70vk~_To{Sn=03TVr4ESR^+0iGzYEZ zsii*^St%%^%CnMLPNb5_mxBCZsaVpIg7dG(6sN)pzNOGM|oIP9Jtii^xGS6}kP zz2*M6I$wo~Xg9=$_#r!rYeHVmaIv+9Gv!D=AzN!Jn3)biKNDlv+SntKYw+2_^HGvt zPR?p_($~UDRIyxJQj0p7v0fdoGFvmo)V8vZ3bkNdT?<}l9*4DzzS{yPH;<0LMEUs;h#JYBOTwmye zn@d%=L%vJ%yignK%zWmBVWHx=)B!GbV(hkqqn!=xY^=#A7;RzAt*NOgjEwZTHD~OG zA$@2z3PzQobTm1cdn%}E_SbqcHZk8ei#V-nMjQPbBeS)VPl&&Bs$!qc8^+j6VSY$O z4OPu@6=SXG^xhYC_-kee8Z5mZhBw+Ru*ii<$i$VjZ26p7|+_PhDM zxW336x0dCw>^1OI|t`BiO?c;0%7qU4qE*)$vVP|CtTh2Xg z$Y*I`&GA|ZC3BCZ(u!LP^y}Xbefsu=vy&GRV$=9L!BSL^uco|#j16e0Y(_Kr+8Cc> zYTKUiRaDB}3EyNk(bw3wN@T8h#$yadCaJy3ijTmss6ehSa}Cm)eaPNY&JFsUzgt=K zM`4B^=NTa=Bj=5U?l?cg9g9XdLh5hE^=KPD`#AG=C9YhH=G=pyy&Y}gVQ&KmOAGQ@ zsri^!t(BHAH@AQ}7GB+oqCAlpzV1NmF_U;KAYX?L}Bp@%R2$iK|tm1r*V`Y=@ zQN*e6uf7fKWu^2@^fh%q6P}G`e-be$`kU}8gFeM`Ju1-C4bC$~nT<7BkCmVD0H|YaC zLtPm5GGLDDgTVt$U^civpCkLjbWneuXTveVNA_^!P){UySwk9R&NU)a*qWNa$ARl) zy#Ah>kY&17FmHVJz6uDLSXl|zDmJ+ecST-Yb zPqwwONq_k9cS@P*d8jGlxWVzigJVT=G5zJ*oyZ@#^ect)8JWq}68-xbLq}f+`i4DV zY}}hZ^~GTNHDr(pEQScS0dn2!l!FixWRJX5FEV;_jopL&XfW3>hrr2l5G)26!_CH& z>kf8&CU>ChxmIKYH(LwFCVev1N+M5KsOsc zTie3V#Ts7p)5Fdh_7cwqu81*(ppWX(P zA$s?EDg*hvUOf%ai{~4%J+yW8z*h`;UoBbAR)feikbLxFKwmg0hmgyLdDDt(CYEru zv*a=Q!8Q_Y+TX;8ac|VUH8D1V3CD)M%$a@r_MupxzO0Xt5&E!Ry_sW#da+KudK$uz z622H1=yQK>*562G6u)ED*3m&v9uqRq*Fz6|UFdUNL#Rg&mbp);2W4O&&QYHy?j>Z% zeS)<&`=)3MBTB@jBYm|qXB^Y(!TpUez_=Go7!%@nub#Y@i2WWq(9_j|?w_Q|&zjKD z;eH*lRhM;iG`h+>E+5l^j;@A$t$YtXE$C6Yy4ujy6JCirk=>xH{(?ntb@7P(24odX zhBAwuyfrjbGs#;+1KB@y`>4GXemc@S2l82)^`l27G811V0Crx-6JPSw}5B^;S;^otKL)}?czZ=T;PhHyh;;8x@o~(HK zJ}BQYRrHeI2jyEOE)x~K3gUy?jmy-}F55#+?I()a(<>#sI%kTcyNs_n6jLN6=k@RLXi~WZ2+`pP#N|N-{|0)0b zj}%o@S6`?8S2?V{y|gK#qP|5L=c&w*r2a4PKFVj?VU@*2%|+5*-(Xm~Z^HYdbMN3OVpu2l}d%Ih^w_ANvxw~gTK!Cf4m%EpjE6;Fk z9$VK^G{&{A*;;**r}v32Z7y!AY-p*huTzTq7LBfNZ3(fm5?|E)qpoLBD{I>IMRmucRh$5fWNd%AhJ^9=Xy+wHmJ{ zFJBW|*;LzJ)KnV!w4lr?ZE6-RLa44PK0WmGdxPCYYdzO`-3R`%|9@)LlH%@0ZD?(( zk-aM^b}y|dtu3uub8>w7X7S z`@1grKWoJX=JWdIiu(W1mfeT{y+ykZ1&TINw{6MaH|*b^`d?AhfK2eA`fReNgGH#m zWU9!OG>6#6nR3+BkTgs+hDkc=PHn0YD(MMhJyf3lrW#?A4*y8T+uPSvV~k|+AN!U1 zfT@P+`D=rpUMt4TrH*7$t}eUC=cvo!qFhp2SHg2dof}GOOGNn~%QM?rOIg-T zW_fyBWobLhr&+eCX|1hf`B#=rYD z{am@FbPVe$Nm2C;W97V{bSQRIa+vm4#+SC&l(w|E4l63IE@~>_h+o@KR5w z!Lxm%UzMbNFG|wD3(xl1tmU5@O_QX($DZTqFXH97X-j2kv72bn?w|khgzhu{bK$w~ za}(d!-FC`o_1L2njapn^Q{UR8Y;GtjE>*hzHHiP$7d}_5=j!2-URqY#R9eTc%3_o; zGt%z5l1h07R$2F-9R6Qk_FNrAQ61MT7;pTSWK!TJ^*LrDX?}M^(lR!XG)Id0v7+0z zA^gXAiCNh&Ew3YTJ}L}{orTpA(eOT|)!R4X+}?b3K@vNT}q$@@!3KivwIz_8uyke?ij$)BwxniASi{eeiyNXW~Unou}&MU4f?kRpy{H~#? zVW?rEVWwfH;jZDY5uuT!F8uK(>(O9psU1P7tCmLUAoYAy*}Yt;bsb((b8ks_m>DsGXplqg}4uu036Q zsrDxAJ=&jXpV7Xh{j-jaPJbPH9hFYJ&Ip|3pnnLg$9g6J1^1LAuVm zA-Y3#i*#Fbr|Z6|yIuDq-IKbvbbr+|(6i9<(u>v0)vME+qPJ9UtKNRSlX`db{^-%C zhi#9*9z%PS^cdS?evgek-s^F!$E_ZJ=o{(V>xbwM*RRr_tpAGsPW{jHFX{hiU|?Wn z5MYpIP-*aj!7B!D7#udZZt$C7UqdIuD8rG4t%maqUpM^N@Vw!VJ$v@F>lxlNw`WVw zc|EuE{Iutlp1<}o?&a1ip;t+-NxfF|+S}`7uZO*R^tSCC(L2BQxZX>9@9ur9_k%t? z`q=e}>QmHbVxJX#-tBX?&l4kKBTu8DMzuzBjkX$nVRW~zZeP2;F?~z=PV2j&@27ol z7;73^8%G%z8&5UfX#AP+EfXCRdy@o{Dw8=TJ4}w6Jnq-GpHIK6eq;Kr==Wj2YyCC* z+x1WAU(H`pqN3` zgBA|jH|X+Ut-(%%(+0N>UOo7;!4HO*3<(-iJY@Eew}xCW)i8B3O*ic@-C%me^og0d zS)5se*{f!snmsV@Zys)5Wxm*azxh22V~bFWN{hu7A6a~>?5B)S)+k?59#lTIG_{Pk zY_(ixdDQX`D|@R{E(P6#AX-6GLf5&RaRgTA>IQx|PtoAwQYwVli zJHz*Y??3%ieocNm{qCu3RE4UQsRT zst(#3bT`;OxHNcU@Qo0wkfM-vA=g5cp@pGqL$8Hdh82aa5BnzEI=m!&Q}~?-$B3$k z?GXf>n5=(y-yGJ z*Bz`kuOCx?qQSXgdc(EGz{VwwkDHR3HZ?1nM>W6GV#3MPkyeM+7hA8lg|@9|`?Wo* zefJonF?C~(jCC42YwVqIvEyFr(CR4eI56IF{N(Z1CqztGH&HQh^uz;`tS3#IbnAt< z7dB7UpIklp>nR>n7ESqSYWCFkrkPE9VcLxs<6hi0z1Q@n>1SsI%~&&2Yi8xlqqDqc zy*le(vrA@wImctp(mDT_TRiv6mpos3#}RFB){^`t2VDLc=aF4E0&*G5xHX5O4F6I zR{pZ8WYx*l;j4G9F9c#zU|9zqV!5;7xNj z{qyy@*RO3(-+XY3YRi_brd#K4)7aL!?cVm0+mG*v-to>(*PZKj_1`t;4e5>6H@(T!^aOkDgWfgfr0}UKh62{^ue@)M?XvY?C|HYpMQEN z;?PHjLk@rNMc^0je(C?^zOVeg+Iz(J$eyo#zut4y@95rRs$=gQ4>Cvo#)PuJbUe2$+^4dYtDavq3yyS7hkxfeQEaPK9`qXF} zs^isN*Zi)1cs=_1k#91-xp<@a#{HYkH~(>K+U=gVm)^0sv*oVW-4E`?-aGzn-nX~z zH{Ac@!SwHpzFYaw;o;kl!XF)Zob&kB_f6m9hq*rv`tkLje11CcWZ07{KiB^J$1k&g l9rWww-~4|&^n3R2cm8PqhweXK`KRMQ-}_h6zb>H`_Change your avatar 4. Wherever you want to display an avatar for a user, first load the avatar template tags:: - + {% load avatar_tags %} - + Then, use the ``avatar`` tag to display an avatar of a default size:: - + {% avatar user %} - + Or specify a size (in pixels) explicitly:: - + {% avatar user 65 %} 5. Optionally customize ``avatar/change.html`` and @@ -59,7 +59,7 @@ Changing an avatar The actual view function is located at ``avatar.views.change``, and this can be referenced by the url name ``avatar_change``. It takes two keyword arguments: ``extra_context`` and ``next_override``. If ``extra_context`` is -provided, that context will be placed into the template's context. +provided, that context will be placed into the template's context. If ``next_override`` is provided, the user will be redirected to the specified URL after form submission. Otherwise the user will be redirected to the URL @@ -128,6 +128,12 @@ AVATAR_DEFAULT_URL The default URL to default to if ``AVATAR_GRAVATAR_BACKUP`` is set to False and there is no ``Avatar`` instance found in the system for the given user. +AVATAR_ALLOWED_MIMETYPES + Limit allowed avatar image uploads by their actual content payload and what image codecs we wish to support. + This limits website user content site attack vectors against image codec buffer overflow and similar bugs. + `You must have python-imaging library installed `_. + Suggested safe setting: ``("image/png", "image/gif", "image/jpeg")``. + When enabled you'll get the following error on the form upload *File content is invalid. Detected: image/tiff Allowed content types are: image/png, image/gif, image/jpg*. Management Commands -------------------