18分钟阅读

ChangeLog:OWASP十大项目

HRVOJE是一名软件工程师,使用PHP,Python,JavaScript,SQL和HTML等语言的5年以上的经验。

网页应用程序在过去十年中爆发了复杂性。它们已经从简单的容器中发展,以便接触表格和民意调查进入全吹的应用程序。我们可以将它们与尺寸和性能进行尺寸和性能进行比较。复杂性和越来越多的特色应用程序陡峭地增长,它已成为投资大量时间和关注尽可能安全地进行关注的必需品。互联网用户的大规模崛起使其更重要的是解决保护数据和应用程序用户的问题。有一个巨大的威胁试图蠕动,并对所涉及的每个人带来严重的头痛。

2001年,一个新的组织进入了舞台。其目标是打击影响网站和应用程序的安全问题。它被适当命名为Open Web应用程序安全项目(OWASP)。如今,它发表资源,组织会议,并提出了关于Web和应用程序安全的标准。 Web应用程序安全的事实上标准是OWASP十大项目。它列出了十个最普遍的安全威胁。决定进入的因素是广泛的数据和社区反馈。 2017年底,项目更新。对于许多现代Web应用程序至关重要的几个新问题,而有些问题已从列表中逃脱。

本文为原始列表提供了补充,并说明了列表的最新更改。它描述了威胁,试图提供清晰的例子,以便更容易理解,并提出抗击安全威胁的方式。

从OWASP前10名列表中删除的问题

在2017年更新之前,2013年的列表是最近的。考虑到Web应用程序现在建立和消耗的方式的更改,执行全面修订只有意义。微服务正在采取他们的馅饼,新的酷炫和闪亮的框架正在取代香草代码战斗齿轮。这些事实意味着在被删除之前列出的一些威胁以及一些新的威胁占据了他们的位置。

我们将确保刷新本文中长期忘记的问题的记忆,并介绍了新的坏狼。学习历史是唯一确定不重复同样错误的方式。

跨站点请求伪造

跨站点请求伪造(CSRF)是最近项目迭代中的“输家”之一。它消失了,因为许多现代的网络框架包括CSRF防御机制。将申请暴露于威胁的可能性随着速度迅速减少。

无论CSRF退出列表,刷新我们的内存仍然很好。让我们确保它不会比以往更强大。

从本质上讲,CSRF是一种感觉烟雾炸弹的漏洞。攻击者欺骗毫无戒心的用户来在Web应用程序中执行不需要的请求或动作。简单地说,攻击者迫使受害者向第三方申请发送请求,受害者不知道被派遣的请求。该请求可以是HTTP GET请求来检索资源,甚至更差,一个HTTP POST请求更改受害者控制下的资源。在袭击过程中,受害者认为一切都很好,最常见的是甚至没有注意到背景发生的事情。在空气清除后,损坏已经完成或缺少某些东西,没有人知道发生了什么。

在目标应用程序中成功的先前用户身份验证是启动陷阱的原因。用户在攻击签名到应用程序之前有某个点。该应用程序将受害者发送了一个饼干来记住它们。一旦Web浏览器发送恶意请求,Cookie就会自动发送,以及任何潜在的有效载荷,并且应用程序不对象向其本来知道的用户服务请求。

One of the most famous examples is tricking a user to transfer money from their account to the one an attacker controls. A user signs into an e-banking system to check their account balance. After that, they visit an online forum to check the reviews of a new mobile phone. An attacker, fishing with dynamite, posts a review including an image with a seemingly broken image hyperlink. Instead of a real hyperlink, the attacker uses a hyperlink which the e-banking system internally uses to transfer money from account A to account B: //payments.dummybank.com?receiver=attacker&amount=100. The banking system makes the authenticated user the sender and the value from the “receiver” parameter the receiver of the funds. Of course, the attacker specifies their offshore account as the receiver.

由于浏览器在渲染页面时自动加载图像,因此请求发生在后台。如果银行的支付系统使用HTTP GET请求实现货币转移,则无法阻止灾难发生。请注意,该示例很简单,最可能通过HTTP GET处理传输。但是,攻击者只有稍微困难,可以在论坛的HTML消息发布表单中更改属性“动作”。然后,浏览器将请求发送到银行的付款系统,而不是论坛的后端。

偷钱只是那里的众多例子中的一个。更改用户的电子邮件地址或取消预期的购买也属于此类别。由于它经常发生,社会工程和一些技术知识是针对软件工程错误的有效杠杆。

在设计系统时,请记住以下内容:

  • 不要 使用HTTP获取请求进行修改资源的封装操作。您应该只使用这些请求来检索信息。请记住,拇指的规则是让GET请求IDEMPOTENT。
  • 如果在内部使用HTTP POST请求传输数据时,倾向于将数据以JSON,XML或某些其他格式发送到以外的参数作为查询字符串。使用非平凡的数据格式会降低创建假HTML表单的人的危险,这将将数据发送到您的服务。
  • 确保创建并包含唯一和不可预测的令牌进入您的HTML表单。这些令牌对每个请求也应该是唯一的。检查这些令牌的存在和正确性将降低发生的威胁风险。要找出令牌并在其假请求中使用它,攻击者需要访问您的系统并直接从那里拍摄令牌。由于令牌只是一次性,因此他们无法在恶意代码中重新使用它们。

当与跨站点脚本(XSS)耦合时,此漏洞甚至更糟糕的效果。如果攻击者可以将恶意代码注入最喜欢的网站或应用程序,则攻击的范围变得更加重要和危险。如果可能的攻击,攻击者可以根据XSS攻击规避针对CSRF的一些保护机制。

请记住,CSRF没有消失,它并不像以前那样普遍。

CSRF在动作中的图 - 从OWASP前10名取出

未经alvateated重定向和转发

在完成动作后,将用户重定向或向前转发到相同的另一部分,甚至是其他应用程序的许多应用程序。例如,成功登录应用程序触发到主页或用户最初访问的页面的重定向。通常,目的地是表单操作或链接地址的一部分。如果处理重定向或转发的组件不确保目的地地址确实是由应用程序生成的目标,则会产生潜在的威胁。这是一种被称为“未经验证的重定向和转发”的安全漏洞。

未经alvated重定向和转发将被视为危险的两个主要原因是网络钓鱼和凭证劫持。攻击者可以设法更改重定向/转发目标位置,并将用户发送给恶意应用程序,几乎无法从原始信息中无法区分。毫无戒心的用户将其凭证和机密信息透露给恶意第三方。在他们意识到发生了什么之前,已经太晚了。

作为示例,Web应用程序通常使用支持对上一个访问页面的重定向来实现登录。为了能够轻松地执行此操作,HTML表单的操作属性可能看起来像 http://myapp.example.com/signin?url=http://myapp.example.com/puppies。你是一个巨大的小狗的崇拜者,所以安装浏览器扩展是有意义的,用你最喜欢的小狗的缩略图替换网站favicons。不幸的是,这是一只狗吃狗的世界。浏览器扩展的作者决定兑现无条件的爱,并介绍另外一个“功能”。每次访问您喜欢的Puppy扇区站点时,它会替换表单的操作属性中的“URL”参数,并将其链接到自己的网站。由于网站完全相同,当您提供信用卡详细信息购买小狗扑克牌时,您实际上是融资恶意攻击者,而不是您的爱好。

解决漏洞涉及通过确保它是预期的一个来检查目的地位置。如果框架或库进行完整的重定向或前进逻辑,则有利于检查实施并在必要时更新代码。否则,您需要手动检查以防止攻击。

您可以进行几种类型的检查。为获得最佳保护,请使用几种方法的组合,而不是只用其中一个粘贴。

  • 验证传出URL,确保它指向您控制的域。
  • 而不是使用显式地址,在前端编码它们,然后在后端解码并验证它们。
  • 准备一个值得信赖的URL的白名单。允许仅转发和重定向到白名单位置。更喜欢这种方法来维护黑名单。黑名单通常只在发生错误时填充新物品。白名单是更严格的。
  • 采用LinkedIn和其他一些应用程序使用的方法:将您的用户展示了一个页面,要求他们确认重定向/向前,使其清除它们正在留下您的应用程序。

合并问题

列表中的大多数问题可以被标记为实施中的缺陷,原因是由于缺乏知识或不充分的深入调查潜在的威胁。这两种原因都可以归因于缺乏经验,并在将来考虑它们的解决方案很容易 - 只是确保学习更多并更彻底。一种特别棘手的依赖性依赖于危险(但非常人性化)特征的组合,其制造太多假设,其难以开发和维护复杂的计算机系统。适合此类别的漏洞是“破碎的访问控制”。

破碎的访问控制

对于应用程序的某些部分,漏洞是由不充分的,或完全缺乏,授权和访问控制造成的。在OWASP前十个项目的先前迭代中,有两个问题:不安全的直接对象引用和缺少函数级访问控制。他们现在被合并为他们的相似性。

直接对象参考

直接对象引用通常用于URL以识别正在操作的资源。例如,当用户登录时,它们可以通过单击包含其配置文件标识符的链接来访问其配置文件。如果将该相同的标识符存储在数据库中并用于检索配置文件信息,并且应用程序假定人们只能通过登录页面访问配置文件页面,更改URL中的简档标识符暴露另一用户的配置文件信息。

设置删除配置文件表单的URL的应用程序 http://myapp.example.com/users/15/delete 明确表示应用程序中至少有14个其他用户。在这种情况下,如何进入其他用户的删除形式而不是火箭科学。

解决此问题的解决方案是为每个资源执行授权检查,而不假设只能拍摄某些部分以获取应用程序的某些部分。此外,删除直接引用并使用间接引用是另一个前进的,因为恶意用户难以弄清楚如何创建引用。

在开发期间,作为预防措施,写下简单的状态机图。让各个国家在您的应用程序中表示不同的页面,并转换用户可以采取的操作。这使得列出需要特别注意的所有转换和页面更容易。

状态机图的例证

缺少函数级访问控制

缺少的函数级访问控制非常类似于不安全的直接对象引用。在这种情况下,用户修改URL或其他参数以尝试访问应用程序的受保护部分。如果没有适当的访问控制检查访问级别,则用户可以获得对应用程序资源的特权访问或至少一些对其存在的知识。

从示例借用直接对象引用,如果应用程序假定访问删除表单的用户是超级用户,因为超级用户可以看到删除表单的链接,而不进行任何进一步授权,则会打开一个巨大的安全漏洞。计算某些UI元素的可用性不是正确的访问控制。

通过始终确保在应用程序的所有层中执行检查,解决问题。前端界面可能不是恶意用户可以访问域图层的唯一方式。此外,不要依赖于从用户传递的信息有关他们的访问级别。执行适当的会话控制,始终仔细检查接收的数据。仅仅因为请求正文说用户是一个管理员,它并不是真正的意思。

断开的访问控制现在结合了与访问控制不足相关的所有问题,如应用程序级别或系统级别,如文件系统的错误配置。

断开访问控制图

OWASP前10名列表中的新问题

新的前端框架和采用新软件开发实践的出现将安全问题转移到完全新的主题。新技术也设法解决了我们之前手动处理的一些常见问题。因此,对清单进行修改并相应地调整到现代趋势,它变得有益。

XML外部实体

XML标准提供了一个名为外部实体的鲜为人知的想法,该想法是文档数据类型定义(DTD)的一部分。它允许文档作者指定与外部实体的链接指定,然后可以在主文档中引用并包含在主文档中。一个非常简单的例子是:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
  <!ELEMENT foo ANY>
  <!ENTITY bar "baz">
]>
<foo>
  &bar;
</foo>

During the parsing, a reference &bar; is replaced with the content from the defined entity, thus yielding <foo>baz</foo>.

如果应用程序要采取外部输入并将其包含,如果没有任何检查,直接进入XML文档定义,则可以实现广泛的数据泄漏和攻击。

神奇的事情是实体不一定是一个简单的字符串 - 它可以是对文件系统上文件的引用。 XML解析器将很乐意占用指定文件的内容,并将其包含到生成的响应中,可能会显示敏感系统信息。如OWASP所示,通过定义实体,可以很容易地获取系统用户的信息

<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>

An especially troublesome “feature” of this vulnerability is the possibility to easily execute a denial-of-service attack. One easy way to do it would be to list contents of an endless file like /dev/random. The other one is to create a sequence of entities, each referencing the previous one many times. This turns the final reference into a root of a potentially very wide and deep tree whose parsing could exhaust system memory. This attack is even known as Billion Laughs. As shown on Wikipedia, a series of dummy entities are defined, producing an opportunity for an attacker to include one billion lols in the final document.

<?xml version="1.0"?>
<!DOCTYPE lolz [
 <!ENTITY lol "lol">
 <!ELEMENT lolz (#PCDATA)>
 <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
 <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
 <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
 <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
 <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
 <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
 <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
 <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
 <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

可以使用更复杂的数据格式来完成防止XML外部实体利用。 JSON是一个很好的替代品,提供了一些预防措施,也是由于可能的攻击而采取了一些预防措施。更新XML库是必不可少的,耦合禁用外部实体处理和DTD。一如既往,验证和消毒在使用它之前或在文档中包含它之前来自不受信任的来源的数据。

不安全的反序列化

在编写代码时,开发人员有权控制他们正在使用的代码编写的系统。控制第三方系统只写一点甚至没有代码的三方系统的行为有多令人敬畏?由于人们并不完美,图书馆有缺陷,这绝对可能。

应用状态和配置通常是序列化和存储的。如果序列化数据紧密耦合到当前用户,有时浏览器用作存储引擎。试图成为聪明和保存处理时间的应用程序可以使用cookie标记用户已登录的。由于只能在登录后才成功创建cookie,因此存储饼干中的用户名是有意义的。然后基于cookie的存在和内容进行身份验证和授权用户。如果人们没有意识,那就没有什么可能出错。说实话,他们也不好奇。

如果好奇的用户在他们的机器上找到了一个cookie,他们可以看到这样的东西:

{"username": "joe.doe", "expires": "2018-06-01 10:28:16"}

A perfectly valid Python dictionary serialized to JSON, nothing special about it. The ever-curious user might change the expiration date to keep the application from forcing the sign-out. An even more curious user might try to modify the username to "jane.doe". If this username existed, it would open a whole new world for the unsuspecting user who now has access to private data.

将数据序列化为JSON并保持一切透明的简单示例远非可能发生在您身上的最糟糕的事情。如果攻击者达到修改某些序列化数据,则它们可能能够以迫使系统执行任意代码的方式修改它。

假设您正在构建一个REST API,允许人们在Python中编写自己的机器学习模型,并将其上传到您的服务。该服务将评估上传的模型并使用数据集培训它们。这允许人们使用您的计算资源和大量可用数据集,以便快速且简易模型建设。

该服务无法以纯文本格式存储代码。用户 泡菜 他们的代码,使用他们的私钥加密它,并将其发送到API进行培训。当服务需要运行模型时,它会解密代码,解密它,并运行它。棘手的部分是泡菜协议是不安全的。代码可以以允许在反序列化期间执行任意恶意代码的方式构造。

Python’s pickle protocol allows classes to define a method __reduce__, which returns information on how to deserialize a custom object. One of the supported return values is a tuple of two arguments: a callable and a tuple of arguments to be passed to the callable. Taking into account that your ML model training system aims to provide maximum flexibility of code structure, it’s possible to write the following code:

class Algo(object):
 def run(self):
   pass
 def __reduce__(self):
   import itertools
   return (list, (itertools.count(1), ))

Once the object needs to be deserialized (unpickled), a function list is called with only one argument. The function list is a list constructor in Python, and the function itertools.count produces an infinite iterator of values, starting with the passed parameter. Turning an infinite iterator into a finite list can have disastrous consequences to your system’s performance and stability.

这种类型漏洞的唯一真实治疗正在选择不将来自外部源的数据进行反序列化。如果这是不可能的,建议使用校验和或数字签名来防止由恶意用户潜在修改的数据的反序列化。此外,尝试设置从主系统解耦的沙箱环境,以限制可能出现的问题的影响。

当使用外部库进行反序列化数据时,例如来自XML或JSON,请尝试选择允许您在执行实际解序过程中进行对象类型检查的那些。这可能会捕获意外的对象类型,其唯一目的是损害您的系统。

与应用程序执行的所有其他操作一样,强制执行广泛的日志记录和监控。反序列化经常发生或失败超过正常情况是发出错误的信号。早期赶上问题。

记录和监控不足

您花了多少时间来确保您记录应用程序中发生的所有警告和错误?您是否只存储在代码中发生的错误或您还会记录验证错误吗?当您的域名的业务规则没有满足时会发生什么?未能持保留申请中的所有错误和可疑活动都具有安全性和数据妥协。

想象一下以下情景。您的应用程序包含登录页面,最多。该表格有两个字段,一个字段用于输入电子邮件,另一个用于密码。如果用户尝试登录并提供错误的密码,则可以重试。不幸的是,不正确的尝试不当的数量不受限制,因此在N不成功的尝试后,登录页面将不会被锁定。攻击者可以利用这个机会,并且给定一个正确的电子邮件,继续从彩虹桌进入密码,直到一个组合终于成功。如果您的应用程序足够安全,并且在将密码进入数据库之前,您可以散列密码,此特定攻击将无法正常工作。但是,您是否有识别入侵的机制?

仅仅因为这一个尝试未能破解打开你的登录页面,它并不意味着其他人不会。登录页面可能不是您拥有的唯一潜在的后门。如果不是别的东西,有人可能会尝试使用破碎的访问控制。即使是完美制作的应用程序也应该知道有人试图攻击它们,即使可能是不可能的。但总是它。

要尽力保护自己免受此类攻击,请执行以下步骤:

  • 记录应用程序中发生的所有失败和警告,都是在代码或访问控制,验证和数据操作错误中抛出的异常。必须复制存储的所有信息并持续到足够长的时间,以便可以进行回顾性检查和分析。
  • 确定格式和持久性层很重要。具有任意文本格式的巨大文件易于完成;稍后处理它不是。选择一个存储选项,使其易于存储和读取数据和一种格式,可以轻松且快速地(de)序列化。将JSON存储在数据库中,该数据库启用快速访问缓解使用情况。通过定期备份数据库。
  • 如果您正在处理重要和有价值的数据,请遵循可以遵循的行动跟踪,以审核最终状态。实现防止数据篡改的机制。
  • 有后台系统分析日志并提醒您,如果出现。检查 - 如果用户反复尝试访问应用程序的受保护部分,则视为测试。但是,不要用虚拟检查过载系统。监控系统必须作为单独的服务运行,不得影响主系统的性能。

解决问题时,请特别注意不要将错误日志泄漏到外部用户。未能这样做让您容易受到敏感信息曝光。伐木和监控应该有助于你解决问题,而不是更有效地完成工作的攻击者。

伐木和监控图

下一步

了解Web应用程序中的潜在威胁和漏洞很重要。开始在应用程序中识别它们并应用修补程序删除它们是更重要的。

注意应用程序安全是软件开发项目所有步骤的重要组成部分。软件架构师,开发人员和测试人员必须将软件测试程序纳入其工作流程。利用安全检查表和自动测试是有益的,进入软件开发过程的适当步骤,以降低安全风险。

您是否正在分析现有申请或开发新的新申请,您应该调查 OWASP应用安全验证标准项目 (ASVS)。该项目的目标是为应用程序安全验证制定标准。标准枚举开发安全Web应用程序的测试和要求。将测试分配一到三个,其中一个意味着危险量最少,三种意味着最高的潜在威胁。分类允许应用程序管理员决定哪种威胁更有可能和重要。没有必要在每个应用程序中包含每个测试。

新的和现有的Web应用程序项目,特别是那些遵循敏捷原则的项目,从而受益于确保其申请的努力的结构化规划。如果您决定使用,OWASP ASVS测试的规划更容易 OWASP安全知识框架。它是管理安全测试导向的Sprint的应用程序,具有一组关于如何解决常见安全问题的示例,以及基于OWASP ASV的易于遵循的清单。

如果您刚刚开始探索Web应用程序安全性并需要一个安全的沙箱游乐场,请使用OWASP的Web应用程序实现 - 网页Goat.。它是一个有意地不安全地实现Web应用程序。应用程序通过课程指导您,每个课程都集中在一个安全威胁。

在应用程序开发期间,请确保您:

  • 确定和确定威胁。 定义哪些威胁可以逼真地发生并对您的应用程序构成风险。优先考虑威胁并决定哪些应该得到最大的发展和测试努力。如果您服务于静态博客,则不有很多努力解决了很多努力。
  • 评估应用程序的架构和设计。 在应用程序开发的后期阶段,一些漏洞非常难以解决。例如,如果您打算执行第三方代码,并且没有使用沙箱环境的计划,则非常困难地防止不安全的反序列化和注入攻击。
  • 更新软件开发过程。 对Web应用程序威胁的测试必须尽可能多地成为自动化过程。通过试图找到安全漏洞的自动化测试,增加您的CI / CD工作流是有益的。您甚至可以利用现有的单元测试系统来开发安全测试并定期运行它们。
  • 学习和改进。 问题和漏洞列表并不静态,绝对不限于十或十五威胁。新功能和想法打开了新型攻击的门。重要的是要阅读Web应用程序安全世界中的当前趋势,以保持当前。应用你的学习;否则,你正在浪费你的时间。

结论

即使是名称表明,OWASP十大项目只列出了十个安全漏洞,有数千名可能的陷阱和后门威胁您的应用程序,最重要的是,您的用户及其数据。确保在景点上响起,不断刷新您的知识,因为技术改变和改进都有upsides和缺点。

哦,别忘了,世界不是黑白。安全漏洞并不孤单;他们经常交织在一起。暴露于一个人通常意味着一束其他人在角落周围,等待他们的丑陋头部和某个时候,即使不是你的错,也是如此 系统安全开发人员,你仍然意味着修补漏洞来遏制网络犯罪。例如,看到 黑客信用卡号码仍然是谷歌.

理解基础知识

OWASP代表什么?

首字母缩略词OWASP代表开放式Web应用程序安全项目。它是一个在线社区,产生处理Web应用程序安全性的学习资源和工具。

什么是OWASP前10名?

OWASP前十名是安全专家生产的最常见的Web应用程序安全威胁列表,将社区反馈考虑在内。

什么是CSRF攻击?

跨站点请求伪造是一种攻击,使用户对其进行身份验证的应用程序进行不期望的请求。

什么是未经验证的重定向和转发?

未经验证的重定向和转发是一种安全漏洞,允许攻击者将用户重定向到不安全的Web应用程序,通过注入攻击获得受保护的应用程序资源或窃取特权用户信息。

什么是注射攻击?

注射攻击是一种攻击类型,允许攻击者将不需要的代码注入应用程序。基于应用程序,有几种类型的攻击,最常见的是SQL注入和跨站点脚本。

什么是反序列化?

反序列化是将字节流转换为加载到存储器中的代码的过程。原始字节流由序列化过程进行相反的过程。

什么是攻击矢量?

攻击载体代表一种利用应用程序中的安全漏洞的方法。注入对银行API资源的请求的无效HTML IMG元素是CSRF攻击中使用的攻击矢量的示例。

XML中的一个实体是什么?

XML实体是用于将别名定义到XML文档或文档类型定义(DTD)中使用的项目的别名。

什么是外部实体?

外部实体是一种XML实体制作类型,文档作者可以轻松地使用统一的资源标识符(URI)将外部资源包含到其文档中。

什么是OWASP WebGoat?

OWASP WebGoAT是一个故意不安全的Web应用程序的实现,它是用于教授Web应用程序安全课程的学习机制。