Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is Python security coding and code audit like

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.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report