mirror of
https://github.com/openappsec/openappsec.git
synced 2025-06-28 16:41:02 +03:00
184 lines
6.1 KiB
C++
184 lines
6.1 KiB
C++
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
|
|
// Licensed under the Apache License, Version 2.0 (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.
|
|
|
|
#pragma once
|
|
#include "debug.h"
|
|
#include <cereal/types/string.hpp>
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <iostream>
|
|
|
|
USE_DEBUG_FLAG(D_WAAP_ULIMITS);
|
|
|
|
namespace Waap {
|
|
namespace UserLimits {
|
|
|
|
typedef unsigned long long ull;
|
|
#define DEFAULT_URL_MAX_SIZE 32*1024
|
|
#define DEFAULT_HEADER_MAX_SIZE 100*1024
|
|
#define DEFAULT_BODY_MAX_SIZE_KB 1000000
|
|
#define DEFAULT_BODY_MAX_SIZE 1000000*1024
|
|
#define DEFAULT_OBJECT_MAX_DEPTH 40
|
|
|
|
// @file Feature behaviour description:
|
|
// Phase 1:
|
|
// 1. No enforcement. No logs to mgmt.
|
|
// 2. Only logs to automation and dev Kibana.
|
|
// 3. Logs should represent the state as if the limits are enforced as described in phase 2.
|
|
// Phase 2:
|
|
// 1. DISABLE mode: no enforcement and no logs.
|
|
// 2. LEARNING mode: requests that violated a limit will be accepted, and won't be scanned any further.
|
|
// Illegal methods won't be automatically accepted, and will be further scanned.
|
|
// 3. PREVENT mode: requests that violated a limit will be dropped, and won't be scanned any further.
|
|
class Policy {
|
|
struct Config {
|
|
Config() :
|
|
urlMaxSize(DEFAULT_URL_MAX_SIZE),
|
|
httpHeaderMaxSize(DEFAULT_HEADER_MAX_SIZE),
|
|
httpBodyMaxSizeKb(DEFAULT_BODY_MAX_SIZE_KB),
|
|
httpBodyMaxSize(DEFAULT_BODY_MAX_SIZE),
|
|
maxObjectDepth(DEFAULT_OBJECT_MAX_DEPTH),
|
|
httpIllegalMethodsAllowed(false) {}
|
|
~Config() {}
|
|
|
|
template <typename _A>
|
|
void serialize(_A& ar) {
|
|
ar(cereal::make_nvp("urlMaxSize", urlMaxSize));
|
|
ar(cereal::make_nvp("httpHeaderMaxSize", httpHeaderMaxSize));
|
|
httpBodyMaxSizeKb = 0;
|
|
ar(cereal::make_nvp("httpRequestBodyMaxSize", httpBodyMaxSizeKb));
|
|
// Kilobytes to bytes conversion
|
|
httpBodyMaxSize = httpBodyMaxSizeKb * 1024;
|
|
ar(cereal::make_nvp("jsonMaxObjectDepth", maxObjectDepth));
|
|
int intToBool = 0;
|
|
ar(cereal::make_nvp("httpIllegalMethodsAllowed", intToBool));
|
|
httpIllegalMethodsAllowed = (intToBool == 1);
|
|
}
|
|
|
|
bool operator==(const Policy::Config& other) const;
|
|
|
|
size_t urlMaxSize; // URL max size in bytes
|
|
size_t httpHeaderMaxSize; // Header Size in Bytes
|
|
size_t httpBodyMaxSizeKb; // Body Size in Kilobytes
|
|
ull httpBodyMaxSize; // Body Size in Bytes
|
|
size_t maxObjectDepth; // Can range from 0 to 1024
|
|
// List of legal methods can be viewed in isLegalHttpMethod function
|
|
bool httpIllegalMethodsAllowed;
|
|
};
|
|
public:
|
|
template <typename _A>
|
|
explicit Policy(_A& ar)
|
|
{
|
|
ar(cereal::make_nvp("practiceAdvancedConfig", m_config));
|
|
}
|
|
Policy() : m_config() {}
|
|
~Policy() {}
|
|
|
|
bool operator==(const Policy& other) const;
|
|
size_t getUrlMaxSize() const { return m_config.urlMaxSize; }
|
|
size_t getMaxObjectDepth() const { return m_config.maxObjectDepth; }
|
|
size_t getHttpHeaderMaxSize() const { return m_config.httpHeaderMaxSize; }
|
|
size_t getHttpBodyMaxSizeKb() const { return m_config.httpBodyMaxSizeKb; }
|
|
ull getHttpBodyMaxSize() const { return m_config.httpBodyMaxSize; }
|
|
bool isHttpIllegalMethodAllowed() const { return m_config.httpIllegalMethodsAllowed; }
|
|
const Config& getConfig() const { return m_config; }
|
|
|
|
private:
|
|
Config m_config;
|
|
|
|
friend std::ostream& operator<<(std::ostream& os, const Policy& policy);
|
|
};
|
|
|
|
struct ViolatedStrData
|
|
{
|
|
std::string type;
|
|
std::string policy;
|
|
std::string assetId;
|
|
};
|
|
|
|
class State {
|
|
public:
|
|
enum class StateType
|
|
{
|
|
NO_STATE,
|
|
URL,
|
|
METHOD,
|
|
HEADER,
|
|
BODY,
|
|
DEPTH
|
|
};
|
|
|
|
enum class ViolationType
|
|
{
|
|
NO_LIMIT,
|
|
ILLEGAL_METHOD,
|
|
URL_LIMIT,
|
|
URL_OVERFLOW,
|
|
HEADER_LIMIT,
|
|
HEADER_OVERFLOW,
|
|
BODY_LIMIT,
|
|
BODY_OVERFLOW,
|
|
OBJECT_DEPTH_LIMIT
|
|
};
|
|
public:
|
|
explicit State(const Policy& policy) :
|
|
m_policy(policy),
|
|
m_urlSize(0),
|
|
m_httpHeaderSize(0),
|
|
m_httpBodySize(0),
|
|
m_objectDepth(0),
|
|
m_currState(StateType::NO_STATE),
|
|
m_type(ViolationType::NO_LIMIT),
|
|
m_strData()
|
|
{
|
|
m_strData.type = "no violation";
|
|
}
|
|
~State() {}
|
|
|
|
void setAssetId(const std::string& assetId) { m_strData.assetId = assetId; }
|
|
// @return true if limit is reached or overflows
|
|
bool addUrlBytes(size_t size);
|
|
bool addHeaderBytes(const std::string& name, const std::string& value);
|
|
bool addBodyBytes(size_t chunkSize);
|
|
// @return true if limit is reached
|
|
bool setObjectDepth(size_t depth);
|
|
bool isValidHttpMethod(const std::string& method);
|
|
bool isLimitReached() const;
|
|
bool isIllegalMethodViolation() const;
|
|
const std::string getViolatedTypeStr() const { return m_strData.type; }
|
|
const ViolatedStrData& getViolatedStrData() const { return m_strData; }
|
|
size_t getViolatingSize() const;
|
|
|
|
private:
|
|
bool isLegalHttpMethod(const std::string& method) const;
|
|
void setCurrStateType(StateType type) { m_currState = type; }
|
|
StateType getCurrStateType() { return m_currState; }
|
|
void setViolationType(ViolationType type);
|
|
void setViolatedTypeStr();
|
|
void setViolatedPolicyStr();
|
|
const std::string& getAssetId() const { return m_strData.assetId; }
|
|
|
|
private:
|
|
const Policy& m_policy;
|
|
size_t m_urlSize;
|
|
size_t m_httpHeaderSize;
|
|
ull m_httpBodySize;
|
|
size_t m_objectDepth;
|
|
StateType m_currState; // State that is currently being enforced
|
|
ViolationType m_type; // Type of violation reached
|
|
ViolatedStrData m_strData; // Holds the string info of the violated data
|
|
};
|
|
|
|
}
|
|
}
|