È sicuro usare flex e bison come un parser di protocollo?

1

Ho iniziato a scrivere un semplice lexer e parser di protocollo per STOMP usando flex e bison. Qualcuno sa di problemi di sicurezza che potrebbero derivare da questo?

Modifica: codice aggiunto.

%{
 /* Tokenizer for the STOMP 1.2 protocol. */
%}

%%
 /* Client commands. */
"SEND"                          return T_CLIENT_SEND;
"SUBSCRIBE"                     return T_CLIENT_SUBSCRIBE;
"UNSUBSCRIBE"                   return T_CLIENT_UNSUBSCRIBE;
"BEGIN"                         return T_CLIENT_BEGIN;
"COMMIT"                        return T_CLIENT_COMMIT;
"ABORT"                         return T_CLIENT_ABORT;
"ACK"                           return T_CLIENT_ACK;
"NACK"                          return T_CLIENT_NACK;
"DISCONNECT"                    return T_CLIENT_DISCONNECT;
"CONNECT"                       return T_CLIENT_CONNECT;
"STOMP"                         return T_CLIENT_STOMP;

 /* Server Commands. */
"CONNECTED"                     return T_SERVER_CONNECTED;
"MESSAGE"                       return T_SERVER_MESSAGE;
"RECEIPT"                       return T_SERVER_RECEIPT;
"ERROR"                         return T_SERVER_ERROR;

 /* Other tokens */
\x00                            return T_NULL;
\x0A                            return T_LF;
\x0D                            return T_CR;
[\x0D]?\x0A                     return T_EOL;
:                               return T_COLON;
[0-255]                         return T_OCTET;
 /* (T_OCTET - (T_LF + T_CR + T_COLON)) */
[\x00-\x09\x0B-\x0C\x0E-\xFF]   return T_SPECIAL;

%%
%{
 /* Parser for the STOMP 1.2 protocol. */
 #include <stdio.h>
 #include "../client_protocol_stomp.h"

 extern stomp_node_t stomp_frame_root;

 void yyerror(const char *str) {
     fprintf(stderr,"error: %s\n",str);
 }

 int yywrap() {
     return 1;
 }

 int yylex(void);
%}

%defines
%error-verbose

/* Tokens for header file generation. */
%token T_CLIENT_SEND T_CLIENT_SUBSCRIBE T_CLIENT_UNSUBSCRIBE T_CLIENT_BEGIN
%token T_CLIENT_COMMIT T_CLIENT_ABORT T_CLIENT_ACK T_CLIENT_NACK
%token T_CLIENT_DISCONNECT T_CLIENT_CONNECT T_CLIENT_STOMP T_SERVER_CONNECTED
%token T_SERVER_MESSAGE T_SERVER_RECEIPT T_SERVER_ERROR T_NULL T_LF T_CR T_EOL
%token T_COLON T_OCTET T_SPECIAL

%union {
    stomp_node_t node;
}

/* Map tokens and non-terminals to fiels in the yylval union. */
/* %type <node> factor term exp */

%%
expression     : frame { /* stomp_frame_root = $1; */ }
               ;

frame          : frame_command
                 frame_command
                 T_EOL
                 frame_octet
                 T_NULL
                 frame_eol
               ;

frame_command  : command T_EOL
               ;

frame_header   : header T_EOL
               | header T_EOL frame_header
               ;

frame_octet    : T_OCTET
               | T_OCTET frame_octet
               ;

frame_eol      : T_EOL
               | T_EOL frame_eol
               ;

command        : client_command 
               | server_command
               ;

client_command : T_CLIENT_SEND
               | T_CLIENT_SUBSCRIBE
               | T_CLIENT_UNSUBSCRIBE
               | T_CLIENT_BEGIN
               | T_CLIENT_COMMIT
               | T_CLIENT_ABORT
               | T_CLIENT_ACK
               | T_CLIENT_NACK
               | T_CLIENT_DISCONNECT
               | T_CLIENT_CONNECT
               | T_CLIENT_STOMP
               ;

server_command : T_SERVER_CONNECTED
               | T_SERVER_MESSAGE
               | T_SERVER_RECEIPT
               | T_SERVER_ERROR
               ;

header         : header_name T_COLON header_value
               ;

header_name    : T_SPECIAL
               ;

header_value   : header_name
               | header_name header_value
               ;
%%
    
posta Jon Bringhurst 08.02.2013 - 17:20
fonte

1 risposta

5

Bison e flex sono strumenti ragionevoli per scrivere parser per protocolli che si adattano a una grammatica LALR (1); ma sono solo strumenti come, ad esempio, un compilatore C. Sta ancora a te non fare nulla di sbagliato in loro. Del resto, bison e flex significano che stai per implementare il tuo codice con C o C ++, lingue che sono conosciute per essere difficili da gestire correttamente e inclini a scatenare falle nella sicurezza, specialmente a causa di problemi di aliasing del puntatore, gestione manuale della memoria, mancanza di strutture di gestione delle stringhe di caratteri decenti e limiti di array non controllati. Questi sono problemi C, non problemi bisonti, ma li otterrete comunque.

L'analisi

LALR (1) può essere un po 'confusa perché tendi a ottenere regole "ridotte" su una base da destra a sinistra. Quando scrivi il codice allegato alle clausole grammaticali, questo può rendere le cose difficili (devi gestire le foglie dell'albero della sintassi è un modo per lo più privo di contesto).

Il bello del flex e del bisonte è che sono sistematici: implementeranno tutti i casi angolari della grammatica. Questa è una grande proprietà per la sicurezza (la maggior parte dei codici sicuri riguarda la copertura di tutti i casi possibili senza dimenticarli)

    
risposta data 08.02.2013 - 18:38
fonte

Leggi altre domande sui tag