In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >
Share
Shulou(Shulou.com)06/01 Report--
This article introduces what Python security coding and code audit is like, the content is very detailed, interested friends can refer to, hope to be helpful to you.
1 preface
Now the general web development framework security has been done quite well, such as the commonly used django, but some non-standard development methods will still lead to some common security problems, here are some summary of these common problems. In the code audit preparation section, see "php Code Audit", this document focuses on a variety of common error scenarios, basically the mistakes made by our own developers, and sensitive information has been removed.
2 XSS
Input and output are not filtered, scene:
Def xss_test (request): name = request.GET ['name'] return HttpResponse (' hello% s'% (name))
After searching in the code, it is found that there are a large number of places to use, and the correct way to use it is as follows:
Def xss_test (request): name = request.GET ['name'] # return HttpResponse (' hello% s'% (name))
Return render_to_response ('hello.html', {' name':name})
Even better is to limit the input, such as a regular range, and use the correct api or filter the output.
3 CSRF
CSRF protection should be done for some important operations in the system, such as login, shutdown, scanning and so on. Django provides CSRF middleware django.middleware.csrf.CsrfViewMiddleware, which can be written to settings.py middleware. In addition, add the @ csrf_exempt modifier before the function.
4 command injection
In the process of auditing the code, we found some bad habits of writing code. The most serious one is that in the aspect of command injection, some functions that can be completed by python's own function libraries have to be called os.system to complete through the execution of shell commands. Frankly speaking, I hate this kind of code writing most. Here's a simple example:
Def myserve (request, filename, dirname): re = serve (request=request,path=filename,document_root=dirname,show_indexes=True) filestr='authExport.dat' re ['Content-Disposition'] =' attachment; filename= "'+ urlquote (filestr) +'" fullname=os.path.join (dirname,filename) os.system ('sudo rm-f% s'%fullname) return re
It is obvious that this code is problematic because fullname is user-controllable. The right thing to do is not to use the os.system interface, but instead to use python's own library functions, so that command injection can be avoided. There are three ways to delete files in python:
(1) shutil.rmtree deletes a folder and all files
(2) os.rmdir deletes an empty directory
(3) os.remove,unlink deletes a file
After using the above interface, you should also be careful not to traverse the directory, otherwise the whole system may be deleted. Common functions with command execution risks are as follows:
Os.system,os.popen,os.spaw*,os.exec*,os.open,os.popen*,commands.call,commands.getoutput,Popen*
It is recommended to use the subprocess module and make sure that shell=True is not set, otherwise there is also a risk of injection.
5 sql injection
There should be no sql injection if you use django's api to manipulate the database, but there is a risk of sql injection if splicing sql is used for some other reason. Here is an example of an injection risk:
Def getUsers (user_id=None): conn = psycopg2.connect ("dbname=' × × 'user=' × ×' host='' password=''") cur = conn.cursor (cursor_factory=psycopg2.extras.DictCursor) if user_id==None: str='select distinct * from auth_user' else: str='select distinct * from auth_user where id=%d'%user_id res = cur.execute (str) res = cur.fetchall () conn.close () return res
Sql stitching like this has the problem of sql injection. Normally, you should use django's database api. If there is a need for this, you can write it as follows:
Def user_contacts (request): user = request.GET ['username'] sql = "SELECT * FROM user_contacts WHERE username =% s" cursor = connection.cursor () cursor.execute (sql, [user]) # do something with the results results = cursor.fetchone () # or results = cursor.fetchall () cursor.close ()
Direct splicing is absolutely impossible, if you use ModelInstance.objects.raw (sql, []), or connection.objects.execute (sql, []), the parameters passed through the list will not be injected risk, because django will have processing.
6 code execution
Generally due to the abuse of eval and pickle.loads, especially eval, people are not aware of this problem. Here is an example from the code:
Login_required@permission_required ("accounts.newTask_assess") def targetLogin (request): req= simplejson.loads (request.POST ['loginarray']) req=unicode (req) .encode ("utf-8") loginarray=eval (req) ip=_e (request,'ipList') # targets=base64.b64decode (targets) (iplist1,iplist2) = getIPTwoList (ip) iplist1=list (set (iplist1) iplist2=list (set (iplist2)) loginlist= [] delobjs= [] holdobjs= []
This piece of code is because the parameters of eval are not controllable, resulting in arbitrary code execution, the correct thing to do is the literal.eval interface. Take another example of pickle.loads:
> import cPickle > cPickle.loads ("cos\ nsystem\ n (S'uname-a'\ ntR.") Linux RCM-RSAS-V6-Dev 3.9.0-aurora # 4 SMP PREEMPT Fri Jun 7 14:50:52 CST 2013 i686 Intel (R) Core (TM) i7-2600 CPU @ 3.40GHz GenuineIntel GNU/Linux0
7 file operation
File operations mainly include any file download, delete, write, overwrite, etc., if you can achieve the purpose of writing, you can basically write a webshell. Here is an example of an arbitrary file download:
Login_required@permission_required ("accounts.newTask_assess") def exportLoginCheck (request,filename): if re.match (r "* .lic", filename): fullname = filename else: fullname = "/ tmp/test.lic" print fullname return HttpResponse (fullname)
This code has the problem of downloading arbitrary .lic files, and it does not do a good job of restricting directory traversal.
8 File upload
8.1 upload any file
Here, the file size is not limited, which may lead to ddos, unrestricted file suffix, arbitrary file upload, and no file renaming, which may lead to directory traversal, file overwriting and other problems.
8.2upload from xml,excel etc.
In our products, xml is often used to save some configuration files, and it also supports the export and import of xml files, which may lead to xxe vulnerabilities under libxml2.9. Take lxml, for example:
Root@kali:~/python# cat test.xmltest&xxe > from lxml import etree > tree1 = etree.parse ('test.xml') > print etree.tostring (tree1.getroot ()) testroot:x:0:0:root:/root:/bin/bashdaemon:x:1:1:daemon:/usr/sbin:/bin/shbin:x:2:2:bin:/bin:/bin/shsys:x:3:3:sys:/dev:/bin/shsync:x:4:65534:sync:/bin:/bin/syncgames:x:5:60:games : / usr/games:/bin/shman:x:6:12:man:/var/cache/man:/bin/sh
This is due to the default adoption of XMLParser in lxml:
Class XMLParser (_ FeedParser) | XMLParser (self, encoding=None, attribute_defaults=False, dtd_validation=False, load_dtd=False, no_network=True, ns_clean=False, recover=False, XMLSchema schema=None, remove_blank_text=False, resolve_entities=True, remove_comments=False, remove_pis=False, strip_cdata=True, target=None, compact=True)
Pay attention to two of the key parameters, including resolve_entities=True,no_network=True, in which resolve_entities=True will lead to parsing entities, and no_network as True will lead to effective utilization conditions, which will lead to some ssrf problems and data cannot be brought out. Xml.dom.minidom,xml.etree.ElementTree is not affected in python
9 unsafe encapsulation
9.1 eval package is not complete
Simply leave _ _ builtings__ empty, which can be bypassed as follows, see bug84179
S2 = "". [x for x in (). _ class__.__bases__ [0]. _ subclasses__ (). If x.roomnamekeeper _ = "zipimporter"] [0] (... "/ home/liaoxinxi/eval_test/configobj-4.4.0-py2.5.egg") .load_module (. "configobj". Os.system ("uname"). "" > eval (S2, {'_ builtins__': {}}) Linux0
9.2 Encapsulation of command interface is not complete
In the underlying encapsulation function, the shell metacharacter is not filtered, but some commands are limited, but its parameters are not controlled. See bug86011.
10 Summary
1. All inputs are unreliable, so filter them strictly.
2. Verify input, avoid injection, list of dangerous functions: evec (), eval (), os.system (), os.popen (), execfile (), input (), compile ()
3. Access control
4. Authentication management and session management. Do not carry authentication information or user information in url. Encrypt sensitive information. Random and whrandom of python are not strong enough. To obtain a strong password, you must use n=open ('/ dev/urandom') data = n.read.
5 、 xss
6. Error handling
7. Insecure storage, such as base64 encoded passwords
8 、 ddos
9. Configuration management, session expiration time
10. Buffer overflow
On Python security coding and code audit is how to share here, I hope the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 270
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.