Skip to content

BChecks V1‐Beta grammar definition

Albert-PortSwigger edited this page Oct 10, 2023 · 5 revisions

`//Diamond brackets denote lexical states //'=> ' denotes a transition to a lexical state //'<=' denotes a transition to a previous lexical state //Strings are matched using Java regex //Token and grammar rules are matched with their order in this file as precedence //"IGNORED" tokens are matched by the lexer but are ignored in the grammar rules

//Lexer rules

//<Default, ActiveCheck, InsertionPointCheck, PassiveCheck, RequestNaming, WithinVariableRef>: IGNORED ::= " " | "\n" | "\t" | "\r" | "\f" | "#[^\r|\n]*[\n|\r|\r\n]"

// METADATA_HEADER ::= "metadata" NAME_HEADER ::= "name" DESCRIPTION_HEADER ::= "description" LANGUAGE_HEADER ::= "language" LANGUAGE_LEVEL_1 ::= "v1-beta" AUTHOR_HEADER ::= "author" TAGS_HEADER ::= "tags" GIVEN_HEADER ::= "given" HOST_FREQ ::= "host" // => REQUEST_FREQ ::= "request" // => RESPONSE_FREQ ::= "response" // => INSERTION_POINT_FREQ ::= "insertion point" // => ANY ::= "any" HEADER ::= "header" QUERY ::= "query" COOKIE ::= "cookie" DEFINE_HEADER ::= "define" RUN_FOR_EACH_HEADER ::= "run for each" EQUALS ::= "="

//<Default, ActiveCheck, InsertionPointCheck, PassiveCheck, WithinVariableRef> INTERPOLATABLE_STRING_OPENING_QUOTE ::= "`" // => LITERAL_STRING_OPENING_QUOTE ::= """ // => OPEN_BRACKET ::= "(" CLOSE_BRACKET ::= ")" NATURAL_NUMBER ::= (DIGIT)?(DIGIT)?(DIGIT)?(DIGIT)?(DIGIT)?(DIGIT)?DIGIT LETTER_OR_UNDERSCORE ::= "[_|a-z|A-Z]" DIGIT ::= "[0-9]" COMMA ::= ","

// INTERPOLATABLE_STRING_CLOSING_QUOTE ::= "" // <= INTERPOLATABLE_STRING_LITERAL ::= "\\.|[^|{|\]"

// LITERAL_STRING_CLOSING_QUOTE ::= """ // <= LITERAL_STRING ::= "\"|[^"]"

//<Default, ActiveCheck, InsertionPointCheck, PassiveCheck, WithinInterpolatableString, WithinVariableRef> VARIABLE_START ::= "{" // =>

// VARIABLE_END ::= "}" // <= GENERATE_COLLABORATOR_ADDRESS_FUNCTION ::= "generate_collaborator_address" RANDOM_STR_FUNCTION ::= "random_str" TO_LOWER_FUNCTION ::= "to_lower" TO_UPPER_FUNCTION ::= "to_upper" REGEX_REPLACE_FUNCTION ::= "regex_replace" BASE64_ENCODE_FUNCTION ::= "base64_encode" BASE64_DECODE_FUNCTION ::= "base64_decode" SHA1_FUNCTION ::= "sha1" SHA256_FUNCTION ::= "sha256" MD5_FUNCTION ::= "md5" REQUEST_OBJECT ::= "request" RESPONSE_OBJECT ::= "response" REQUEST_RESPONSE_COMMON_PROPERTY ::= "http_version" | "headers" | "body" REQUEST_SPECIFIC_PROPERTY ::= "method" RESPONSE_SPECIFIC_PROPERTY ::= "status_code" URL ::= "url" URL_PROPERTY ::= "protocol" | "host" | "port" | "path" | "file" | "query"

// <ActiveCheck, InsertionPointCheck, PassiveCheck> REPORT_ISSUE_HEADER ::= "report issue" SEVERITY_HEADER ::= "severity" HIGH_SEVERITY ::= "high" MEDIUM_SEVERITY ::= "medium" LOW_SEVERITY ::= "low" INFO_SEVERITY ::= "info" CONFIDENCE_HEADER ::= "confidence" CERTAIN_CONFIDENCE ::= "certain" FIRM_CONFIDENCE ::= "firm" TENTATIVE_CONFIDENCE ::= "tentative" REMEDIATION_HEADER ::= "remediation" DETAIL_HEADER ::= "detail" IF_HEADER ::= "if" ELSE_HEADER ::= "else" IF_FOOTER ::= "end if" IN_KEY ::= "in" IS_KEY ::= "is" MATCHES_KEY ::= "matches" DIFFERS_FROM_KEY ::= "differs from"

// <Default, ActiveCheck, InsertionPointCheck> BODY ::= "body"

// <ActiveCheck, InsertionPointCheck> SEND ::= "send" REQUEST_HEADER ::= "request" CALLED ::= "called" // => METHOD ::= "method" PATH ::= "path" QUERIES ::= "queries" APPENDING ::= "appending" REMOVING ::= "removing" REPLACING ::= "replacing" HEADERS ::= "headers" ANY_KEY ::= "any" DNS_KEY ::= "dns" HTTP_KEY ::= "http" SMTP_KEY ::= "smtp" INTERACTIONS_KEY ::= "interactions"

// PAYLOAD_HEADER ::= "payload"

// <Default, ActiveCheck, PassiveCheck, InsertionPointCheck> BOOL_AND ::= "and" BOOL_OR ::= "or" BOOL_NOT ::= "not" COLON ::= ":" THEN ::= "then"

//<Default, WithinVariableRef> VARIABLE_NAME ::= LETTER_OR_UNDERSCORE (LETTER_OR_UNDERSCORE|DIGIT)*

// REQUEST_NAME ::= LETTER_OR_UNDERSCORE (LETTER_OR_UNDERSCORE|DIGIT)* // <=

//<Default, ActiveCheck, InsertionPointCheck, PassiveCheck, WithinVariableRef> DOT ::= "."

//<Default, ActiveCheck, InsertionPointCheck, PassiveCheck, RequestNaming, WithinInterpolatableString, WithinLiteralString, WithinVariableRef> UNKNOWN ::= "." UNKNOWN_STRING ::= LETTER_OR_UNDERSCORE (LETTER_OR_UNDERSCORE|DIGIT)*

//Parser rules

Start ::= Metadata ScanCheck EOF

Metadata ::= METADATA_HEADER COLON MetadataBlock

MetadataBlock ::= LanguageLevelField NameField (MetadataField)*

LanguageLevelField ::= LANGUAGE_HEADER COLON LANGUAGE_LEVEL_1

NameField ::= NAME_HEADER COLON RawStringLit

MetadataField ::= (AuthorField | TagsField | DescriptionField)

AuthorField ::= AUTHOR_HEADER COLON RawStringArray

TagsField ::= TAGS_HEADER COLON RawStringArray

DescriptionField ::= DESCRIPTION_HEADER COLON RawStringLit

ScanCheck ::= ((DefineBlock (RunForEachBlock)?) | (RunForEachBlock (DefineBlock)?))? GivenBlock

GivenBlock ::= GIVEN_HEADER Frequency THEN (Exp)+

Frequency ::= (HOST_FREQ | REQUEST_FREQ | RESPONSE_FREQ | ((InsertionPointModes(BOOL_OR InsertionPointModes)*)? INSERTION_POINT_FREQ))

InsertionPointModes ::= (ANY | QUERY | HEADER | BODY | COOKIE)

Exp ::= (ControlFlow | BCheckAction)+

DefineBlock ::= DEFINE_HEADER COLON (NonIterableVariableDeclaration)+

RunForEachBlock ::= RUN_FOR_EACH_HEADER COLON (IterableVariableDeclaration)+

NonIterableVariableDeclaration ::= VARIABLE_NAME EQUALS (NonIterableVariableValue | VariableReference)

IterableVariableDeclaration ::= VARIABLE_NAME EQUALS IterableVariableValue

ReportIssue ::= REPORT_ISSUE_HEADER COLON ((IssueSeverityField IssueConfidenceField) | (IssueConfidenceField IssueSeverityField)) ((IssueRemediationField (IssueDetailField)?) | (IssueDetailField (IssueRemediationField)?))?

IssueSeverityField ::= SEVERITY_HEADER COLON SeverityEnum

IssueConfidenceField ::= CONFIDENCE_HEADER COLON ConfidenceEnum

IssueRemediationField ::= REMEDIATION_HEADER COLON (StringLit | VariableReference)

IssueDetailField ::= DETAIL_HEADER COLON (StringLit | VariableReference)

SeverityEnum ::= (INFO_SEVERITY | LOW_SEVERITY | MEDIUM_SEVERITY | HIGH_SEVERITY)

ConfidenceEnum ::= (CERTAIN_CONFIDENCE | FIRM_CONFIDENCE | TENTATIVE_CONFIDENCE)

ControlFlow ::= IfBlock IF_FOOTER

IfBlock ::= IF_HEADER BooleanCondition THEN Exp (ElseBlock)?

ElseBlock ::= ELSE_HEADER (IfBlock | THEN Exp)

BooleanCondition ::= BooleanExpression (BooleanOperand BooleanCondition)?

BooleanExpression ::= (((BooleanFunction)? OPEN_BRACKET BooleanCondition CLOSE_BRACKET) | BooleanAtom)

BooleanAtom ::= ((Value (Comparison Value) | (RegexComparison RegexStringLit)) | Boolean)

Boolean ::= HasInteractions

HasInteractions ::= InteractionsEnum

InteractionsEnum ::= (((ANY_KEY)? INTERACTIONS_KEY) | (DNS_KEY INTERACTIONS_KEY) | (HTTP_KEY INTERACTIONS_KEY) | (SMTP_KEY INTERACTIONS_KEY))

Value ::= (VariableReference | StringLit)

Comparison ::= (IS_KEY | IN_KEY | DIFFERS_FROM_KEY)

RegexComparison ::= MATCHES_KEY

Function ::= (GenerateCollaboratorAddress | RandomStr | ToLower | ToUpper | Base64Encode | Base64Decode | RegexReplace | SHA1 | SHA256 | MD5)

GenerateCollaboratorAddress ::= GENERATE_COLLABORATOR_ADDRESS_FUNCTION OPEN_BRACKET CLOSE_BRACKET

RandomStr ::= RANDOM_STR_FUNCTION OPEN_BRACKET NATURAL_NUMBER CLOSE_BRACKET

ToLower ::= TO_LOWER_FUNCTION OPEN_BRACKET (VariableComponent | VariableReference | StringLit) CLOSE_BRACKET

ToUpper ::= TO_UPPER_FUNCTION OPEN_BRACKET (VariableComponent | VariableReference | StringLit) CLOSE_BRACKET

RegexReplace ::= REGEX_REPLACE_FUNCTION OPEN_BRACKET (VariableComponent | VariableReference | StringLit) COMMA RegexStringLit COMMA (VariableComponent | VariableReference | StringLit) CLOSE_BRACKET

Base64Encode ::= BASE64_ENCODE_FUNCTION OPEN_BRACKET (VariableComponent | VariableReference | StringLit) CLOSE_BRACKET

Base64Decode ::= BASE64_DECODE_FUNCTION OPEN_BRACKET (VariableComponent | VariableReference | StringLit) CLOSE_BRACKET

SHA1 ::= SHA1_FUNCTION OPEN_BRACKET (VariableComponent | VariableReference | StringLit) CLOSE_BRACKET

SHA256 ::= SHA256_FUNCTION OPEN_BRACKET (VariableComponent | VariableReference | StringLit) CLOSE_BRACKET

MD5 ::= MD5_FUNCTION OPEN_BRACKET (VariableComponent | VariableReference | StringLit) CLOSE_BRACKET

BCheckAction ::= (ReportIssue | (SEND NamedOperation))

NamedOperation ::= (SendRequest | SendPayload)

SendRequest ::= REQUEST_HEADER (CALLED REQUEST_NAME)? COLON (StringLit | (RequestModifier)*)

SendPayload ::= PAYLOAD_HEADER (CALLED REQUEST_NAME)? COLON PayloadModifier

PayloadModifier ::= (AppendingPayloadModifier | ReplacingPayloadModifier)

AppendingPayloadModifier ::= APPENDING COLON (StringLit | VariableReference)

ReplacingPayloadModifier ::= REPLACING COLON (StringLit | VariableReference)

RequestModifier ::= (RemoveModifier | AppendModifier | ReplaceModifier)

RemoveModifier ::= REMOVING (BODY | METHOD | PATH | ((HEADERS | QUERIES) KeyModificationValues))

AppendModifier ::= APPENDING (((BODY | METHOD | PATH) ModificationValue) | (QUERIES KeyModificationValues) | (HEADERS KeyValuePairModificationValues))

ReplaceModifier ::= (REPLACING)? (((BODY | METHOD | PATH) ModificationValue) | (QUERIES KeyModificationValues) | (HEADERS KeyValuePairModificationValues))

ModificationValue ::= COLON (StringLit | VariableReference)

KeyModificationValues ::= COLON (StringLit | VariableReference) (COMMA (StringLit | VariableReference))*

KeyValuePairModificationValues ::= COLON KeyValuePair (COMMA KeyValuePair)*

KeyValuePair ::= (StringLit | VariableReference) COLON (StringLit | VariableReference)

IterableVariableValue ::= Array

NonIterableVariableValue ::= StringLit

RawStringArray ::= RawStringLit (((INTERPOLATABLE_STRING_OPENING_QUOTE | LITERAL_STRING_OPENING_QUOTE) | (COMMA RawStringLit ((INTERPOLATABLE_STRING_OPENING_QUOTE | LITERAL_STRING_OPENING_QUOTE))))

Array ::= (StringLit | VariableReference) (((StringLit | VariableReference)) | ((COMMA (StringLit | VariableReference) ((StringLit | VariableReference)))))

StringLit ::= (InterpolatableString | RawStr)

RawStringLit ::= RawStr

RegexStringLit ::= RawStr

InterpolatableString ::= INTERPOLATABLE_STRING_OPENING_QUOTE (((INTERPOLATABLE_STRING_LITERAL | VariableReference | UNKNOWN)+ INTERPOLATABLE_STRING_CLOSING_QUOTE) | INTERPOLATABLE_STRING_CLOSING_QUOTE)

RawStr ::= LITERAL_STRING_OPENING_QUOTE (((LITERAL_STRING)+ LITERAL_STRING_CLOSING_QUOTE) | LITERAL_STRING_CLOSING_QUOTE)

VariableReference ::= VARIABLE_START VariableComponent VARIABLE_END

VariableComponent ::= (Function | VariableObject)

VariableObject ::= VARIABLE_NAME (DOT ((REQUEST_OBJECT (DOT VariableRequestProperty)?) | (RESPONSE_OBJECT (DOT VariableResponseProperty)?)))?

VariableRequestProperty ::= (REQUEST_SPECIFIC_PROPERTY | REQUEST_RESPONSE_COMMON_PROPERTY | VariableUrlProperty)

VariableResponseProperty ::= (RESPONSE_SPECIFIC_PROPERTY | REQUEST_RESPONSE_COMMON_PROPERTY | VariableUrlProperty)

VariableUrlProperty ::= URL (DOT URL_PROPERTY)?

BooleanFunction ::= BOOL_NOT

BooleanOperand ::= (BOOL_AND | BOOL_OR) `

Clone this wiki locally