Code security guide for developers , To sort out API
And provide detailed and feasible security coding scheme . be based on DevSecOps
idea , We hope to explain the secure coding scheme in a way that is easier for developers to understand , Guide to avoid loopholes from the source .
Python Code security guide
After the code is written , follow-up work , Such as encryption code !
DES
and 3DES
It is no longer applicable to modern applications , Should be changed to use AES
.6
A month or more bash
# The password strength must meet
1. The password length is greater than 14 position
2. The following elements must be included : Case letters 、 Numbers 、 Special characters
3. Do not use each system 、 The default initial password for the program
4. Not with the recent 6 The password used times is repeated
5. Do not use the same password as other external systems
DES
and 3DES
) Encrypted storage password salt
Encrypt and store passwords Before releasing the system or launching the environment , Something to be aware of !
Python 3.6+
edition bash
# Why do you do this ?
because Python2 stay 2020 Maintenance stopped in , The vulnerability of related components cannot be repaired and maintained in time !
AK/SK
、IP
、 Database account secret and other configuration information KMS
Key management system This is a gorgeous dividing line
Writing code is a problem that needs to be considered and thought !
python
# Cerberus Example
v = Validator({'name': {'type': 'string'}})
v.validate({'name': 'john doe'})
# jsonschema Example
schema = {
"type" : "object",
"properties" : {
"price" : {"type" : "number"},
"name" : {"type" : "string"},
},
}
validate(instance={"name" : "Eggs", "price" : 34.99}, schema=schema)
SQL
sentence , Force a distinction between data and commands , Avoid producing SQL
Inject holes .python
# The wrong sample
import mysql.connector
mydb = mysql.connector.connect(
... ...
)
cur = mydb.cursor()
userid = get_id_from_user()
# Use % Directly format string splicing SQL sentence
cur.execute("SELECT `id`, `password` FROM `auth_user` WHERE `id`=%s " % (userid,))
myresult = cur.fetchall()
python
# Safety example
import mysql.connector
mydb = mysql.connector.connect(
... ...
)
cur = mydb.cursor()
userid = get_id_from_user()
# Pass tuples as parameters
cur.execute("SELECT `id`, `password` FROM `auth_user` WHERE `id`=%s " , (userid,))
myresult = cur.fetchall()
ORM
Framework to manipulate the database , Such as : Use SQLAlchemy
.python
# install sqlalchemy And initialize the database connection
# pip install sqlalchemy
from sqlalchemy import create_engine
# Initialize database connection , Change to your database user name and password
engine = create_engine('mysql+mysqlconnector://user:[email protected]:port/DATABASE')
python
# Reference data type
from sqlalchemy import Column, String, Integer, Float
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
# Definition Player object :
class Player(Base):
# Name of table :
__tablename__ = 'player'
# The structure of the table :
player_id = Column(Integer, primary_key=True, autoincrement=True)
team_id = Column(Integer)
player_name = Column(String(255))
height = Column(Float(3, 2))
python
# Additions and deletions
from sqlalchemy.orm import sessionmaker
# establish DBSession type :
DBSession = sessionmaker(bind=engine)
# establish session object :
session = DBSession()
# increase :
new_player = Player(team_id=101, player_name="Tom", height=1.98)
session.add(new_player)
# Delete :
row = session.query(Player).filter(Player.player_name=="Tom").first()
session.delete(row)
# Change :
row = session.query(Player).filter(Player.player_name=="Tom").first()
row.height = 1.99
# check :
rows = session.query(Player).filter(Player.height >= 1.88).all()
# Submit and save to database :
session.commit()
# close session:
session.close()
SQL
When the sentence is , Parameters must be safely filtered .python
def sql_filter(sql, max_length=20):
dirty_stuff = ["\"", "\\", "/", "*", "'", "=", "-", "#", ";", "<", ">", "+",
"&", "$", "(", ")", "%", "@", ","]
for stuff in dirty_stuff:
sql = sql.replace(stuff, "x")
return sql[:max_length]
os.system()
、os.popen()
、subprocess.call()
etc. .API
Perform file operations instead of directly invoking operating system commands .python
import os
import sys
import shlex
domain = sys.argv[1]
# Replace empty characters that can be used to inject commands
badchars = "\n&;|'\"$()`-"
for char in badchars:
domain = domain.replace(char, " ")
result = os.system("nslookup " + shlex.quote(domain))
XXE
attack .python
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
WebShell
Wait for the documents .python
import os
ALLOWED_EXTENSIONS = ['txt','jpg','png']
def allowed_file(filename):
if ('.' in filename and
'..' not in filename and
os.path.splitext(filename)[1].lower() in ALLOWED_EXTENSIONS):
return filename
return None
WEB
The executable directory of the container (appBase
).python
import os
upload_dir = '/tmp/upload/' # Expected upload directory
file_name = '../../etc/hosts' # The file name passed in by the user
absolute_path = os.path.join(upload_dir, file_name) # /tmp/upload/../../etc/hosts
normalized_path = os.path.normpath(absolute_path) # /etc/hosts
if not normalized_path.startswith(upload_dir): # Check whether the final path is in the expected upload directory
raise IOError()
python
import uuid
def random_filename(filename):
ext = os.path.splitext(filename)[1]
new_filename = uuid.uuid4().hex + ext
return new_filename
bash
# When the program needs to be provided from the user URL Address for information
# As specified URL Address to get text content of web page 、 Load a picture at the specified address 、 When downloading, etc , Need for URL Address for security verification
1. Only HTTP or HTTPS agreement
2. Analyze goals URL, Get its host
3. analysis host, obtain host Point to the IP Address converted to long type
4. Check IP Whether the address is intranet IP
# With RFC Defined VPC as an example
# If there is a custom private network segment, it should also be added to the forbidden access list
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
127.0.0.0/8
5. request URL
6. If there is a jump , Execute after jump 1, Otherwise, yes URL Initiate request
bash
# X-Content-Type-Options
add to “X-Content-Type-Options” Response header and set its value to “nosniff”.
# HttpOnly
Control the user's login authentication Cookie The field should be set to HttpOnly Property to prevent from being XSS Loophole /JavaScript Manipulate the leak .
# X-Frame-Options
Set up X-Frame-Options Response head , And reasonably set the allowable range according to the demand .
This header is used to indicate that the browser prohibits the current page from being displayed in frame、 iframe、embed And so on , So as to avoid the click hijacking problem .
It has three optional values :
DENY: The browser will refuse to load any frame page ;
SAMEORIGIN: be frame The address of the page can only be the page under the same domain name
ALLOW-FROM origin: You can decide Semantic permission frame Page address loaded .
python
# Recommended mozilla Maintenance of bleach Library to filter
import bleach
bleach.clean('an <script>evil()</script> example')
# u'an <script>evil()</script> example'
SHA2
、RSA
And so on cvv
Codes and logs are forbidden to be stored 3***************1
6
Bit character , Such as 134******48
4
Bit character , Such as ************8639
python
# Don't do it this way
admin_login_url = "xxxx/login"
# Safety example
admin_login_url = "xxxx/ranD0Str"
CMS
) And Data permission verification .bash
1. Verify the login status of the current user
2. Obtain the identity information of the verified current request account from the trusted structure ( Such as session), Prohibit requesting parameters or Cookie To obtain the identity of an external incoming untrusted user and query it directly
3. Verify whether the current user has the operation permission
4. Verify whether the current user has the permission to operate the data
5. Verify whether the current operation account is the expected account
try/except/finally
Handle system exceptions , Avoid error messages being output to the front end .debug
Pattern , Or output the program running log to the front end .Use Flask Framework coding is a problem that needs to be considered and considered !
Flask
Safety precautions in the documentation https://flask.palletsprojects.com/en/latest/security/Use Django Framework coding is a problem that needs to be considered and considered !
Django
The built-in safety feature turns on https://docs.djangoproject.com/en/3.0/topics/security/Django
The built-in safety features are right XSS
、CSRF
、SQL
Inject 、 Click hijacking and other types of vulnerabilities can play a better protective effect . Try to avoid turning off these safety features .