目前大部分应用都会包括:服务端逻辑、客户端逻辑、数据存储、数据传输以及API等组件。同时,使用的每种语言、框架和环境都会使应用程序面临一组独特的漏洞。为了保证这些组件的安全,往往需要我们不懈努力,在第一时间发现应用漏洞,进而构建一个具有高安全态势的应用。值得庆幸的是,大多数应用程序漏洞的根本原因即使不相同也很相似。研究这些常见类型的漏洞及其背后的原因,将有助于我们妥善保护我们的应用程序。下面,我将向您介绍影响Angular和React应用程序的六个最常见的漏洞,以及如何发现和预防它们:身份验证绕过不适当的访问控制打开重定向跨站点请求伪造(CSRF)模板注入站点脚本包含(XSSI)身份验证绕过身份验证是指在执行敏感操作或访问敏感数据之前验证身份的合法性。未能在应用程序上正确实施身份验证可能允许攻击者利用此错误配置来访问他们不应访问的服务和功能。例如,Angular通常使用AppRoutingModule进行路由。在将用户定向到应用程序中的敏感路由之前,您应该检查用户是否已通过身份验证并获得访问资源的授权。请参考以下代码片段:@NgModule({imports:[RouterModule.forRoot([//这些路径对所有用户可用。{path:'',component:HomeComponent},{path:'features',component:FeaturesComponent},{path:'login',component:LoginComponent},//这些路由只有用户登录后才能使用{path:'feed',component:FeedComponent,canActivate:[AuthGuard]},{path:'profile',component:ProfileComponent,canActivate:[AuthGuard]},//这是路由无法识别时的fall-through组件{path:'**',component:PageNotFoundComponent}])],exports:[RouterModule]})exportclassAppRoutingModule{}糟糕的访问控制攻击者会找到绕过访问控制实施不当的应用程序的方法。访问控制不仅仅包括身份验证。也就是说,除了证明用户的身份(即“你是谁?”)之外,我们还需要通过应用授予相应的权限(即“你能做什么?”)。只有双管齐下,才能共同保证用户不会访问超出权限的服务和功能。目前,我们有多种配置用户授权的方式,包括:基于角色的访问控制、基于所有权的访问控制和访问控制列表。开发人员常犯的一个错误是在客户端执行授权检查。这是不安全的,因为攻击者可以操纵和覆盖客户端的检查。如您所见,必须使用服务器端代码执行此类授权检查。请参考如下代码段:exportclassAdministratorGuardimplementsCanActivate{constructor(privateauthService:AuthService,privaterouter:Router){}canActivate(next:ActivatedRouteSnapshot,state:RouterStateSnapshot):Observable{//检查此用户是否是管理员。returnthis.authService.isAdmin().pipe(map(isAdmin=>{if(!isAdmin){returnthis.router.parseUrl('/')}returnisAdmin}))}}exportclassAuthService{构造函数(私有http:HttpClient){}//用户当前是否登录。loggedIn:boolean|null=null//包含用户名称和角色的用户对象对象。将设置用户:User|null=null//检查当前用户是否为管理员。isAdmin():Observable{returnthis.getCurrentUser().pipe(map(user=>{returnuser!=null&&user.role==='admin'}))}//获取来自本地状态或服务器的用户定义(如果这是我们第一次检查)。getCurrentUser():Observable<用户|null>{if(this.loggedIn!==null){returnof(this.user)}returnthis.http.get('/api/auth',{responseType:'json'}).pipe(tap({next:user=>{//如果我们从服务器获取用户定义,则表明该用户已登录。this.user=userthis.loggedIn=true},error:error=>{//A401来自服务器的响应表明该用户未登录。this.user=nullthis.loggedIn=false}}),catchError(()=>{returnof(null)}))}}exportinterfaceUser{username:stringrole:string}开启重定向例如,当未认证用户试图访问一个需要登录才能看到的页面时,网站需要自动将用户重定向到登录页面,通过后返回到原来的位置认证。当发生开放重定向攻击时,攻击者通过向用户提供来自合法站点的URL来诱骗用户访问外部站点。即,URL将其重定向到不同的站点。虽然该网站试图让用户相信他们仍在原来的网站上,但它可以帮助攻击者构建更合理的网络钓鱼活动。为防止开放重定向,您需要确保您的应用程序无法轻易将用户重定向到那些恶意站点的位置。例如,您可以通过验证重定向URL来完全禁用站外重定向。请参考如下代码段:exportclassLoginComponent{//用户在登录表单中输入的用户名和密码。用户名='';密码='';//用户登录成功后重定向到的目标URL。destinationURL='/feed'constructor(privateauthService:AuthService,privateroute:ActivatedRoute,privaterouter:Router){}ngOnInit(){this.destinationURL=this.route.snapshot.queryParams['destination']||'/喂养';}onSubmit(){this.authService.login(this.username,this.password).subscribe(()=>{//用户登录后,将他们重定向到他们想要的目的地。leturl=this.destinationURL//确认URL是相对路径-即以单个“/”字符开头。if(!url.match(/^\/[^\/\\]/)){url='/feed'}this.router.navigate([网址])})}}当然,还有很多其他方法可以防止打开重定向,比如检查请求的referrer,或者使用页面索引来重定向。然而,由于验证URL相对困难,开放重定向仍然是当代Web应用程序中普遍存在的问题。跨站请求伪造跨站请求伪造(CSRF)是一种客户端技术,可用于攻击Web应用程序的其他用户。使用CSRF,攻击者可以从受害者发送虚假的HTTP请求来执行攻击者的有害操作。例如,攻击者可以在未经受害者许可的情况下更改受害者的密码或从他们的银行账户转账。与开放重定向不同,我们目前有一种行之有效的方法来对抗CSRF,即结合使用CSRF令牌和SameSitecookie来避免使用GET请求进行各种状态更改。例如,Angular允许您使用HttpClientXsrfModule模块向HTTP请求添加防伪令牌。请参考以下代码片段:@NgModule({declarations:[],imports:[BrowserModule,HttpClientModule,HttpClientXsrfModule.withOptions({cookieName:'XSRF-TOKEN',headerName:'X-CSRF-TOKEN'}),],providers:[],bootstrap:[AppComponent]})exportclassAppModule{}template注入类似于HTML文件的网页模板,为开发者提供了一种通过将应用程序数据与静态模板相结合来指定如何呈现页面的方式。此功能允许开发人员将动态内容插入网页、从数据库或HTTP请求中检索。顾名思义,模板注入需要注入到网页的模板中。根据受感染应用程序的权限,攻击者可以使用模板注入漏洞来读取敏感文件、执行恶意代码或提升他们在系统上的各种权限。下面演示了Angular模板的不安全用法。它允许攻击者通过URL的哈希值恶意注入代码:@Component({selector:'app-header',template:''+(window.location.hash||'Home')+'
'})exportclassHeaderComponent{}注意:请不要将用户提供的输入直接连接到模板中,而是使用模板引擎内置的替换机制来安全地嵌入动态输入。请参考以下代码片段:@Component({selector:'app-header',template:'{{title}}
'})exportclassHeaderComponent{title=''ngOnInit(){这。title=window.location.hash||'家';}}跨站点脚本跨站点脚本包括也称为XSSI(跨站点脚本包含)的攻击。当恶意站点包含来自受害者站点的Javascript并通过脚本提取其敏感信息时,就会发生此类攻击。同源策略(same-originpolicy,SOP)通常可以起到控制跨源(cross-origins)数据访问的作用。但是,SOP不限制JavaScript代码,HTML