Enjoy Sharing Technology!

Software,Develope,Devops, Security,TroubleShooting

Sunday, November 21, 2021

error: Microsoft Visual C++ 14.0 is required

For developers, they often pip install the packages they need. Most of the packages can be installed basically, but they will always encounter the problem of not being able to install the packages. The first step of pre-study learning motivation is killed by the installation package. . One of the most troubled is this question: error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual……

I tried a lot of methods on the Internet, but still did not fundamentally solve the problem. Generally, for this kind of package that cannot be installed by pip, one is to go to the Python installation package complete (https://www.lfd.uci.edu/~gohlke/pythonlibs/) to download the installation package with the corresponding suffix of .whl. Install.

How to install the installation package with the suffix .whl: Download the corresponding installation package with the suffix .whl and place it in the folder you specify, enter cmd,

pip install Scrapy-1.5.0-py2.py3-none-any.whl 

The other is that if the package with the suffix .whl is not found, or the .whl package is not successfully installed, it is generally installed on the operating system. It is very convenient to install these packages on the Linux system with pip, and no error will be reported.

To solve this problem fundamentally, you can refer to the following.

When running the code first, it says that the XXX package is not installed. If you encounter this problem, go to cmd, and the pip install installation error is reported:


It shows that the visual studio installer has stopped working. . .

I tried to download and install Microsoft Visual 2017 https://download.csdn.net/download/heyshheyou/10624594, but when I downloaded it and installed it, I reported an error as soon as I clicked to install it, and the visual studio installer has stopped working. I was completely speechless. . . . . Download different versions of visual studio installation are all reporting this error, it may be a program conflict.

There are also uninstalling .NET Framework files on the Internet, downloading a newest .NET Framework file; and also uninstalling all files beginning with Microsoft Visual:

I almost tried it, but fortunately I continued to find other solutions. Except in the end, there is no way to try, or reinstall the system. Do not reinstall the system as a last resort.
Troubleshoot blocked installation and uninstallation of .NET Framework
For the downloaded version of Microsoft Visual C++:
Visual Studio 2013 ---> 12
Visual Studio 2015 ---> 14
 Visual Studio 2017 ---> 15

Python3 is compiled with VC++14, python27 is compiled with VC++9, and the package to install python3 needs to be compiled and supported by VC++14 or above.
If you encounter an error: error: Microsoft Visual C++ 14.0 is required, please try the following solutions first.

Solution:

Installed Microsoft visual c++ 14.0, searched for a lot of packages, and finally found a Microsoft Visual C++ Build Tools 2015 :visualcppbuildtoos_full.exe .

Double-click visualcppbuildtools_full.exe, select the default, click install, and wait for about 10 minutes to complete the installation.

Finally, the installation is complete, check the control panel-program-uninstall program under an additional file Microsoft visual c++ Build Tools:

That is, the installation is successful.

As a result, go to pip in cmd to install the packages you need.






Share:

fortify scan: XML Injection

Abstract:

XML Injection is an attack technique used to manipulate or compromise the logic of an XML application or service. The injection of unintended XML content and/or structures into an XML message can alter the intend logic of the application. Further, XML injection can cause the insertion of malicious content into the resulting message/document.



Explanation:

XML injection occurs when:

1. Data enters a program from an untrusted source.

2. The data is written to an XML document.

Applications typically use XML to store data or send messages. When used to store data, XML documents are often treated like databases and can potentially contain sensitive information. XML messages are often used in web services and can also be used to transmit sensitive information. XML messages can even be used to send authentication credentials.

The semantics of XML documents and messages can be altered if an attacker has the ability to write raw XML. In the most benign case, an attacker may be able to insert extraneous tags and cause an XML parser to throw an exception. In more nefarious cases of XML injection, an attacker may be able to add XML elements that change authentication credentials or modify prices in an XML e-commerce database. In some cases, XML injection can lead to cross-site scripting or dynamic code evaluation.

Example 1:

Assume an attacker is able to control shoes in following XML.

<order>

   <price>100.00</price>

   <item>shoes</item>

</order>

Now suppose this XML is included in a back end web service request to place an order for a pair of shoes. Suppose the attacker modifies his request and replaces shoes with shoes</item><price>1.00</price><item>shoes. The new XML would look like:

<order>

    <price>100.00</price>

    <item>shoes</item><price>1.00</price><item>shoes</item>

</order>

This may allow an attacker to purchase a pair of $100 shoes for $1.

Recommendations:

When writing user supplied data to XML, follow these guidelines:

1. Do not create tags or attributes with names that are derived from user input.

2. XML entity encode user input before writing to XML.

3. Wrap user input in CDATA tags.

Share:

Wednesday, November 17, 2021

OutOfMemoryError(4): Metaspace

A series of articles on this topic:

JVM limits the maximum memory of Java programs, and this limitation can be changed by modifying/specifying startup parameters. Java divides the heap memory into multiple parts, as shown in the following figure:


[Java8 and above] The maximum value of these memory pools is specified by JVM startup parameters such as -Xmx and -XX:MaxMetaspaceSize. If not explicitly specified, it will be determined according to the platform type (OS version + JVM version) and the size of the physical memory. java.lang.OutOfMemoryError: The information expressed by the Metaspace error is: Metaspace has been used up.

Cause Analysis
If you are an old Java driver, you should be familiar with PermGen. But starting from Java 8, the memory structure has undergone major changes. Permgen is no longer used, but a new space is introduced: Metaspace. This change is based on many considerations, partly The reasons are listed as follows:

The specific size of the Permgen space is difficult to predict. Specifying a small size will cause java.lang.OutOfMemoryError: Permgen size error, and setting too many will cause waste.

In order to improve the performance of GC, the concurrent phase of the garbage collection process is no longer paused, and metadata is specifically traversed (specific iterators).

Deeply optimize the concurrent class unloading of the G1 garbage collector.

In Java 8, all the content in PermGen before has been moved to the Metaspace space. For example: class name, field, method, bytecode, constant pool, JIT optimized code, etc.

Metaspace usage is related to the number/size of classes loaded into memory by JVM. It can be said that the main reason for java.lang.OutOfMemoryError: Metaspace error is that the number of classes loaded into the memory is too large or the size is too large.

Example
Similar to PermGen , the amount of Metaspace space used has a lot to do with the number of classes loaded by the JVM. Here is a simple example:

public class Metaspace {
  static javassist.ClassPool cp = javassist.ClassPool.getDefault();
  public static void main(String[] args) throws Exception{
    for (int i = 0; ; i++) { 
      Class c = cp.makeClass("eu.plumbr.demo.Generated" + i).toClass();
    }
  }
}

As you can see, it is very simple to use the javassist tool library to generate a class. In the for loop, a lot of classes are dynamically generated, and these classes are finally loaded into the Metaspace.

Execute this code, as more and more classes are generated, it will eventually fill up the Metaspace space, throwing java.lang.OutOfMemoryError: Metaspace. On Mac OS X, in the Java 1.8.0_05 environment, if the startup is set Parameter -XX:MaxMetaspaceSize=64m, JVM will hang after about 70,000 classes are loaded.

solution:

If an OutOfMemoryError related to Metaspace is thrown, the first solution is to increase the size of Metaspace. Use the following startup parameters:

-XX:MaxMetaspaceSize=512m

Here, the maximum value of Metaspace is set to 512MB, if it is not used up, OutOfMemoryError will not be thrown.

There is a seemingly simple solution, which is to directly remove the size limit of Metaspace. But it should be noted that there is no limit to the size of Metaspace memory. If the physical memory is insufficient, it may cause memory swapping, which will seriously affect system performance. In addition, it may cause problems such as native memory allocation failure.

In modern application clusters, it is better to let the application node go down than to respond slowly.

If you don't want to receive an alarm, you can hide the java.lang.OutOfMemoryError: Metaspace error message like an ostrich. But this will not really solve the problem, it will only delay the outbreak of the problem. If there is a memory leak, please refer to these articles and look for a solution carefully.
Share:

OutOfMemoryError(3): Permgen space

 A series of articles on this topic:

Note: Permgen (permanent generation) belongs to the concept of JDK1.7 and previous versions; in order to adapt to the development of Java programs, JDK8 and later versions use less restrictive MetaSpace instead

JVM limits the maximum memory usage of Java programs, which can be configured through startup parameters. The heap memory of Java is divided into multiple areas, as shown in the following figure:



The maximum value of these areas is specified by the JVM startup parameters -Xmx and -XX:MaxPermSize. If not explicitly specified, it is determined according to the operating system platform and the size of the physical memory.

java.lang.OutOfMemoryError: PermGen space error message means: Permanent Generation (Permanent Generation) memory area is full.

Cause Analysis

Let's first look at what PermGen is used for.

In JDK1.7 and earlier versions, permanent generation is mainly used to store class definitions loaded/cached in memory, including class names, fields, methods and bytecodes (method bytecode); and constant pool information; classes associated with object arrays/type arrays, and class information optimized by the JIT compiler.

It is easy to see that the usage of PermGen is related to the number/size of classes loaded into memory by the JVM. It can be said that the main reason for java.lang.OutOfMemoryError: PermGen space is that the number of classes loaded into the memory is too large or the size is too large.

The simplest example

We know that the usage of PermGen space has a lot to do with the number of classes loaded by the JVM. The following code demonstrates this situation:

import javassist.ClassPool;

public class MicroGenerator {

  public static void main(String[] args) throws Exception {

    for (int i = 0; i < 100_000_000; i++) {

      generate("eu.plumbr.demo.Generated" + i);

    }

  }

  public static Class generate(String name) throws Exception {

    ClassPool pool = ClassPool.getDefault();

    return pool.makeClass(name).toClass();

  }

}

This code generates many classes dynamically in the for loop. As you can see, it is very simple to use the javassist tool class to generate a class.

Executing this code will generate a lot of new classes and load them into memory. As more and more classes are generated, they will fill up the Permgen space, and then throw a java.lang.OutOfMemoryError: Permgen space error, of course , Other types of OutOfMemoryError may also be thrown.

To see the effect quickly, you can add appropriate JVM startup parameters, such as: -Xmx200M -XX:MaxPermSize=16M and so on.

OutOfMemoryError during Redeploy

Note: If Tomcat generates a warning during development, you can ignore it. It is recommended not to redploy in the production environment, just close/or Kill related JVM directly, and then start from the beginning.

The following situation is more common. When redeploying a web application, it is likely to cause a java.lang.OutOfMemoryError: Permgen space error. It stands to reason that when redeploying, a container such as Tomcat will use a new classloader to load a new class. Let the garbage collector clean up the previous classloader (along with the loaded class).

But the actual situation may not be optimistic. Many third-party libraries, as well as some restricted shared resources, such as threads, JDBC drivers, and file system handles (handles), will cause the previous classloader to be unable to be completely uninstalled. Then in redeploy, The previous class still resides in PermGen, and each redeployment will generate tens of MB or even hundreds of MB of garbage.

Suppose that when an application is started, the JDBC driver is loaded through the initialization code to connect to the database. According to the JDBC specification, the driver will register itself to java.sql.DriverManager, that is, add an instance of itself to a static in DriverManager area.

Then, when the application is uninstalled from the container, java.sql.DriverManager still holds a JDBC instance (Tomcat often warns), and the JDBC driver instance holds a java.lang.Classloader instance, so the garbage collector has no way. Reclaim the corresponding memory space.

The java.lang.ClassLoader instance holds all the loaded classes, usually tens/hundreds of MB of memory. As you can see, redeploy will take up another piece of PermGen space of the same size. After multiple redeploys, it will cause java.lang.OutOfMemoryError: PermGen space error. In the log file, you should see related error messages.

solution

1. Solve the OutOfMemoryError generated when the program starts

When the program starts, if PermGen is exhausted and an OutOfMemoryError is generated, it is easy to solve. Increase the size of PermGen so that the program has more memory to load the class. Modify the -XX:MaxPermSize startup parameter, similar to the following:

java -XX:MaxPermSize=512m com.yourcompany.YourClass

The above configuration allows the JVM to use the maximum PermGen space of 512MB, if it is not enough, an OutOfMemoryError will be thrown.

2. Solve the OutOfMemoryError generated during redeploy

We can perform heap dump analysis-after redeploy, perform a heap dump, similar to the following:
jmap -dump:format=b,file=dump.hprof <process-id>

Then use a heap dump analyzer (such as the powerful Eclipse MAT) to load the dump file. Find out the duplicate classes, especially the class corresponding to the classloader. You may need to compare all the classloaders to find the one currently in use.

Eclipse MAT  official website download address: http://www.eclipse.org/mat/downloads.php

For an inactive classloader (inactive classloader), you need to determine the shortest path GC root first, and see which one prevents it from being recycled by the garbage collector. In this way, you can find the source of the problem. If it is a third-party library, Then you can search Google/StackOverflow to find the solution. If it is your own code problem, you need to dereference at the right time.

3. Solve OutOfMemoryError generated during runtime
If an OutOfMemoryError occurs during operation, first confirm whether the GC can unload the class from PermGen. The official JVM is quite conservative in this regard (after loading a class, it has been allowed to reside in memory, even if the class is no longer used). However, modern applications will dynamically create a large number of The life cycle of these classes is basically very short, and the old version of JVM cannot handle these problems well. Then we need to allow the JVM to uninstall the class. Use the following startup parameters:

-XX:+CMSClassUnloadingEnabled

By default, the value of CMSClassUnloadingEnabled is false, so it needs to be specified explicitly. After enabling, GC will clean up PermGen and uninstall useless classes. Of course, this option only takes effect when UseConcMarkSweepGC is set. If you use ParallelGC, or Serial GC, you need to switch to CMS:
-XX:+UseConcMarkSweepGC

If it is determined that the class can be unloaded, if OutOfMemoryError still exists, then a heap dump analysis is required, similar to the following command:
jmap -dump:file=dump.hprof,format=b <process-id> 

Then load the heap dump through a heap dump analyzer (such as Eclipse MAT). Find the heaviest classloader, that is, the one with the largest number of loaded classes. Compare the class loader with the loaded class and the number of corresponding instances, find the top part, and analyze it one by one.

For each suspected class, you need to manually trace to the code that generates these classes to locate the problem.





Share:

OutOfMemoryError(2): GC overhead limit exceeded

A series of articles on this topic:

The Java runtime environment has a built-in garbage collection (GC) module. Many programming languages of the previous generation did not have an automatic memory recovery mechanism, and programmers were required to manually write code to allocate and release memory to reuse heap memory.

In a Java program, you only need to care about memory allocation. If a block of memory is no longer used, the Garbage Collection module will automatically clean it up. For the detailed principle of GC, please refer to the GC performance optimization series of articles. Generally speaking, the garbage collection algorithm built in JVM can handle most business scenarios.

java.lang.OutOfMemoryError: GC overhead limit exceeded The reason this happens is that the program basically uses up all the available memory, and the GC can't clean it up.

Cause Analysis:

JVM throws java.lang.OutOfMemoryError: GC overhead limit exceeded error is a signal: the proportion of time to perform garbage collection is too large, and the amount of effective calculation is too small. By default, if the time spent in GC exceeds 98%, And if the memory reclaimed by GC is less than 2%, the JVM will throw this error.

Note that the java.lang.OutOfMemoryError: GC overhead limit exceeded error is only thrown in extreme cases where less than 2% of the GC has been recycled for multiple consecutive times. What happens if the GC overhead limit error is not thrown? That is, the memory cleaned up by the GC will fill up again soon, forcing the GC to execute again. This forms a vicious circle, the CPU usage is always 100%, and the GC But there is no result. System users will see that the system freezes-an operation that used to take only a few milliseconds, now takes several minutes to complete.

This is also a good case of the fast failure principle.

Example:
The following code adds data to the Map in an infinite loop. This will result in a "GC overhead limit exceeded" error:

public class OOM {

    static final int SIZE=2*1024*1024;

    public static void main(String[] a) {

        int[] i = new int[SIZE];

    }

}

Configure JVM parameters: -Xmx12m. The error message generated during execution is as follows:

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded

    at java.util.Hashtable.addEntry(Hashtable.java:435)

    at java.util.Hashtable.put(Hashtable.java:476)

    at com.cncounter.rtime.TestWrapper.main(TestWrapper.java:11)

The error message you encounter is not necessarily the same. Indeed, the JVM parameters we executed are:

java -Xmx12m -XX:+UseParallelGC TestWrapper

Soon I saw the java.lang.OutOfMemoryError: GC overhead limit exceeded error message. But in fact, this example is a bit tricky. Because of different heap memory sizes, different GC algorithms are used, the error messages generated are different. For example, when the Java heap memory is set to 10M:

java -Xmx10m -XX:+UseParallelGC TestWrapper

The error message in DEBUG mode is as follows:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

    at java.util.Hashtable.rehash(Hashtable.java:401)

    at java.util.Hashtable.addEntry(Hashtable.java:425)

    at java.util.Hashtable.put(Hashtable.java:476)

    at com.cncounter.rtime.TestWrapper.main(TestWrapper.java:11)

Try to modify the parameters, execute to see the specifics. The error message and stack information may be different.

The java.lang.OutOfMemoryError: Java heap space error message is thrown when the Map is rehashing. If you use other garbage collection algorithms, such as -XX:+UseConcMarkSweepGC, or -XX:+UseG1GC, the error will be caused by the default exception handler Capture, but there is no stacktrace information, because there is no way to fill the stacktrace information when creating an Exception.

For example configuration:

-Xmx12m -XX:+UseG1GC

Running in Win7x64, Java8 environment, the error message generated is:

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"

It is recommended that readers modify the memory configuration and test the garbage collection algorithm.

These real cases show that under resource constraints, it is impossible to accurately predict which specific reasons a program will die of. Therefore, in the face of such errors, a specific error processing sequence cannot be bound.

solution:

There is a solution to deal with the problem, just don't want to throw "java.lang.OutOfMemoryError: GC overhead limit exceeded" error message, then add the following startup parameters

// not recommendation

-XX:-UseGCOverheadLimit

We strongly recommend not to specify this option: because it does not really solve the problem, it can only postpone the occurrence of out of memory errors a little bit, and other processing must be done at the end. Specifying this option will cover up the original java.lang.OutOfMemoryError: GC overhead limit exceeded error and turn it into a more common java.lang.OutOfMemoryError: Java heap space error message.

Note: Sometimes the cause of the GC overhead limit error is caused by insufficient heap memory allocated to the JVM. In this case, you only need to increase the heap memory size.

In most cases, increasing the heap memory does not solve the problem. For example, there is a memory leak in the program, and increasing the heap memory can only delay the time of java.lang.OutOfMemoryError: Java heap space error.

Of course, increasing the heap memory may also increase the time of GC pauses, thereby affecting the throughput or delay of the program.

If you want to solve the problem fundamentally, you need to troubleshoot the code related to memory allocation. Simply put, you need to answer the following questions:

Which type of object takes up the most memory?

These objects are allocated in which part of the code.

To figure this out, it may take several days. The following is the general process:

Obtain the permission to perform a heap dump on the production server. "Dump" is a snapshot of the heap memory, which can be used for subsequent memory analysis. These snapshots may contain confidential information, such as passwords, credit card accounts, etc., so sometimes, due to corporate security restrictions, it is necessary to obtain the production environment Heap dumping is not easy.

Perform a heap dump at the appropriate time. Generally speaking, memory analysis needs to compare multiple heap dump files. If the timing is not right, it may be a "scrap" snapshot. In addition, every time a heap dump is executed, the JVM will be "freeze" ", so in the production environment, you can't perform too many dump operations, otherwise the system is slow or stuck, and your troubles will be big.

Use another machine to load the Dump file. If the JVM memory in question is 8GB, the machine memory for analyzing Heap Dump generally needs to be greater than 8GB. Then open the dump analysis software (we recommend Eclipse MAT, of course, you can also use other tools).

Detect the GC roots that occupy the most memory in the snapshot. For details, please refer to: Solving OutOfMemoryError (part 6) – Dump is not a waste. This may be a bit difficult for novices, but it will also deepen your understanding of the heap memory structure and navigation mechanism.

Next, find out the code that may allocate a large number of objects. If you are very familiar with the entire system, you may be able to locate the problem very quickly. If you are unlucky, you will have to work overtime to investigate.







Share:

OutOfMemoryError(1): Java heap space

A series of articles on this topic:

Each Java program can only use a certain amount of memory, and this limitation is determined by the startup parameters of the JVM. The more complicated situation is that the memory of Java programs is divided into two parts: Heap space and Permanent Generation (Permgen):

The maximum memory size of these two areas is specified by the JVM startup parameters -Xmx and -XX:MaxPermSize. If not explicitly specified, it is determined according to the platform type (OS version + JVM version) and the size of the physical memory. If when creating a new object, the space in the heap memory is not enough to store the newly created object, it will cause java.lang.OutOfMemoryError: Java heap space error. No matter there is no free physical memory on the machine, as long as the heap memory usage reaches the maximum memory limit, a java.lang.OutOfMemoryError: Java heap space error will be thrown.


Cause Analysis:

The reason for the java.lang.OutOfMemoryError: Java heap space error is often similar to stuffing the object of the XXL number into the Java heap space of the S number. In fact, if you know the reason, it's easy to solve, right? Just increase the size of the heap memory, and the program can run normally. In addition, there are some more complicated situations, mainly caused by code problems:
The amount of visits/data exceeded expectations. When designing an application system, there is generally a definition of "capacity", so many machines are deployed to process a certain amount of data/business. If the number of visits soars suddenly and exceeds the expected threshold, which is similar to a pinpoint-shaped map in the time coordinate system, then the program is likely to be stuck during the time period when the peak is located, and java.lang.OutOfMemoryError: Java heap space error is triggered. .
Memory leak. This is also a common situation. Due to some errors in the code, the system occupies more and more memory. If there is a memory leak in a certain method/a certain piece of code, every time it is executed, it will take up more memory (there are more garbage objects) . As the running time goes by, the leaked object consumes all the memory in the heap, then the java.lang.OutOfMemoryError: Java heap space error broke out.

A very simple example:

The following code is very simple. The program tries to allocate an int array with a capacity of 2M. If the startup parameter -Xmx12m is specified, then java.lang.OutOfMemoryError: Java heap space error will occur. As long as the parameter is slightly modified to -Xmx13m, the error will no longer occur.

publicclass OOM {static final int SIZE=2*1024*1024; publicstaticvoidmain(String[] a) {int[] i = newint[SIZE]; }}

public class OOM {
    static final int SIZE=2*1024*1024;
    public static void main(String[] a) {
        int[] i = new int[SIZE];
    }
}

Memory leak example:

This example is more realistic. In Java, when creating a new object, such as Integer num = new Integer(5);, there is no need to manually allocate memory. Because the JVM automatically encapsulates and handles memory allocation. During the execution of the program, the JVM will check if necessary which objects are still in use in the memory, and those objects that are no longer used will be discarded and the memory occupied by them will be discarded. Recycle and reuse. This process is called garbage collection. The module responsible for garbage collection in the JVM is called the garbage collector (GC).

Java's automatic memory management relies on GC. GC scans the memory area over and over again and deletes unused objects. Simply put, memory leaks in Java are those logically no longer used objects, but they are not garbage collected The program is killed. As a result, garbage objects continue to occupy the heap memory, gradually accumulate, and finally cause java.lang.OutOfMemoryError: Java heap space error.

It is easy to write a BUG program to simulate a memory leak:

import java.util.*;

public class KeylessEntry {

    static class Key {
        Integer id;

        Key(Integer id) {
        this.id = id;
        }

        @Override
        public int hashCode() {
        return id.hashCode();
        }
     }

    public static void main(String[] args) {
        Map m = new HashMap();
        while (true){
        for (int i = 0; i < 10000; i++){
           if (!m.containsKey(new Key(i))){
               m.put(new Key(i), "Number:" + i);
           }
        }
        System.out.println("m.size()=" + m.size());
        }
    }
}

At a glance, you may think that there is no problem, because this caches up to 10,000 elements! But a closer examination will find that the Key class only rewrites the hashCode() method, but does not rewrite the equals() method, so it will continue Add more keys to the HashMap.
As time goes by, there will be more and more "cached" objects. When the leaked objects occupy all the heap memory and the GC can't clean it up, a java.lang.OutOfMemoryError: Java heap space error will be thrown.
The solution is simple, implement the equals() method appropriately in the Key class:
@Override public boolean equals(Object o) { boolean response = false; if (o instanceof Key) { response = (((Key)o).id).equals(this.id); } return response; }
To be honest, when looking for the real cause of a memory leak, you may die many, many brain cells.

A scene in SpringMVC

In order to be easily compatible with the code migrated from Struts2 to SpringMVC, the request is directly obtained in the Controller.

So in the ControllerBase class, the request object held by the current thread is cached through ThreadLocal:

public abstract class ControllerBase {

    private static ThreadLocal<HttpServletRequest> requestThreadLocal = new ThreadLocal<HttpServletRequest>();

    public static HttpServletRequest getRequest(){
        return requestThreadLocal.get();
    }
    public static void setRequest(HttpServletRequest request){
        if(null == request){
        requestThreadLocal.remove();
        return;
        }
        requestThreadLocal.set(request);
    }
}

Then in the SpringMVC Interceptor implementation class, in the preHandle method, save the request object to ThreadLocal:


public class LoginCheckInterceptor implements HandlerInterceptor {
    private List<String> excludeList = new ArrayList<String>();
    public void setExcludeList(List<String> excludeList) {
        this.excludeList = excludeList;
    }

    private boolean validURI(HttpServletRequest request){
        String uri = request.getRequestURI();
        Iterator<String> iterator = excludeList.iterator();
        while (iterator.hasNext()) {
        String exURI = iterator.next();
        if(null != exURI && uri.contains(exURI)){
            return true;
        }
        }
        LoginUser user = ControllerBase.getLoginUser(request);
        if(null != user){
        return true;
        }
        return false;
    }

    private void initRequestThreadLocal(HttpServletRequest request){
        ControllerBase.setRequest(request);
        request.setAttribute("basePath", ControllerBase.basePathLessSlash(request));
    }
    private void removeRequestThreadLocal(){
        ControllerBase.setRequest(null);
    }

    @Override
    public boolean preHandle(HttpServletRequest request,
        HttpServletResponse response, Object handler) throws Exception {
        initRequestThreadLocal(request);
        if (false == validURI(request)) {
        throw new NeedLoginException();
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request,
        HttpServletResponse response, Object handler, ModelAndView modelAndView)
        throws Exception {
        removeRequestThreadLocal();
    }

    @Override
    public void afterCompletion(HttpServletRequest request,
        HttpServletResponse response, Object handler, Exception ex)
        throws Exception {
        removeRequestThreadLocal();
    }
}

In the postHandle and afterCompletion methods, clean up the request object in ThreadLocal.

But in actual use, business developers set a large object (such as a List occupying about 200MB of memory) as the Attributes of the request and pass it to the JSP.

If an exception may occur in the JSP code, SpringMVC's postHandle and afterCompletion methods will not be executed.

Thread scheduling in Tomcat may not be able to schedule the thread that throws the exception, so ThreadLocal always holds the request. As the running time goes by, the available memory is filled up, and the Full GC is being executed all the time, and the system is directly stuck.

Subsequent amendments: Through Filter, clean up ThreadLocal in the finally block.

@WebFilter(value="/*", asyncSupported=true)
public class ClearRequestCacheFilter implements Filter{

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        clearControllerBaseThreadLocal();
        try {
            chain.doFilter(request, response);
        } finally {
            clearControllerBaseThreadLocal();
        }
    }

    private void clearControllerBaseThreadLocal() {
        ControllerBase.setRequest(null);
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}
    @Override
    public void destroy() {}
}

ThreadLocal can be used, but there must be a controlled release measure, usually a try-finally code form.

Explanation: In the Controller of SpringMVC, the request can be injected through @Autowired. The actual injection is an HttpServletRequestWrapper object, and the current request is also called through the ThreadLocal mechanism during execution.

Conventional way: Just receive the request parameter directly in the controller method.
Share:

Monday, November 15, 2021

appscan:CSRF (Cross-site request forgery)

 1.1, attack principle

   CSRF (Cross-site request forgery) cross-site request forgery, also known as "One Click Attack" or Session Riding, usually abbreviated as CSRF or XSRF, is a malicious use of websites. Although it sounds like cross-site scripting (XSS), it is very different from XSS. XSS is caused by the arbitrary execution of input from the browser, while CSRF is caused by over-trusting users and allowing them to come from so-called legitimate users who have passed authentication. An attack carried out by requesting to perform a certain function of the website. Compared with XSS attacks, CSRF attacks are often less popular (so the resources to prevent them are also quite scarce) and difficult to prevent. CSRF is more dangerous than XSS.

1.2, case analysis

Background: A user was attacked by CSRF during normal transfer, and his account balance was stolen

  1) User Bob initiates a transfer request to the bank http://bank.com.cn/transfer?account=bob&amount=1000000&for=bob2, at this time, the server verifies Bob's identity through the verification session, and Bob completes the normal transfer operation

  2) The hacker Lisa also opened an account in the same bank and initiated a transfer request to the bank: http://bank.com.cn/transfer?account=bob&amount=1000000&for=lisa, Lisa identity verification failed, the request failed

3) There is a CSRF vulnerability in this website. Lisa forged a URL or a hyperlink image with the embedded code http://bank.com.cn/transfer?account=bob&amount=1000000&for=lisa, and induced Bob to click on this URL or image At this time, the request will initiate a request from Bob’s browser to the bank with Bob’s cookie attached. Bob has just visited the bank’s website and the Session value has not expired. The browser’s cookie contains Bob’s authentication information

  4) Tragedy happened! The request http://bank.com.cn/transfer?account=bob&amount=1000000&for=lisa sent to the bank server through Bob's browser will be executed, and the money in Bob's account will be transferred to the Lisa account

  5) Traceability and accountability cannot be traced. The bank log shows that there is indeed a legitimate request from Bob himself to transfer funds, and there is no trace of being attacked.

1.3, APPSCAN test process

APPSCAN removes the HTTP headers that may interfere with the CSRF attack, and uses the forged Referer header http://bogus.referer.ibm.com/ to initiate a request to the server. If the application server returns normally, it is judged that the application is vulnerable to cross-site request forgery attacks .

POST /tg/supplier/supplyFreezeSearch.do HTTP/1.1

Content-Type: application/x-www-form-urlencoded

Accept-Language: en-US

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Referer: http://bogus.referer.ibm.com

Host: pxxx-core-xxxx.com.cn

User-Agent: Mozilla/4.0 (compatible; MSIE 9.0; Win32)

ec_i = ec & ec_eti = & ec_ev = & ec_efn = & ec_crd = 15 & ec_f_a = & ec_p = 1 & ec_s_supplyId = & ec_s_supplyName = & ec_s_reason = & ec_s_flagMean = & ec_s_cdate = & ec_s_beginDate = & ec_s_acceName = & __ ec_pages = 2 & ec_rd = 50 & ec_f_supplyId = 1234 & ec_f_supplyName = 1234 & ec_f_reason = 1234 & ec_f_flagMean = 1234 & ec_f_cdate = 1234 & ec_f_beginDate = 1234 & ec_f_acceName = 1234

HTTP/1.1 OK

Date: Mon, 10 Apr 2018 15:17:54 GMT

Location: http://pxxx-core-stg2.paic.com.cn/login

X-Powered-By: Servlet/2.5 JSP/2.1

Set-Cookie: WLS_HTTP_BRIDGE=Ln1YOmot2_3Gzn7sonux8lIOYaSafCnOVQZzmUl8EjaP1lHMMwqP!-1955618416; path=/; HttpOnly

<html><head><title>Welcome to XXX system</title></head>

1.4, defense suggestions

  1) Verify the HTTP Referer field

   According to the HTTP protocol, there is a field in the HTTP header called Referer, which records the source address of the HTTP request. Under normal circumstances, a request to access a secure restricted page comes from the same website. For example, to access http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory, the user must first log in to bank.example and then pass Click the button on the page to trigger the transfer event. At this time, the Referer value of the transfer request will be the URL of the page where the transfer button is located, usually an address beginning with the bank.example domain name. If a hacker wants to implement a CSRF attack on a bank website, he can only construct a request on his own website. When a user sends a request to the bank through the hacker's website, the referer of the request points to the hacker's own website. Therefore, to defend against CSRF attacks, the bank website only needs to verify the Referer value for each transfer request. If it is a domain name starting with bank.example, it means that the request comes from the bank website itself and is legitimate. If the Referer is another website, it may be a CSRF attack by a hacker and reject the request.

2) Add the token to the request address and verify that the CSRF attack is successful because the hacker can completely forge the user’s request. All the user authentication information in the request is in the cookie, so the hacker can do without knowing these verifications. In the case of information, the user’s own cookie is directly used to pass the security verification. To resist CSRF, the key is to include information that hackers cannot forge in the request, and that information does not exist in the cookie. You can add a randomly generated token as a parameter to the HTTP request, and establish an interceptor on the server side to verify the token. If there is no token in the request or the content of the token is incorrect, the request may be rejected because of a CSRF attack. .

3) Customize attributes and verify in the HTTP header. This method also uses tokens and performs verification. The difference from the previous method is that instead of putting the token in the HTTP request as a parameter, it It is placed in a custom attribute in the HTTP header. Through the XMLHttpRequest class, you can add the HTTP header attribute csrftoken to all requests of this type at one time, and put the token value in it. This solves the inconvenience of adding a token to the request in the previous method. At the same time, the address requested through XMLHttpRequest will not be recorded in the browser's address bar, and there is no need to worry about the token being leaked to other websites through the Referer.

  4) Use audited libraries or frameworks that do not allow this weakness, such as: OWASP CSRFGuard: http://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

"ESAPI Session Management" control http://www.owasp.org/index.php/ESAPI

  5) Ensure that there are no XSS vulnerabilities, because XSS usually leads to the theft of user identity information

  6) Do not use the GET method for any request that triggers a state change

1.5, the actual repair plan

By configuring the filter in web.xml to filter the corresponding request, inherit the OncePerRequestFilter.java parent class in the filter class, and then perform the corresponding matching judgment on the request header in the corresponding filter. If it does not match, it is considered to be a kind of The request of CSRF attack will not be executed.

The filter condition (url-pattern) should be configured according to the actual situation, sometimes it is not necessarily the request at the end of .do or .html to report this vulnerability. At this time, other configurations need to be performed according to the actual situation, and /* may be required for globalization Request a match.

   At the same time, the web.xml in the server may be overwritten by the cache file web_merged.xml, causing the configuration newly added to the web.xml to become invalid, resulting in the old configuration in the cache file being executed. This requires attention. Solution: Shut down the server, delete the cache file, and then restart the service.




Share:

appscan: Authentication Bypass Using HTTP Verb Tampering

 1.1, attack principle

Insecure HTTP methods PUT/DELETE/MOVE/COPY/TRACE/PROPFIND/PROPPATCH/MKCOL/LOCK/UNLOCK allow attackers to modify web server files, delete web pages, and even upload web shells to obtain user identity information, etc., they all have Serious security vulnerabilities may be created. Developers need to control HTTP request types to prevent unauthorized tampering of server resources.

1.2, case analysis

  APPSCAN uses the meaningless HTTP verb bogus to initiate a request to the server, and the system returns normally, showing that the system does not restrict the judgment of the http request type, and there is an HTTP verb tampering vulnerability.

BOGUS /fams/admin/j_security_check HTTP/1.1

Accept-Language: en-US

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Referer: http://xxx-core-stg1.paic.com.cn/fams/

Host: xxx-core-stg1.paic.com.cn

User-Agent: Mozilla/4.0 (compatible; MSIE 9.0; Win32)

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Content-Type: text/html;charset=utf-8

Content-Length: 477

Date: Wed, 14 Mar 2018 01:56:23 GMT

1.3, defense recommendations

   1. Restrict http method, such as only allow GET, POST and other types

  2. Use the Filter method provided in the J2EE standard for request type filtering

  3. Check tomcat's web.xml, weblogic.xml configuration of weblogic, and restrict the request type, such as:

<security-constraint>

  <web-resource-collection>

    <url-pattern>/*</url-pattern>

    <http-method>PUT</http-method>

    <http-method>DELETE</http-method>

    <http-method>HEAD</http-method>

    <http-method>OPTIONS</http-method>

    <http-method>TRACE</http-method>

  </web-resource-collection>

  <auth-constraint></auth-constraint>

</security-constraint>

<login-config>

  <auth-method>BASIC</auth-method>

</login-config>

  4. Use the request.getMethod method to add a request interceptor in Struts, such as:

if(method.equalsIgnoreCase("post")||method.equalsIgnoreCase("get")||method.equalsIgnoreCase("head")||method.equalsIgnoreCase("trace")||method.equalsIgnoreCase("connect") ||method.equalsIgnoreCase("options")){}

   5. Disable the WebDAV function of IIS. WebDAV is based on a communication protocol of HTTP 1.1. It adds some methods other than GET, POST, and HEAD to HTTP 1.1, so that applications can directly write files to the Web Server.

  6. ​​The following restrictions are set in the httpd.conf file of apache

<Location />

 <LimitExcept GET POST HEAD CONNECT OPTIONS>

   Order Allow,Deny

   Deny from all

 </LimitExcept>

 </Location>

1.4, the actual repair plan

  1. The server can be divided into two types: Tomcat and WebSphere (WAS). The local is Tomcat, plus the configuration mode of 2 and the mode of 3 is mainly for the WAS server.

  2. Add the <security-constraint> configuration in the web.xml file.

   3. If it is the requested static resource, save the subordinate field as a file .htaccess and place it under the static resource folder.

  <LimitExcept GET POST>

  Order deny,allow

  Deny from all

  </LimitExcept>

  Dynamic resources need to be implemented in java code.

   Refer to the limitexcept command on the official website, IHS is based on apache, and the syntax is the same.

http://httpd.apache.org/docs/2.4/mod/core.html#limitexcept

Share:

appscan:Session identification is not updated (medium-sangered)

 1.1, attack principle

   When authenticating a user or establishing a new user session in other ways, if any existing session identifier is not invalidated, an attacker has the opportunity to steal the authenticated session. This vulnerability can be combined with XSS to obtain the user session to initiate a login process attack on the system.

1.2, APPSCAN test process

  AppScan scans the cookies before and after the "login behavior", which records the session information. After the login behavior occurs, if the value in the cookie does not change, it is judged as a "session ID not updated" vulnerability

1.3, repair suggestions

  1. Always generate a new session for the user to log in when the user is successfully authenticated to prevent the user from manipulating the session ID. Do not accept the session ID provided by the user's browser when logging in; revoke any existing session ID before authorizing the new user session.

  2. For platforms that do not generate new values ​​for session identification cookies (such as ASP), please use auxiliary cookies. In this method, the auxiliary cookie on the user's browser is set to a random value, and the session variable is set to the same value. If the session variable and cookie value never match, cancel the session and force the user to log in again.

  3. If you are using the Apache Shiro security framework, you can use the SecurityUtils.getSubject().logout() method, refer to: http://blog.csdn.net/yycdaizi/article/details/45013397


1.4, fix the code sample

  Add the following code to the login page:


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%

    request.getSession().invalidate();//Clear session

    Cookie cookie = request.getCookies()[0];//Get cookie

    cookie.setMaxAge(0);//Let the cookie expire

%>

  Add the following code before verifying that the login is successful:


try {

    request.getSession().invalidate();

    if (request.getCookies() != null) {

       Cookie cookie = request.getCookies()[0];// Get cookie

       cookie.setMaxAge(0);// Let the cookie expire

    }

} catch (Exception e) {

     e.printStackTrace();

}

session = request.getSession(true);

1.5, exception handling

   The session is indeed updated before and after login, it can be regarded as a false positive

Share:

appscan:encrypted session (SSL) is using a cookie without the "secure" attribute

 1.1, attack principle

Any information such as cookies, session tokens, or user credentials sent to the server in clear text may be stolen and later used for identity theft or user disguise. In addition, several privacy regulations point out that user credentials and other information are sensitive Information must always be sent to the Web site in an encrypted manner.

1.2, repair suggestions

   add secure attribute to cookie

1.3, fix the code example

  1) The server is configured as HTTPS SSL

  2) Servlet 3.0 (Java EE 6) web.xml is configured as follows:

  <session-config>

   <cookie-config>

    <secure>true</secure>

   </cookie-config>

  </session-config>

  3) Configure as follows in ASP.NET Web.config:

   <httpCookies requireSSL="true" />

  4) Configure as follows in php.ini

  Session.cookie_secure = True

  or

  Void session_set_cookie_params (int $lifetime [, string $path [, string $domain

                                  [, bool $secure= false [, bool $httponly= false ]]]])

  or

  Bool setcookie (string $name [, string $value [, int $expire = 0 [, string $path

                 [, string $domain [, bool $secure= false [, bool $httponly= false ]]]]]])

  5) Configure as follows in weblogic:


  <wls:session-descriptor>

      <wls:cookie-secure>true</wls:cookie-secure>

       <wls:cookie-http-only>true</wls:cookie-http-only>

   </wls:session-descriptor>

1.4. Other information

  Https://www.owasp.org/index.php/SecureFlag

1.5, the actual repair plan

  Solution 1: The project uses the WebShpere server, this can be set in the server:

   In fact, this repair method is the same as 5.2 repair suggestion 2) adding configuration to web.xml. Both of these repair methods can definitely be scanned by Appscan, but the 19 environment needs to support both https and http protocols. The above two solutions will cause the cookies under the http protocol to not be transmitted, resulting in the part under the http protocol The function cannot be used. For the time being, this scheme has been scanned at the expense of not using the functions under the http protocol.

  Option II:

   If the cookie is configured with the secure attribute, then the cookie can be transmitted in the https protocol, but not in the http protocol. In the actual system application, two protocols must be supported. Here you can get which protocol is through request.getScheme() (this way https protocol is also http, strange, you can judge whether it is https protocol in the following way)

  String url = req.getHeader("Referer");

  If(url.startsWith("https")){}

  Then judge whether to add this attribute: cookie.setSecure(true).

   With this scheme, you can only set the cookies that your own code responds later, but not the cookies that the container automatically responds to. Therefore it is not used here.

Share:

Sunday, November 14, 2021

fortify scan: cross-site request forgery (CSRF)

Abstract:

Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. With a little help of social engineering (such as sending a link via email or chat), an attacker may trick the users of a web application into executing actions of the attacker’s choosing. If the victim is a normal user, a successful CSRF attack can force the user to perform state changing requests like transferring funds, changing their email address, and so forth. If the victim is an administrative account, CSRF can compromise the entire web application.



Explanation:

A cross-site request forgery (CSRF) vulnerability occurs when:

1. A web application uses session cookies.

2. The application acts on an HTTP request without verifying that the request was made with the user's consent.

A nonce is a cryptographic random value that is sent with a message to prevent replay attacks. If the request does not contain a nonce that proves its provenance, the code that handles the request is vulnerable to a CSRF attack (unless it does not change the state of the application). This means a web application that uses session cookies has to take special precautions in order to ensure that an attacker can't trick users into submitting bogus requests. Imagine a web application that allows administrators to create new accounts as follows:

  var req = new XMLHttpRequest();

  req.open("POST", "/new_user", true);

  body = addToPost(body, new_username);

  body = addToPost(body, new_passwd);

  req.send(body);

An attacker might set up a malicious web site that contains the following code.

  var req = new XMLHttpRequest();

  req.open("POST", "http://www.example.com/new_user", true);

  body = addToPost(body, "attacker");

  body = addToPost(body, "haha");

  req.send(body);

If an administrator for example.com visits the malicious page while she has an active session on the site, she will unwittingly create an account for the attacker. This is a CSRF attack. It is possible because the application does not have a way to determine the provenance of the request. Any request could be a legitimate action chosen by the user or a faked action set up by an attacker. The attacker does not get to see the Web page that the bogus request generates, so the attack technique is only useful for requests that alter the state of the application.

Applications that pass the session identifier in the URL rather than as a cookie do not have CSRF problems because there is no way for the attacker to access the session identifier and include it as part of the bogus request.

Recommendations:

Applications that use session cookies must include some piece of information in every form post that the back-end code can use to validate the provenance of the request. One way to do that is to include a random request identifier or nonce, like this:

  RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, "/new_user");

  body = addToPost(body, new_username);

  body = addToPost(body, new_passwd);

  body = addToPost(body, request_id);

  rb.sendRequest(body, new NewAccountCallback(callback));

Then the back-end logic can validate the request identifier before processing the rest of the form data. When possible, the request identifier should be unique to each server request rather than shared across every request for a particular session. As with session identifiers, the harder it is for an attacker to guess the request identifier, the harder it is to conduct a successful CSRF attack. The token should not be easily guessed and it should be protected in the same way that session tokens are protected, such as using SSLv3.

Additional mitigation techniques include:

Framework protection: Most modern web application frameworks embed CSRF protection and they will automatically include and verify CSRF tokens.

Use a Challenge-Response control: Forcing the customer to respond to a challenge sent by the server is a strong defense against CSRF. Some of the challenges that can be used for this purpose are: CAPTCHAs, password re-authentication and one-time tokens.

Check HTTP Referer/Origin headers: An attacker won't be able to spoof these headers while performing a CSRF attack. This makes these headers a useful method to prevent CSRF attacks.

Double-submit Session Cookie: Sending the session ID Cookie as a hidden form value in addition to the actual session ID Cookie is a good protection against CSRF attacks. The server will check both values and make sure they are identical before processing the rest of the form data. If an attacker submits a form in behalf of a user, he won't be able to modify the session ID cookie value as per the same-origin-policy.

Limit Session Lifetime: When accessing protected resources using a CSRF attack, the attack will only be valid as long as the session ID sent as part of the attack is still valid on the server. Limiting the Session lifetime will reduce the probability of a successful attack.

The techniques described here can be defeated with XSS attacks. Effective CSRF mitigation includes XSS mitigation techniques.

Tips:

1. SCA flags all HTML forms and all XMLHttpRequest objects that might perform a POST operation. The auditor must determine if each form could be valuable to an attacker as a CSRF target and whether or not an appropriate mitigation technique is in place.


Share:

fortify scan: Header Manipulation: Cookies

Abstract:

Including unvalidated data in Cookies can lead to HTTP Response header manipulation and enable cache-poisoning, cross-site scripting, cross-user defacement, page hijacking, cookie manipulation or open redirect.

Explanation:

Cookie Manipulation vulnerabilities occur when:

1. Data enters a web application through an untrusted source, most frequently an HTTP request.

2. The data is included in an HTTP cookie sent to a web user without being validated.

As with many software security vulnerabilities, cookie manipulation is a means to an end, not an end in itself. At its root, the vulnerability is straightforward: an attacker passes malicious data to a vulnerable application, and the application includes the data in an HTTP cookie.

Cookie Manipulation: When combined with attacks like cross-site request forgery, attackers may change, add to, or even overwrite a legitimate user's cookies.

Being an HTTP Response header, Cookie manipulation attacks can also lead to other types of attacks like:

HTTP Response Splitting:

One of the most common Header Manipulation attacks is HTTP Response Splitting. To mount a successful HTTP Response Splitting exploit, the application must allow input that contains CR (carriage return, also given by %0d or \r) and LF (line feed, also given by %0a or \n)characters into the header. These characters not only give attackers control of the remaining headers and body of the response the application intends to send, but also allows them to create additional responses entirely under their control.

Many of today's modern application servers will prevent the injection of malicious characters into HTTP headers. For example, recent versions of Apache Tomcat will throw an IllegalArgumentException if you attempt to set a header with prohibited characters. If your application server prevents setting headers with new line characters, then your application is not vulnerable to HTTP Response Splitting. However, solely filtering for new line characters can leave an application vulnerable to Cookie Manipulation or Open Redirects, so care must still be taken when setting HTTP headers with user input.

Example: The following code segment reads the name of the author of a weblog entry, author, from an HTTP request and sets it in a cookie header of an HTTP response.

author = form.author.value;

...

document.cookie = "author=" + author + ";expires="+cookieExpiration;

...

Assuming a string consisting of standard alphanumeric characters, such as "Jane Smith", is submitted in the request the HTTP response including this cookie might take the following form:

HTTP/1.1 200 OK

...

Set-Cookie: author=Jane Smith

...

However, because the value of the cookie is formed of unvalidated user input the response will only maintain this form if the value submitted for AUTHOR_PARAM does not contain any CR and LF characters. If an attacker submits a malicious string, such as "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n...", then the HTTP response would be split into two responses of the following form:

HTTP/1.1 200 OK

...

Set-Cookie: author=Wiley Hacker


HTTP/1.1 200 OK

...

Clearly, the second response is completely controlled by the attacker and can be constructed with any header and body content desired. The ability of attacker to construct arbitrary HTTP responses permits a variety of resulting attacks, including: cross-user defacement, web and browser cache poisoning, cross-site scripting, and page hijacking.

Cross-User Defacement: An attacker will be able to make a single request to a vulnerable server that will cause the server to create two responses, the second of which may be misinterpreted as a response to a different request, possibly one made by another user sharing the same TCP connection with the server. This can be accomplished by convincing the user to submit the malicious request themselves, or remotely in situations where the attacker and the user share a common TCP connection to the server, such as a shared proxy server. In the best case, an attacker may leverage this ability to convince users that the application has been hacked, causing users to lose confidence in the security of the application. In the worst case, an attacker may provide specially crafted content designed to mimic the behavior of the application but redirect private information, such as account numbers and passwords, back to the attacker.

Cache Poisoning: The impact of a maliciously constructed response can be magnified if it is cached either by a web cache used by multiple users or even the browser cache of a single user. If a response is cached in a shared web cache, such as those commonly found in proxy servers, then all users of that cache will continue receive the malicious content until the cache entry is purged. Similarly, if the response is cached in the browser of an individual user, then that user will continue to receive the malicious content until the cache entry is purged, although only the user of the local browser instance will be affected.

Cross-Site Scripting: Once attackers have control of the responses sent by an application, they have a choice of a variety of malicious content to provide users. Cross-site scripting is common form of attack where malicious JavaScript or other code included in a response is executed in the user's browser. The variety of attacks based on XSS is almost limitless, but they commonly include transmitting private data like cookies or other session information to the attacker, redirecting the victim to web content controlled by the attacker, or performing other malicious operations on the user's machine under the guise of the vulnerable site. The most common and dangerous attack vector against users of a vulnerable application uses JavaScript to transmit session and authentication information back to the attacker who can then take complete control of the victim's account.

Page Hijacking: In addition to using a vulnerable application to send malicious content to a user, the same root vulnerability can also be leveraged to redirect sensitive content generated by the server and intended for the user to the attacker instead. By submitting a request that results in two responses, the intended response from the server and the response generated by the attacker, an attacker may cause an intermediate node, such as a shared proxy server, to misdirect a response generated by the server for the user to the attacker. Because the request made by the attacker generates two responses, the first is interpreted as a response to the attacker's request, while the second remains in limbo. When the user makes a legitimate request through the same TCP connection, the attacker's request is already waiting and is interpreted as a response to the victim's request. The attacker then sends a second request to the server, to which the proxy server responds with the server generated request intended for the victim, thereby compromising any sensitive information in the headers or body of the response intended for the victim.

Open Redirect: Allowing unvalidated input to control the URL used in a redirect can aid phishing attacks.

Recommendations:

The solution to cookie manipulation is to ensure that input validation occurs in the correct places and checks for the correct properties.

Since Header Manipulation vulnerabilities like cookie manipulation occur when an application includes malicious data in its output, one logical approach is to validate data immediately before it leaves the application. However, because web applications often have complex and intricate code for generating responses dynamically, this method is prone to errors of omission (missing validation). An effective way to mitigate this risk is to also perform input validation for Header Manipulation.

Web applications must validate their input to prevent other vulnerabilities, such as SQL injection, so augmenting an application's existing input validation mechanism to include checks for Header Manipulation is generally relatively easy. Despite its value, input validation for Header Manipulation does not take the place of rigorous output validation. An application might accept input through a shared data store or other trusted source, and that data store might accept input from a source that does not perform adequate input validation. Therefore, the application cannot implicitly rely on the safety of this or any other data. This means that the best way to prevent Header Manipulation vulnerabilities is to validate everything that enters the application or leaves the application destined for the user.

The most secure approach to validation for Header Manipulation is to create a whitelist of safe characters that are allowed to appear in HTTP response headers and accept input composed exclusively of characters in the approved set. For example, a valid name might only include alphanumeric characters or an account number might only include digits 0-9.

A more flexible, but less secure approach is known as blacklisting, which selectively rejects or escapes potentially dangerous characters before using the input. To form such a list, you first need to understand the set of characters that hold special meaning in HTTP response headers. Although the CR and LF characters are at the heart of an HTTP response splitting attack, other characters, such as ':' (colon) and '=' (equal), have special meaning in response headers as well.

After you identify the correct points in an application to perform validation for Header Manipulation attacks and what special characters the validation should consider, the next challenge is to identify how your validation handles special characters. The application should reject any input destined to be included in HTTP response headers that contains special characters, particularly CR and LF, as invalid.

Many application servers attempt to limit an application's exposure to HTTP response splitting vulnerabilities by providing implementations for the functions responsible for setting HTTP headers and cookies that perform validation for the characters essential to an HTTP response splitting attack. Do not rely on the server running your application to make it secure. When an application is developed there are no guarantees about what application servers it will run on during its lifetime. As standards and known exploits evolve, there are no guarantees that application servers will also stay in sync.


Share:

fortify scan:JSON Injection

Abstract:

The method writes unvalidated input into JSON. This call could allow an attacker to inject arbitrary elements or attributes into the JSON entity.

Explanation:

JSON injection occurs when:

1. Data enters a program from an untrusted source.

2. The data is written to a JSON stream.

Applications typically use JSON to store data or send messages. When used to store data, JSON is often treated like cached data and may potentially contain sensitive information. When used to send messages, JSON is often used in conjunction with a RESTful service and can be used to transmit sensitive information such as authentication credentials.

The semantics of JSON documents and messages can be altered if an application constructs JSON from unvalidated input. In a relatively benign case, an attacker may be able to insert extraneous elements that cause an application to throw an exception while parsing a JSON document or request. In a more serious case, such as ones that involves JSON injection, an attacker may be able to insert extraneous elements that allow for the predictable manipulation of business critical values within a JSON document or request. In some cases, JSON injection can lead to cross-site scripting or dynamic code evaluation.

Example 1: The following JavaScript code uses jQuery to parse JSON where a value comes from a URL:

var str = document.URL;

var url_check = str.indexOf('name=');

var name = null;

if (url_check > -1) {

  name =  decodeURIComponent(str.substring((url_check+5), str.length));

}

$(document).ready(function(){

  if (name !== null){

    var obj = jQuery.parseJSON('{"role": "user", "name" : "' + name + '"}');

    ...

  }

  ...

});

Here the untrusted data in name will not be validated to escape JSON-related special characters. This allows a user to arbitrarily insert JSON keys, possibly changing the structure of the serialized JSON. In this example, if the non-privileged user mallory were to append ","role":"admin to the name parameter in the URL, the JSON would become:

{

  "role":"user",

  "username":"mallory",

  "role":"admin"

}

This is parsed by jQuery.parseJSON() and set to a plain object, meaning that obj.role would now return "admin" instead of "user"

Recommendations:

When writing user supplied data to JSON, follow these guidelines:

1. Do not create JSON attributes with names that are derived from user input.

2. Ensure that all serialization to JSON is performed using a safe serialization function that delimits untrusted data within single or double quotes and escapes any special characters.

Example 2: The following JavaScript code implements the same functionality as that in Example 1, but instead verifies the name against a whitelist, and rejects the value otherwise setting the name to "guest" prior to parsing the JSON:

var str = document.URL;

var url_check = str.indexOf('name=');

var name = null;

if (url_check > -1) {

  name =  decodeURIComponent(str.substring((url_check+5), str.length));

}

function getName(name){

  var regexp = /^[A-z0-9]+$/;

  var matches = name.match(regexp);

  if (matches == null){

    return "guest";

  } else {

    return name;

  }

}

$(document).ready(function(){

  if (name !== null){

    var obj = jQuery.parseJSON('{"role": "user", "name" : "' + getName(name) + '"}');

    ...

  }

  ...

});

Although in this case it is ok to perform whitelisting in this way, as we want the user to control the name, in other cases it is best to use values that are not user-controlled at all.


Share:

fortify scan: Often Misused: Authentication

Abstract:

An API is a contract between a caller and a callee. The most common forms of API abuse are caused by the caller failing to honor its end of this contract. ... For example, if a coder subclasses SecureRandom and returns a non-random value, the contract is violated.

Explanation:

Many DNS servers are susceptible to spoofing attacks, so you should assume that your software will someday run in an environment with a compromised DNS server. If attackers are allowed to make DNS updates (sometimes called DNS cache poisoning), they can route your network traffic through their machines or make it appear as if their IP addresses are part of your domain. Do not base the security of your system on DNS names.

Example 1: The following code uses a DNS lookup to determine whether or not an inbound request is from a trusted host. If an attacker can poison the DNS cache, they can gain trusted status.

 struct hostent *hp;

 struct in_addr myaddr;

 char* tHost = "trustme.trusty.com";

 myaddr.s_addr=inet_addr(ip_addr_string);

 hp = gethostbyaddr((char *) &myaddr,

      sizeof(struct in_addr), AF_INET);

 if (hp && !strncmp(hp->h_name, tHost, sizeof(tHost))) {

 trusted = true;

 } else {

 trusted = false;

 }

IP addresses are more reliable than DNS names, but they can also be spoofed. Attackers may easily forge the source IP address of the packets they send, but response packets will return to the forged IP address. To see the response packets, the attacker has to sniff the traffic between the victim machine and the forged IP address. In order to accomplish the required sniffing, attackers typically attempt to locate themselves on the same subnet as the victim machine. Attackers may be able to circumvent this requirement by using source routing, but source routing is disabled across much of the Internet today. In summary, IP address verification can be a useful part of an authentication scheme, but it should not be the single factor required for authentication.

Recommendations:

You can increase confidence in a domain name lookup if you check to make sure that the host's forward and backward DNS entries match. Attackers will not be able to spoof both the forward and the reverse DNS entries without controlling the nameservers for the target domain. However, this is not a foolproof approach: attackers may be able to convince the domain registrar to turn over the domain to a malicious nameserver. Basing authentication on DNS entries is simply a risky practice.

While no authentication mechanism is foolproof, there are better alternatives than host-based authentication. Password systems offer decent security, but are susceptible to bad password choices, insecure password transmission, and bad password management. A cryptographic scheme like SSL is worth considering, but such schemes are often so complex that they bring with them the risk of significant implementation errors, and key material can always be stolen. In many situations, multi-factor authentication including a physical token offers the most security available at a reasonable price.

Tips:

1. Check how the DNS information is being used. In addition to considering whether or not the program's authentication mechanisms can be defeated, consider how DNS spoofing can be used in a social engineering attack. For example, if attackers can make it appear that a posting came from an internal machine, can they gain credibility?

Share:

Search This Blog

Weekly Pageviews

Translate

Blog Archive