In fact, security is a lot of programmers tend to ignore the problem but we need to pay attention to improve the security of the application. Common security concerns include application acceptance data that may come from unauthenticated users, network connections, and other untrusted sources, and security concerns that may arise if application acceptance data is not verified, which can also be divided into the following aspects:

  • Data validation
  • Sensitive information
  • The encryption algorithm
  • Serialization and deserialization
  • I/O operations
  • Multithreading safety
  • Frameworks and Components

In the article Security Development Specification: Developers must Understand Development security Specification (1) (involving security issues, solutions and code implementation), we cover some security issues related to data validation, and then we continue to analyze and resolve other security issues.

Data verification – Permission management

Rule 1.10: prohibit the addition, deletion, modification of program data, and verification of the data requested by the client and the omission of permission judgment

Vertical overreach vulnerability: Called permission promotion, it is a vulnerability caused by a design flaw in URL-based access control. As the Web application does not do permission control or only does permission control on the menu, malicious users can access or control data or pages owned by other roles as long as they guess the URL of other managed pages, so as to achieve the purpose of permission promotion.

Horizontal overreach vulnerability: A vulnerability caused by a design flaw in data-based access control. Unauthorized data access vulnerability caused by the server not judging the owner of the data when receiving the requested data. For example, the server obtains the user ID from the request parameter (the data that the user can control) submitted by the client. A malicious attacker changes the value of the request ID to view or modify the data that does not belong to the attacker.

Example:

 @RequestMapping(value = "delete")
public String delete(HttpServletRequest request, @RequestParam long id) throws Exception{
   try {
       userManage.delete(id);
       request.setAttribute("msg","delete user success");
   }catch (Exception e){
       request.setAttribute("msg","delete user failure");
   }

   return list(request);
}

@RequestMapping(value = "/delete/{addrId}")
public Object remove(@RequestParam long addrId) {
    Map<String,Object> resMap=new HashMap<>();
    if(WebUtils.isLogged){
        this.addressService.removeUserAddress(addrId);
        resMap.put(Constans.RESP_STATUS_CODE_KEY,Constans.RESP_STATUS_CODE_SUCCESS);
        resMap.put(Constans.MESSAGE,"remove user address success");
    }else {
        resMap.put(Constans.RESP_STATUS_CODE_KEY,Constans.RESP_STATUS_CODE_FAIL);
        resMap.put(Constans.MESSAGE,"user is not login ,remove user address failure");
    }
    return resMap;
}
Copy the code

Example: Vertical overreach vulnerability: before invoking functions, verify whether the current user has the permission to invoke related functions (filters are recommended for unified permission verification)

 public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException ,IOException{
    if(request.getSession(true).getAttribute("manager")==null){
        response.sendRedirect("noright.html");
        return;
    }
    UserManagerService userManagerService=new UserManagerService();
    request.setCharacterEncoding("utf-8");
    response.setCharacterEncoding("utf-8");
    String action=request.getParameter("action");
    if("add".equals(action)){
        String id=request.getParameter("userId");
        String name=request.getParameter("userName");
        String sex=request.getParameter("userSex");
    }
    //todo do somethings
}
Copy the code

Data verification – Permission management

  1. Global filters are used to check whether users are logged in and have access to resources.
  2. Access rules are stored in the database
  3. Configure filters in web.xml

public class PriviegeFilter implements Filter{ @Autowired private UserManagerService userManagerService;

@Override public void init(FilterConfig filterConfig) throws ServletException { List<UserAuthorization> userAuthorizationS=userManagerService.getUserAuthorizationInfo(); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { for(UserAuthorization userAuthorization: UserAuthorizationS){// Get authorization information from database if(! Authen){throw new RuntimeException(" You do not have access to the page, please log in and view it as appropriate "); } filterChain.doFilter(servletRequest,servletResponse); } } @Override public void destroy() { } }Copy the code

Data verification – Permission management

  1. SpringMVC: Spring Security provides URL-based access control and Method-based access control.

  2. When a user performs an operation, the user ID is obtained from the session and the parameter is bound to the user’s identity for verification.

      <sec:http>
         <sec:intercept-url parttern="/persident_portal/*" access="RILE_PERSIDENT"/>
         <sec:intercept-url parttern="/manager_portal/*" access="RILE_MANAGER"/>
         <sec:intercept-url parttern="/**" access="RILE_USER"/>
         <sec:form-login />
         <sec:logout />
      </sec:http>
    Copy the code

Data validation – Insecure network transmission

HTTP protocol is a plaintext transmission protocol. The interaction process and data transmission are not encrypted, and the communication parties do not carry out any authentication. The communication process is prone to hijacking, monitoring, tampering, and even malicious traffic hijacking in serious cases. Even cause personal privacy disclosure (such as bank card number and password disclosure) and other serious security problems. HTTPS adds SSL to HTTP, which relies on certificates to verify the identity of the server and to encrypt communication between the browser and the server.

**** symmetric encryption

Asymmetric encryption

HTTPS protocol (HTTP + SSL protocol), the following figure shows the connection process:

Man-in-the-middle attack

Digital certificates: Resolve man-in-the-middle attacks

A digital certificate is a certificate authority center contains the public key owner information of digital signature and public key files After the client to get the certificate, according to the certificate with the private key of a third party on the way to generate a certificate number, if you generate the certificate number and certificate number on the certificate of the same, so that the certificate is real. At the same time, to avoid the certificate number itself is switched, so encryption is enabled.

Summarize the HTTPS to the client and the server communication process to get security guarantees, must use symmetric encryption algorithm, but the process of negotiation symmetric encryption algorithm, using asymmetric encryption algorithm are needed to ensure safety, however, direct use of asymmetric encryption process itself is not safe, will have the possibility of middlemen to tamper with the public key, Therefore, the client and server do not use the public key directly, but use the certificate issued by the digital certificate Issuing Authority (CA) to ensure the security of the asymmetric encryption process itself. To ensure that the certificate is not tampered with, digital signature is introduced, and the client uses the same symmetric encryption algorithm to verify the authenticity of the certificate. In this way, Finally, the communication security between client and server is solved.

Data validation – Insecure network transmission

Rule 1.11: Sensitive data is transferred between trust domains using signature encryption

Prevent theft and malicious tampering of sensitive data during transmission. Encrypting the transmission object using a secure encryption algorithm protects the data. This is called sealing the object. The digital signature of the sealed object can prevent the object from being tampered with illegally and keep its integrity

public static void main(String[] args) throwsIOException,ClassNotFoundException{
    // Build map
    SerializableMap<String, Integer> map = buildMap();
    // Serialize map
    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data"));
    out.writeObject(map);
    out.close();
    // Deserialize map
    ObjectInputStream in = new ObjectInputStream(new FileInputStream("data"));
    map = (SerializableMap<String, Integer>) in.readObject();
    in.close();
    // Inspect map
    InspectMap(map); 
}
Copy the code

Example:

public static void main(String[] args) throwsIOException,GeneralSecurityException, ClassNotFoundException{ // Build map SerializableMap<String, Integer> map = buildMap(); // Generate sealing key & seal map KeyGenerator generator = KeyGenerator.getInstance("AES"); generator.init(newSecureRandom()); Key key= generator.generateKey(); Cipher cipher= Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, key); SealedObject sealedMap= new SealedObject(map, cipher); // Serialize map ObjectOutputStreamout = new ObjectOutputStream(newFileOutputStream("data")); out.writeObject(sealedMap); out.close(); // Deserialize map ObjectInputStream in = newObjectInputStream(newFileInputStream("data")); sealedMap= (SealedObject) in.readObject(); in.close(); // Unseal map cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, key); map = (SerializableMap<String, Integer>) sealedMap.getObject(cipher); // Inspect map InspectMap(map); } public static void main(String[] args) throwsIOException, GeneralSecurityException, ClassNotFoundException{ SerializableMap<String, Integer> map = buildMap(); KeyGenerator generator = KeyGenerator.getInstance("AES"); generator.init(newSecureRandom()); Key key= generator.generateKey(); Cipher cipher= Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, key); SealedObjectsealedMap= newSealedObject(map, cipher); KeyPairGeneratorkpg= KeyPairGenerator.getInstance("RSA"); KeyPair kp= kpg.generateKeyPair(); Signature sig = Signature.getInstance("SHA256withRSA"); SignedObject signedMap= newSignedObject(sealedMap, kp.getPrivate(), sig); ObjectOutputStreamout = newObjectOutputStream(newFileOutputStream("data")); out.writeObject(signedMap); out.close(); ObjectInputStream in = newObjectInputStream(newFileInputStream("data")); signedMap= (SignedObject) in.readObject(); in.close(); if(! signedMap.verify(kp.getPublic(), sig)){ throw new GeneralSecurityException("Map failed verification"); } sealedMap= (SealedObject) signedMap.getObject(); cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, key); map = (SerializableMap<String, Integer>) sealedMap.getObject(cipher); InspectMap(map); }Copy the code

Is:

public static void main(String[] args) throws IOException, GeneralSecurityException, ClassNotFoundException{ SerializableMap<String, Integer> map = buildMap(); KeyPairGenerator kpg= KeyPairGenerator.getInstance("RSA"); KeyPair kp= kpg.generateKeyPair(); Signature sig = Signature.getInstance("SHA256withRSA"); SignedObject signedMap= new SignedObject(map, kp.getPrivate(), sig); KeyGenerator generator = KeyGenerator.getInstance("AES"); generator.init(new SecureRandom()); Key key= generator.generateKey(); Cipher cipher= Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, key); SealedObject sealedMap = new SealedObject(signedMap, cipher); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data")); out.writeObject(sealedMap); out.close(); // Deserialize map ObjectInputStream in = new ObjectInputStream(new FileInputStream("data")); sealedMap= (SealedObject) in.readObject(); in.close(); // Unseal map cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, key); signedMap= (SignedObject) sealedMap.getObject(cipher); // Verify signature and retrieve map if(! signedMap.verify(kp.getPublic(), sig)){ throw new GeneralSecurityException("Map failed verification"); } map = (SerializableMap<String, Integer>) signedMap.getObject(); // Inspect map InspectMap(map); }Copy the code

Sensitive information

Sensitive information – Common sensitive information

Rule 2.1: Do not save sensitive user data in plaintext in logs

Sensitive user data stored in logs in plain text is easily leaked to O&M personnel or attackers

Rule 2.2: Do not hardcode sensitive information into a program

If sensitive information, including passwords and encryption keys, is hardcoded into a program, it may expose sensitive information to attackers. Anyone with access to a class file can decompile the class file and discover this sensitive information

. DriverManager.getConnection(url,"soctt","tiger") ...Copy the code

Java decompile Javap C Connmngr.class

ldc #36://String jdbc:mysql://ixne.com/rxsql

ldc #38://String scott

ldc #17://String tiger

Example:

Public class IPaddress{private String IPaddress = "172.16.254.1"; public static voidmain(String[] args){ //... }}Copy the code

Is:

public class IPaddress{ public static void main(String[] args) throws IOException{ char[] ipAddress= new char[100]; BufferedReader br= new BufferedReader(newInputStreamReader(newFileInputStream("serveripaddress.txt"))); // Reads the server IP address into the char array, // returns the number of bytes read intn = br.read(ipAddress); // Validate server IP address // Manually clear out the server IP address // immediately after use for(inti= n -1; i>= 0; i--){ ipAddress[i] = 0; } br.close(); }}Copy the code

Rule 2.3: Encrypting Mail transmission n/A During mail transmission, secure Sockets Layer (SSL) and TLS are used to encrypt mail transmission, preventing attackers from sniffing user data on the network. Example: The TLS protocol is not used during mail transmission

public class SendMailTLS{ public static void main(String[] args) { final String username="[email protected]"; final String password="password"; Properties props=new Properties(); // use TLS //props. Put ("mail.smtp.auth","true"); //props.put("mail.smtp.startls.enable","true"); / / to use SSL / / props. The put (" mail. The SMTP. SocketFactory, port ", "465"); //props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory"); //props.put("mail.smtp.auth","true"); props.put("mail.smtp.host","smtp.gmail.com"); props.put("mail.smtp.port","587"); Session session=Session.getInstance(props,new javax.mail.Authenticator){ protected PasswordAuthentication getPasswordAuthentication(){ return new PasswordAuthentication(username,password); }}); }}Copy the code

Example: The TLS protocol is used for encryption

public class SendMailTLS{ public static void main(String[] args) { final String username="[email protected]"; final String password="password"; Properties props=new Properties(); // use TLS props. Put ("mail.smtp.auth","true"); props.put("mail.smtp.startls.enable","true"); / / do the server certificate check props. The put (" mail. The SMTP. SSL. Checkserveridentity ", "true"); // Add the trusted server address. Props. Put ("mail.smtp.ssl.trust","smtp.gmail.com"); props.put("mail.smtp.host","smtp.gmail.com"); props.put("mail.smtp.port","25"); Session session=Session.getInstance(props,new javax.mail.Authenticator){ protected PasswordAuthentication getPasswordAuthentication(){ return new PasswordAuthentication(username,password); }}); }}Copy the code

Rule 2.4: Password stores based on hash algorithms must be salted and use the standard iteration PBKDF2

If no salt value is added, the same password will have the same Hash value

public class PasswordHash{ public static final String PBKDF2_ALGORITHM="PBKDF2WithHmacSHA1"; public static final int SALT_BYTE_SIZE=24; public static final int HASH_BYTE_SIZE=24; public static final int PBKDF2_ITERATIONS=1000; public static String createHash(char[] password) throws NoSuchAlgorithmException,InvalidKeySpecException{ //Generate a random salt SecureRandom random =new SecureRandom(); byte[] salt =new btye[SALT_BYTE_SIZE]; random.nextBytes(salt); // Hash the password byte[] hash =pbkdf2(password,salt,PBKDF2_ITERATIONS,HASH_BYTE_SIZE); //format iterations:salt:hash return PBKDF2_ITERATIONS+":"+toHex(hash); }}Copy the code

The encryption algorithm

Encryption algorithms – Overview of encryption algorithms

Rule 3.1 Insecure Encryption Algorithm – Do not use the insecure encryption algorithm DES\3DES

Encryption algorithm Use a secure encryption algorithm AES Attackers can decrypt insecure encryption algorithms and obtain sensitive information

Counterexample: The insecure algorithm DES is used

byte[] result = DES.encrypt(str.getBytes(),password);
//直接将如上内容解密
try{
byte[] decryResult =DES.decrypt(result,password);
System.out.println("解密后:"+new String(decryResult));
}catch(Excption e1){
e1.printStackTrace();
}
Copy the code

Rule 3.3: Symmetric encryption ALGORITHM AES- The AES insecure packet mode ECB is disallowed. Aes-gcm, which provides not only encryption but also integrity verification, is recommended

AES block cipher: AES-cbc aes-cfb AES-ofb AES-CTR

Counterexample: THE unsafe grouping mode ECB of AES is used

Pubilc class AES{// Encrypt public static String Encrypt(String sSrc,String sKey) throws Excetion{if(sKey==null){ System. The out. Print (" key is empty null "); return null; } // Check whether the key is 16 bits if(key.length()! =16){system.out. print("key length not 16 bits "); return null; } byte[] raw =sKey.getBytes("UTF-8"); SecreKeySpec skeySpec=new SecreKeySpec(raw,"AES"); Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding"); // Algorithm/mode/complement mode cipher.init(cipher.encrypt_mode,skeySpec); byte[] encrypted= cipher.doFinal(sScr.getByte("utf-8")); return new Base64().encodeToString(encrypted); // Base64 is used for transcoding and can be used for encryption twice}}Copy the code

Example: Use the SECURE packet mode CBC in the AES algorithm

Pubilc class AES{// Encrypt public static String Encrypt(String sSrc,String sKey) throws Excetion{if(sKey==null){ System. The out. Print (" key is empty null "); return null; } // Check whether the key is 16 bits if(key.length()! =16){system.out. print("key length not 16 bits "); return null; } byte[] raw =sKey.getBytes("UTF-8"); SecreKeySpec skeySpec=new SecreKeySpec(raw,"AES"); Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding"); IvParameterSpec iv =new IvParameterSpec(skey.getByte ()); // Algorithm/mode/complement IvParameterSpec iv =new IvParameterSpec(skey.getByte ()); Cipher. Init (cipher. ENCRYPT_MODE,skeySpec, iv); // To use CBC mode, a vector iv is required. byte[] encrypted= cipher.doFinal(sScr.getByte("utf-8")); return new Base64().encodeToString(encrypted); // Base64 is used for transcoding and can be used for encryption twice}}Copy the code

Rule 3.4: Asymmetric encryption algorithm RSA- The length of the asymmetric encryption algorithm RSA must be at least 2048 bits

If the RSA key length is less than 2048 bits, the RSA key length cannot meet security standards. Example: The RSA key length is only 1024 bits

public static HashMap<String,Object>getKeys()throws NoSuchAlgorithmException{
	HashMap<String,Object> map=new HashMap<String,Object>;
	KeyPairGenerator keyPairGen=KeyPairGenerator.getInstance("RSA");
	keyPairGen.initialize(1024);
	KeyPair keyPair=keyPairGen.generateKeyPair();
	RSAPublicKey pubilcKey=(RSAPublicKey) keyPair.getPublic();
	RSAPrivateKey privateKey =(RSAPrivateKey) keyPair.getPrivate();
	map.put("public",pubilcKey);
	map.put("private",privateKey);
	return map;
}
Copy the code

Example: The key length of the RSA algorithm must be at least 2048 bits

public static HashMap<String,Object>getKeys()throws NoSuchAlgorithmException{
	HashMap<String,Object> map=new HashMap<String,Object>;
	KeyPairGenerator keyPairGen=KeyPairGenerator.getInstance("RSA");
	keyPairGen.initialize(2048);
	KeyPair keyPair=keyPairGen.generateKeyPair();
	RSAPublicKey pubilcKey=(RSAPublicKey) keyPair.getPublic();
	RSAPrivateKey privateKey =(RSAPrivateKey) keyPair.getPrivate();
	map.put("public",pubilcKey);
	map.put("private",privateKey);
	return map;
}
Copy the code

Rule 3.5: Sensitive data encryption uses strong random numbers

Pseudo-random number generator is portable and repeatable. Attackers can listen on some security vulnerable points of the system and build the corresponding query table to predict the seed value to be used, so as to predict the relevant sensitive data pseudo-random number examples:

import java.util.Random; public class RandomDemo{ Random random1=new Random(100); System.out.println(random1.nextInt()); System.out.println(random1.nextFloat()); System.out.println(random1.nextBoolean()); Random random2=new Random(100); System.out.println(random2.nextInt()); System.out.println(random2.nextFloat()); System.out.println(random2.nextBoolean()); } import java.io.UnsupporedEncodeingException; import java.util.Random; public class SecureRandom{ public static void main(String[] args)throws UnsupporedEncodeingException{ Random ranGen=new Random(); byte[] aesKey=new byte[20]; ranKey.nextBytes(aesKey); StringBuffer hexString =new StringBuffer(); for (int i=0; i<aesKey.length; i++){ String hex=Integer.toHexString(0xff&aesKey[i]); if(hex.length()==1) hexString.append(''0); hexString.append(hex); } System.out.println(hexString); }}Copy the code

Strong random number example:

import java.io.UnsupporedEncodeingException; import java.util.Random; import java.security.SecureRandom; public class SecureRandom{ public static void main(String[] args)throws UnsupporedEncodeingException{ Random ranGen=new SecureRandom(); byte[] aesKey=new byte[20]; ranKey.nextBytes(aesKey); StringBuffer hexString =new StringBuffer(); for (int i=0; i<aesKey.length; i++){ String hex=Integer.toHexString(0xff&aesKey[i]); if(hex.length()==1) hexString.append(''0); hexString.append(hex); } System.out.println(hexString); }}Copy the code

Serialization and deserialization

  • Java serialization refers to the process of converting a Java object into a sequence of bytes for easy storage in memory, files, or databases. The writeObject() method of ObjectOutputStream implements the serialization.

  • Java deserialization is the process of restoring a sequence of bytes to Java objects. The readObject() method of the ObjectInputStream class is used for deserialization.

    Public class Test{public static void main(String[] args) throws Exception{// Define MyObject myObj=new MyObject(); FileOutputStream fos=new FileOutputStream("object"); ObjectOutputStream os =new ObjectOutputStream(fos); Os.writeobject (myObj); //writeObject() writes the myObj object to the objct file. os.close(); FileInputStream fis=new FileInputStream("object"); ObjectInputStream ois =new ObjectInputStream(fis); Ois.readobject (); MyObject objectFromDisk=(MyObject)ois.readObject(); System.out.println(objectFromDisk.name); ois.close; } } class MyObject implements Serializable{ public String name; / / rewrite readObject () method of the private void readObject (Java. IO. ObjectInputStream in) throws IOExeption {/ / perform a default readObject () method in.defaultReadObject(); / / open the calculator program command Runtime. GetRuntime (). The exec (" open/Application/Calcultor. App ")}}Copy the code

Serialization vs. deserialization – Deserialization vulnerability

The ObjectInputStream class should limit the type of objects generated when deserializing them

Counterexample: Unsafe deserialization operations that result in arbitrary command execution and control of the server

ServerSocket serverSocket =new ServerSocket(Integer,parseInt("9999")); while(true){ Socket socket=serverSocket.accpet(); ObjectInputStream objectInputStream=new ObjectInputStream(socket.getInputStream()); try{ Object object=objectInputStream.readObject(); }catch(Exception e){ e.printStackTrace(); }}Copy the code

Rule 4.1: The ObjectInputStream class limits the types of generated objects when deserializing them

public final class SecureObjectInputStram extends ObjectInputStream{ public SecureObjectInputStram() throws IOException{  super(); } public SecureObjectInputStram( InputStream in) throws IOException{ super(in); } portected Class<? >resolveClass(ObjectStreamClass desc) throws ClassNotFoundException,IOException{ if(! desc.getName().equals("java.security.Person")){ throws new ClassNotFoundException(desc.getName()+"not found"); } return super.resolveClass(desc); }}Copy the code

Serialization and deserialization – Insecure deserialization vulnerability solution

Solution:

  • Use secure deserialization plug-ins to update and patch any deserialization vulnerabilities exposed in the industry.
  • The transmitted data should be encrypted and verified in the background to ensure that data is not tampered with.
  • ObjectInputStream: override resolveClass to whitelist className.
  • Java9 can inherit the Java. IO. ObjectInputFilter class rewrite checkInput method to realize a custom filter.
  • The SecurityManager is extended to prevent the JVM from executing external commands runtime.exec.

I/O operations

Rule 5.1: File upload format and size should be limited according to service requirements

Counterexample: unqualified format

@RequestMapping(value="/upload",method=RequestMethod.POST) public String upload(HttpServletRequest request, @RequestParam("description") String description, @RequestParam("file") MultipartFile file)throws Exception{ if(! file.isEmpty()){ String path=request.getServletContext().getRealPath("/images/"); String filename= file.getoriginalfilename (); File filepath=new File(path,filename); // Determine if the path exists and create an if(! filepath.getParentFile().exists()){ filepath.getParentFile.mkdirs(); // Upload the file to a target file file.transferto (new file (path+ file.separator +filename)); return "success" }else{ return "error"; }}Copy the code

Example: Restrict the format of file uploads

@RequestMapping(value="/upload",method=RequestMethod.POST) public String upload(HttpServletRequest request, @RequestParam("description") String description, @RequestParam("file") MultipartFile file)throws Exception{ if(! file.isEmpty()){ String path=request.getServletContext().getRealPath("/images/"); String filename= file.getoriginalfilename (); . / / there is a way to filenameUtils getExtension (); String suffix=filename.substring(filename.lastIndexOf(".")+1) if(suffix! ="jpg"){ File filepath=new File(path,filename); // Determine if the path exists and create an if(! filepath.getParentFile().exists()){ filepath.getParentFile.mkdirs(); // Upload the file to a target file file.transferto (new file (path+ file.separator +filename)); } return "success" ; }else{ return "error"; }}Copy the code

Rule 5.2: Path traversal – where files are downloaded, file paths should be verified, or files should be downloaded using file IDS mapped to files

Example:

protected void doGet(HttpServletRequest request,HttpServeltResponse response) throws ServeltExceptio,IOException{ / / to get project deployment under the absolute path of the upload folder path, download and upload files in the directory String root = request. GetServeltContext () getRealPath ("/upload "); String filename= request.getparameter ("filename"); File File =new File(root+"/"+filename); FileInputStream fis= new FileInputStream(file); Response. addHeader(" Content-disposition ","attachment; filename="+new String(filename.getBytes())); response.addHeader("Content-Length",""+file.length()); byte[] b =new byte[fis.availabe()]; fis.read(b); response.getOutStream().write(b); }Copy the code

Example: Verify file names using whitelists

protected void doGet(HttpServletRequest request,HttpServeltResponse response) throws ServeltExceptio,IOException{ / / to get project deployment under the absolute path of the upload folder path, download and upload files in the directory String root = request. GetServeltContext () getRealPath ("/upload "); String filename= request.getparameter ("filename"); If (filename== filename) {// Create an input stream based on the File path File File =new File(root+"/"+filename); FileInputStream fis= new FileInputStream(file); Response. addHeader(" Content-disposition ","attachment; filename="+new String(filename.getBytes())); response.addHeader("Content-Length",""+file.length()); byte[] b =new byte[fis.availabe()]; fis.read(b); response.getOutStream().write(b); }}Copy the code

Rule 5.3: Unreleased Resource A Resource that has been actively released by Streams using files, IO Streams, database connections, etc

When using files, I/O streams, database connections, etc., resources that are not automatically released, do not close them immediately after they are used. The code to close the resources should be in the try… catch… finally{if (fos ! = null) {fos.close(); }} in finally

private static void TestCloseFileStream(){ String fileName=""; InputStream =null; try{ inputStream=new FileInputStream(filename); }catch(IOException e){ //do something }finally{ if(inputStream! =null){try{// Close stream inputStream.close(); }catch(IOException e){ //do something } } } }Copy the code

Rule 5.4: Delete temporary files after use

Example:

public class TempFile{ public static void main(STring[] args) throws IOExcption{ File f =new File("tempnam.tmp"); if(f.exists()){ System.out.println("This file already exists"); return; } FileOutputStream fop=null; try{ fop=new FileOutputStream(f); String str="Data"; fop.write(str.getBytes()); }finally{ if(fop! =null){ try{ fop.close(); }catch(IOException e){ // handle error } } } } }Copy the code

Is:

public class TempFile{ public static void main(STring[] args) throws IOExcption{ File f =new File("tempnam.tmp"); if(f.exists()){ System.out.println("This file already exists"); return; } FileOutputStream fop=null; try{ fop=new FileOutputStream(f); String str="Data"; fop.write(str.getBytes()); }finally{ if(fop! =null){ try{ fop.close(); }catch(IOException e){ // handle error } //delete file when finished if(! f.delete()){ //log the error } } } } }Copy the code

Double-checked Locking

Rule 6.1: Use locking mechanism in multithreading to prevent deadlocks caused by multithreading operations

Double locking (unsafe in multiple threads)

public class Singleton{ private static Singleton singleton; private Singleton(){} public static Singleton getSingleton(){ if(singleton==null){ synchronized (Singleton.class){ if(singleton==null){ singleton=new Singleton(); } } } return singleton; Singleton = new singleton () 1. Memory =allocate(); 2. CtorInstance (memory); Singleton =memory; Memory =allocate(); allocate(); allocate(); allocate(); Singleton =memory; // set instance to the newly allocated memory address // Note that the object has not been initialized yet! 3. ctorInstance(memory); //2: initializes the objectCopy the code

Double-checked Locking uses the synchronized keyword for methods

public class Singleton{ private static Singleton singleton; private Singleton(){} public static synchronized Singleton getSingleton(){ if(singleton==null){ singleton=new Singleton(); } return singleton; }}Copy the code

Preinitialization

public class Singleton{ private static class SingletonHolder{ private static final Singleton singleton=new Singleton(); } private Singleton(){} public static final Singleton getSingleton(){ return SingletonHolder.INSTANCE; }}Copy the code

Frameworks and Components – Frameworks and component security

Rule 7.1: Use secure versions of frameworks and components. Download them from the official website. Use frameworks and components

For example: WebLogic, Struts2, Nginx –Fastjson, ImageMagick, Log4j

Rule 7.2: Do not use frameworks or components from unknown sources

Rule 7.3: Keep framework and component versions up to date

Abnormal behavior – Abnormal information exposed externally

Rule 8.1: Do not expose abnormal information to the front end

try{
    FileInputStream fis =new FileInputStream(System.getenv("APPDATA")+args[0]);
}catch(FileNotFoundException e){
    //Log the exception
    throws new IOException ("Unable to retrieve file",e);
}
Copy the code

Resolution: Generates fixed error messages and does not leak exception information to the outside world


Finally, you can pay attention to the public number, learning together, every day will share dry goods, and learning video claim!