/*
 * Copyright 2017-2018 Baidu Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.baidu.openrasp.hook.server.weblogic;

import com.baidu.openrasp.HookHandler;
import com.baidu.openrasp.cloud.model.ErrorType;
import com.baidu.openrasp.cloud.utils.CloudUtils;
import com.baidu.openrasp.hook.server.ServerXssHook;
import com.baidu.openrasp.plugin.checker.CheckParameter;
import com.baidu.openrasp.tool.Reflection;
import com.baidu.openrasp.tool.annotation.HookAnnotation;
import com.baidu.openrasp.tool.model.ApplicationModel;
import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.NotFoundException;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;

/**
 * @description: weblogic的xss检测hook点
 * @author: anyang
 * @create: 2018/09/05 15:06
 */
@HookAnnotation
public class WeblogicXssHook extends ServerXssHook {
    @Override
    public boolean isClassMatched(String className) {
        return "weblogic/servlet/internal/CharsetChunkOutput".equals(className);
    }

    @Override
    protected void hookMethod(CtClass ctClass) throws IOException, CannotCompileException, NotFoundException {
        String src = getInvokeStaticSrc(WeblogicXssHook.class, "getWeblogicOutputBuffer", "$0", Object.class);
        insertBefore(ctClass, "flush", "()V", src);
    }

    public static void getWeblogicOutputBuffer(Object object) {
        if (HookHandler.isEnableXssHook()){
            HookHandler.disableBodyXssHook();
            HashMap<String, Object> params = new HashMap<String, Object>();
            try {
                ByteBuffer byteBuffer = (ByteBuffer) Reflection.getField(object, "buf");
                if (byteBuffer != null) {
                    String content = new String(byteBuffer.array());
                    params.put("html_body", content);
                }
            } catch (Exception e) {
                String message = ApplicationModel.getServerName() + " xss detectde failed";
                int errorCode = ErrorType.HOOK_ERROR.getCode();
                HookHandler.LOGGER.warn(CloudUtils.getExceptionObject(message, errorCode), e);
            }
            if (HookHandler.requestCache.get() != null && !params.isEmpty()) {
                HookHandler.doCheck(CheckParameter.Type.XSS_USERINPUT, params);
            }
        }
    }
}

@@ -895,51 +895,8 @@
 er;%0A
-import com.baidu.openrasp.tool.Reflection;%0A
 impo
@@ -1152,20 +1152,20 @@
 ava.nio.
-Byte
+Char
 Buffer;%0A
@@ -1730,18 +1730,22 @@
 , %22$
-0%22, Object
+1%22, CharBuffer
 .cla
@@ -1784,18 +1784,39 @@
 s, %22
-flush%22, %22(
+write%22, %22(Ljava/nio/CharBuffer;
 )V%22,
@@ -1880,21 +1880,25 @@
 fer(
-Object object
+CharBuffer buffer
 ) %7B%0A
@@ -1939,16 +1939,17 @@
 sHook())
+ 
 %7B%0A      
@@ -2086,97 +2086,8 @@
 y %7B%0A
-                ByteBuffer byteBuffer = (ByteBuffer) Reflection.getField(object, %22buf%22);%0A
     
@@ -2103,20 +2103,16 @@
    if (b
-yteB
 uffer !=
@@ -2161,37 +2161,24 @@
 t = 
-new String(byteBuffer.array()
+buffer.toString(
 );%0A 

modify weblogic