将SQL存储过程和参数存储在数据库表中是不好的做法

时间:2012-11-06 08:54:24

标签: c# sql

我们有一个用例,发送电子邮件的应用程序在电子邮件中找到特定字符串(“智能标记”),并将其替换为存储过程的结果。

例如,电子邮件可能在正文中有Dear <ST:Name>,然后代码会识别此字符串,运行存储过程以查找传递客户端ID作为参数的客户端名称。

这些标记的列表和需要运行的存储过程目前是硬编码的,因此每次需要添加新的“智能标记”时,都需要进行代码更改和部署。

我们的BA是我们熟练的SQL,希望能够手动添加新标签。

将过程和参数存储在数据库表中是不好的做法?这是一个适合这种桌子的设计吗?是否有必要存储参数类型?

SmartTag

SmartTagId   SmartTag   StoredProcedure

SmartTagParameters

SmartTagParameterId   SmartTagId   ParameterName

3 个答案:

答案 0 :(得分:3)

表驱动配置,数据驱动编程,很好。

首先要注意的是SQL注入风险(或者在你的情况下,它将被称为'标记注入'...):可以使用电子邮件作为攻击媒介,通过插入精心设计的程序来获得提升的权限这将在更高的特权下运行。请注意,这不仅仅是针对SQL注入的常见问题,因为您已经接受了要执行的任意代码。这更像是sandboxing问题。

典型的问题来自类型系统:参数有各种类型,但声明表有一个字符串类型。 SQL_VARIANT可以提供帮助。

另一个潜在的问题是声明和发现标签的语言。很快您会被要求识别<tag:foo>,但仅在<tag:bar>之前。一个完全成熟的上下文敏感解析器通常在第一次迭代后不久跟随...如果您可以通过利用已经熟悉的东西(例如,思考JQuery如何使用CSS选择器语法)来提供帮助将会很有帮助。 HTMLAgilityPack可能对你有所帮助(顺便说一句,这是一个完美的SQLCLR任务,不要试图在T-SQL中构建精心设计的状态解析器......)。

答案 1 :(得分:1)

这不是一种不好的做法,你所做的一切都很好。只要您的admin / BA可以添加和更改参数并更改配置,您就不必担心注入。如果用户可以添加和更改参数,您需要检查输入并将某些字符列入白名单。

不仅需要检查sql注入,还要跨站点脚本和dom注入以及跨站点请求伪造。合并的文本显示在用户计算机上,因此在查看合并结果时必须保护他。

答案 2 :(得分:0)

有趣的问题,将跟进,因为它有事可做with mine。一点也不差。事实上,我们正在使用相同的方法。我正试图在我的XSL编辑器上实现类似的目标。我正在使用XML标签,存储过程和VB.Net逻辑的组合来进行替换。

我正在使用表与所有使用的XML标记(它们在应用程序的其他位置使用)和执行所有脏工作的存储过程的组合。一组sp从带有标签的文本转换为用户可读文本。其他一组过程从XML标记表创建XML树,以便用户可以选择编辑其文本。

SQL注入对我们来说不是问题,因为我们使用这些过程来创建电子邮件,而不是从外部源解析它们。

关于其中一个问题的评论,我们也直接从SSMS管理标签,没有管理窗口来管理它们,至少目前如此。但我们计划添加一个简单的管理窗口来管理标签,以便在部署应用程序后更容易添加/删除/修改它们。