Question

Depuis un BSTR n'est qu'un typedef pour wchar_t* notre base de code comporte plusieurs (beaucoup ?) endroits où les chaînes littérales sont transmises à une méthode attendant un BSTR cela peut gâcher les commissaires ou quiconque essaie d'utiliser n'importe quel BSTR méthode spécifique (par ex. SysStringLen).

Existe-t-il un moyen de détecter statiquement ce type d'utilisation abusive ?

J'ai essayé de compiler avec VC10 /Wall et avec analyse de code statique Microsoft Toutes les règles mais le morceau de code incriminé suivant n'est signalé par aucun d'eux.

void foo(BSTR str)  
{
    std::cout << SysStringLen(str) << std::endl; 
}

int _tmain()
{
    foo(L"Don't do that");
}

Mise à jour: Après avoir tenté de vandaliser wtypes.h à détecter ce genre de transgressions que j'ai abandonnées.

J'ai essayé deux chemins, sur lesquels j'ai pu travailler avec mon exemple de programme ci-dessus, mais une fois que j'ai essayé un vrai projet, ils ont échoué.

  1. créer une classe nommée BSTR mais depuis un VARIANT a un BSTR en tant que membre du syndicat, la nouvelle classe ne pouvait pas avoir de constructeurs ou d'opérateurs d'affectation, cela cassait partout. NULL a été traité comme un BSTR.j'ai essayé de remplacer NULL avec un type qui a des opérateurs de conversion mais après avoir ajouté des dizaines de nouveaux opérateurs (comparaison, conversion etc.) j'ai commencé à rencontrer des appels ambigus et j'ai abandonné.
  2. J'ai ensuite essayé la méthode suggérée par @CashCow et @Hans (en faisant BSTR un typedef vers un autre type de pointeur).Cela n'a pas fonctionné non plus, après avoir ajouté toBSTR et fromBSTR méthodes et détritus comutil.h (_bstr_t) et d'autres endroits avec des conversions, je suis finalement arrivé au point où le compilateur s'est étouffé avec les en-têtes produits à partir d'IDL (les valeurs par défaut sont traduites en chaînes littérales larges).

En bref, j'ai renoncé à essayer d'y parvenir par moi-même, si quelqu'un connaît un outil d'analyse de code qui peut m'aider, je serais très heureux d'en entendre parler.

Était-ce utile?

La solution

Je crois Couverture prétend détecter ce type de vulnérabilités.Je me souviens qu'ils avaient mentionné spécifiquement des éléments COM lors d'une démonstration auprès d'une entreprise pour laquelle je travaillais.

Leur Fiche de données semble certainement impliquer qu'ils vérifient les classes d'utilisation inappropriée de BSTR.Ils ont une période de démonstration ;vous pouvez l'essayer et voir s'il signale votre exemple d'entrée.

Autres conseils

Pouvez-vous modifier vos méthodes pour prendre _bstr_t ou CComBSTR à la place ?

Sinon, en tant que littéral, il s'agit techniquement d'un const wchar_t *, s'il existe un paramètre du compilateur pour ne pas autoriser la conversion de pointeur littéral-> non const, vous pouvez le faire.

A défaut, il existe une possibilité de modifier la définition de BSTR pour qu'il soit unsigned short*.Ensuite, si vous construisez toutes vos sources, vous obtiendrez des erreurs de compilation partout où un littéral est transmis et vous pourrez corriger tout ce code.Ensuite, je suggérerais de le changer à nouveau...

Vous pouvez essayer de compiler avec Clang, son analyse statique/dynamique peut trouver ce que vous recherchez.

Surchargez toutes les fonctions avec le BSTR et transmettez-les avec la conversion appropriée.

void foo( BSTR str )
{
    std::cout << SysStringLen(str) << std::endl; 
}

void foo( const WCHAR *str )
{
    foo( SysAllocString( str ));
}

int _tmain()
{
    foo( L"don't do this" );
    return 0;
}

Ou, pour générer des erreurs du compilateur, modifiez tous les types de paramètres de BSTR par autre chose et recherchez les erreurs :

typedef UINT bar;

void foo( bar _str )
{
    // make the compiler happy below
    BSTR str = (BSTR)_str;
    std::cout << SysStringLen(str) << std::endl;
}

int _tmain()
{
    foo( L"don't do this" );
    foo( (bar)42 );
    return 0;
}

erreur C2664 :'foo' :impossible de convertir le paramètre 1 de 'const wchar_t [14]' en 'bar'

Je suppose que l'erreur C2664 et le type 'const wchar_t[]' identifiés par le compilateur sont ce que vous voulez que le compilateur trouve pour chaque appel interne effectué à la fonction à l'aide du BSTR ?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top