ic_agile_128ic_business_128ic_agile_white_128ic_banknote_smile_128ic_business_128ic_business_128ic_checkmark_128ic_client_team_manager_128ic_code_file_128ic_code_files_128ic_corporate_cloud_platforms_128ic_crossplatform_apps_128ic_dedicated_team_128ic_developer_128ic_development_team_128ic_enterprise_128ic_faster_timeframe_128ic_fixed_price_128ic_graph_down_128ic_graph_down_128ic_hourly_128ic_hourly_white_128ic_information_finder_128ic_junior_developer_128ic_managed_team_128ic_message_128ic_mobile_app_startups_128ic_mobile_development_128ic_mobile_development_up_128ic_mobile_devices_128ic_multiplatform_128ic_multiplatform_white_128ic_pricetag_128ic_project_checklist_128ic_project_management_128ic_project_management_team_128ic_research_and_development_team_128ic_scalable_team_128ic_senior_developer_128ic_smaller_codebase_128ic_smaller_price_128ic_startup_128ic_team_manager_128ic_three_times_faster_128Arrow_Dropdownic_001_google+_16ic_002_xing_16Group 2ic_003_facebook_16ic_004_linkedIn_16Groupic_005_message_16ic_006_upload_16ic_007_remove_16ic_008_email_16ic_009_attachment_16ic_010_file_16ic_011_name_16ic_012_arrow_left_16ic_013_arrow_right_16ic_014_arrow_down_16ic_015_arrow_up_16ic_016_dropdown_arrow_down_16ic_016_dropdown_arrow_leftic_016_dropdown_arrow_rightic_017_K&C_dropdown_arrow_up_16ic_018_language_16ic_019_Quote_16ic_020_+_16ic_021_=_16ic_022_phone_16ic_023_twitter_16ic_024_position_16ic_025_company_16ic_026_search_16ic_027_mobile_16ic_028_fax_16ic_029_location_16ic_030_enlarge_16ic_031_downscale_16ic_032_contactic_download_normal_16pxic_033_skype_16ic_006_download_16 copySearchGroup 26Rss_font_awesomeK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxK&C_Icons_32pxConsul_VerticalLogo_FullColorPacker_VerticalLogo_FullColorTerraform_VerticalLogo_FullColorVault_VerticalLogo_FullColorethereum_black_64ic_Interest_based_64ic_acrivate_card_64ic_api_client_64ic_application_architecture_64ic_application_architecture_ white_64ic_application_development_user_64ic_application_development_user_64ic_arrow_down_64ic_automated_backups_64ic_automated_infrastructure_provisioning_64ic_automated_infrastructure_provisioning_white_64ic_automated_storage_64ic_automated_storage_64ic_automation_64ic_microservice_architecture_64ic_avaliability_across_the_world_64ic_avaliability_across_the_world_white_64ic_blockchain_64ic_blockchain_white_64ic_brackets_64ic_brackets_64ic_build_64ic_build_64ic_build_64ic_business_64ic_business_partnership_64ic_business_partnership_white_64ic_business_64ic_calculator_64ic_calendar_64ic_calendar_64ic_car_rent_64ic_card_renewal_64ic_chat_64ic_chat_bubbles_64ic_chat_bubbles_64ic_chat_white_64ic_checklist_64ic_checkmark_64ic_blockchain_64ic_smart_development_64ic_blockchain_consulting_64ic_checkmark_white_64ic_clock_64ic_clock_white_64ic_cloud_media_64ic_cloud_solutionsic_cloud_solutions_whiteic_cluster_64ic_cluster_white_64ic_code_base_optimization_64ic_coding_64ic_coding_white_64ic_commenting_widget_64ic_commenting_widget_64ic_containers_64ic_containers_white_64ic_continious_64ic_continious_delivery_64ic_continious_delivery_white_64ic_continious_release_64ic_continious_release_white_64ic_continious_white_64ic_cost_saving_64ic_cost_saving_white_64ic_cpu_load_64ic_credit_card_64ic_crossplatform_app_development_64ic_crossplatform_app_development_white_64ic_custom_crm_64ic_custom_crm_64ic_independence_consulring_64ic_database_calls_64ic_database_calls_white_64ic_dedicated_teams_64ic_dedicated_teams_64ic_desktop_application_user_64ic_desktop_application_user_64ic_desktop_code_64ic_desktop_code_white_64ic_developer_64ic_developer_white_64ic_development_64ic_devops_64ic_devops_64ic_documents_64ic_documents_graph_64ic_documents_graph_white_64ic_documents_white_64ic_download_presentation_64ic_education_64ic_email_open_64ic_email_open_white_64ic_environment_healthcheckethereum_white_64ic_euro_64ic_euro_white_64ic_failure_solved_64ic_gdpr_64ic_globe_outlines_64ic_good_quality_64ic_high_load_websites_64ic_high_load_websites_white_64ic_hotel_booking_64ic_inability_64ic_inability_white_64ic_increase_64ic_increase_white_64ic_increasing_team_64ic_independence_64ic_integration_64ic_it_outsourcing_64ic_it_outsourcing_64ic_knowledge_sharing_64ic_mobile_devices_64ic_laptop_user_64ic_laptop_user_white_64ic_launch_64ic_launch_white_64ic_learning_64ic_learning_two_white_64ic_lighthouse_64ic_link_64ic_load_balancer_64ic_load_balancer_64ic_load_card_64ic_lock_64ic_lock_white_64ic_low_cost_64ic_low_load_websites_64ic_maintenance_tools_64ic_maintenance_tools_white_64ic_media_player_64ic_media_player_white_64ic_messaging_platforms_64ic_microservice_architecture_64ic_microservices_64ic_microservices_64ic_mobile_app_64ic_mobile_app_64ic_mobile_content_64ic_mobile_development_64ic_mobile_development_white_64ic_mobile_devices_64ic_mobile_devices_white_64ic_mobile_payments_64ic_mobile_social_media_applications_64ic_mobile_workflows_64ic_money_transfers_64ic_multimedia_sharing_64ic_multimedia_sharing_white_64ic_my_garage_64ic_no_access_64ic_no_access_white_64ic_no_oldschool_64ic_online_marketplaces_64ic_online_marketplaces_white_64ic_online_trading_64ic_online_trading_64ic_pair_device_64ic_parallels_64ic_parallels_white_64ic_passcode_64ic_payment_systems_64ic_performance_64ic_performance_issues_64ic_performance_issues_white_64ic_performance_white_64ic_plane_64ic_plane_white_64ic_plus_64ic_plus_64ic_pricetags_64ic_pricetags_64ic_product_64ic_product_search_64ic_product_white_64ic_productivity_tools_64ic_productivity_tools_64ic_project_delivery_64ic_project_delivery_white_64ic_project_management_64ic_project_management_collaboration_64ic_project_management_team_64ic_project_management_team_white_64ic_project_risks_reduced_64ic_quality_mark_64ic_quality_mark_64ic_quality_mark_white_64ic_question_64ic_react_native_64ic_response_time_64ic_response_time_white_64ic_rest_api_64ic_retail_64ic_transparency_consulting_64ic_scale_up_64ic_scale_up_white_64ic_security_64ic_security_64ic_self_healing_64ic_self_healing_64 copyic_send_money_64ic_server_64ic_server_white_64ic_shopping_64ic_shopping_white_64ic_sleep_mode_64ic_small_is_beautiful_64ic_smaller_price_64ic_social_benefits_64ic_social_connections_64ic_socket_64Group 20ic_spare_parts_for_cars_64ic_spare_parts_for_cars_white_64ic_speedometer_64ic_performance_consulting_64ic_speedometer_white_64ic_startup_64ic_startup_white _64ic_target_64ic_team_64ic_testing_64ic_testing_checklist_64ic_testing_checklist_white_64ic_testing_white_64ic_three_times_faster_64ic_touch_64ic_touch_id_64ic_touch_white_64ic_transparency_64ic_ui_design_desktop_64ic_ui_design_mobile_64ic_ui_design_mobile_white_64ic_umbrella_64ic_umbrella_64ic_umbrella_white_64ic_up_and_down_scaling_64ic_up_and_down_scaling_64ic_users_64ic_users_white_64ic_ux_design_64ic_ux_design_desktop_64ic_ux_design_64ic_ux_design_white_64ic_vehicle_64ic_web_based_search_64ic_web_based_search_white_64ic_web_browser_code_64ic_web_browser_developer_mode_64ic_web_browser_user_64ic_web_development_64ic_web_development_white_64ic_web_portals_64ic_web_portals_64ic_web_user_64ic_web_user_white64ic_workflow_64ic_workflow_steps_64ic_workflow_steps_white_64ic_workflow_white_64ic_working_environment_64solidity_blackGroup 19

Web App Security 101: How to Defend Against a Brute Force Attack

Don’t use the name part of your email as an app sign-in username, if your email is everywhere. Don’t make selfies with a password written on a whiteboard in the background. And don’t implement Captcha unless you absolutely have to!


In our new Security 101 post (check out the previous post about Threat Modeling) we’ll touch upon the topic of brute force attacks and ways to defend against them. This type of attacks is common, but, thankfully, there are countermeasures that are relatively easy to take, though some of them often get either overlooked or overhyped.

BRUTE FORCE ATTACK: A trap for the careless

In most cases, a username and password are required to access the app. If an attacker doesn't have any valid credentials, either obtained from leaked database or stolen in some other way, for example, with phishing email, a brute force attack is what would likely be used. The goal of the attack is to find at least one valid pair of a username and password.


Sometimes, an attacker can obtain a valid password just by researching publicly available info on the company and watching closely. There are cases of a password been written down on the post-it note at the side of employee's monitor or at the whiteboard in the conference room, which then pop up in a picture or a company video. Knowing only the password, but not the username, the attacker would perform a reverse brute force attack, seeking matching username for the password.


But quite frequently, the attacker will brute force passwords because usernames are easier to acquire – they’re either public (like a nickname on a forum) or can be acquired relatively easy in other ways.

DAWN BEFORE BATTLE: How an attacker may try to pry open your app

Creating a list of username candidates

The pool of login candidates can be easily created by browsing the company’s web pages. An intruder will look at different website's sections, searching for people’s emails or names. It's very probable that their logins would turn out to be the same as email addresses or contain letters or acronyms from names.

Looking through metadata

Files like photos or office documents very often contain additional information stored as their file properties. This information, called metadata, could include personal data, sometimes containing someone’s login.


Obtaining such kind of files may not be particularly hard if an attacked website has a photo gallery or a download section with white papers or catalogs or any other downloadable files with compromising metadata still present in them.



Even if no such section is available for public access from the main page, there’s still a chance that some of metadata-rich files are publicly hosted under your domain. If that is the case, then it's possible that this content was indexed by a search engine. A Google search query that looks for Word files at a given domain can look like this: site:example.com filetype:docx

Verifying candidates

After getting the list of possible usernames, the attacker would need to find out which ones are valid. One of the options for doing that is to use the login page. It is important to implement the login form in a way that doesn’t specify whether login or password is invalid ("Wrong username or password"), giving no hint to an attacker which of them is actually incorrect. It’s also worth noting that it's not only a matter of a message presented to end user. If there's a back-end API that performs a sign in, make sure that there's no difference not only in response's body, but also in its status and headers.


After making sure that the login form can't be used to verify the username, also check the recovery form ("I forgot my password" option). Here the situation is a bit trickier, and a generic message like "If there's such user we've send him an email" might not be enough. In a so called blind attack it’s not the response's body or status what is taken into consideration, but the amount of time it takes for the message to be displayed. An attacker would expect nearly immediate response to an invalid username.


On the other hand, a valid username would prompt a server to actually send a recovery email, and the response message would get slightly delayed. To prevent this the action has to be asynchronous, with an email sent in a background thread.

Password guessing

The original idea behind the family of brute force attacks is that the whole spectrum of possible values should be checked. This means password candidates are generated letter by letter, iterating over the set of allowed characters. It takes a lot of time, more than attacker would be ok with, so it is likely that a dictionary attack would be used. There are a lot of password dictionaries available. Some of them rely on users’ habit to use simple passwords, some them come from database leaks of real services.



A brute force attack usually is not performed manually, and most likely some automation tool would be used. There’s plenty of them out there, and they’re pretty simple to use, down to providing a file with password candidates, application's URL and choosing the authentication method. Take, for example, THC-Hydra - this penetration testing tool is able to brute force not only HTTP login forms but also a great number of other interfaces secured by login/password: SSH, HTTP basic auth, databases etc.

SHIELDS UP: Countering a brute force attack

Detecting the attack

Of course, before we get to fight a brute force attack we must first detect it. Make sure that your application has tools for monitoring network traffic. At least two things would be helpful: metrics and logs.

-The HTTP metrics should be detailed enough to determine the URL and method of each incoming request, status and number of produced responses, etc. Then special alerts might be created in monitoring tools that will inform you about any suspicious behavior (like increased number of 401 responses for the signing in endpoint).

-Logs will provide more detailed information about each request that cannot always be collected and presented as metrics. It can contain data like request headers, source IP, request body etc. Analyzing them could help understand the details of the attack and come up with defense tactic.

IP blocking

First thing that can come to mind after detecting an attack is to block an attacker's IP address. But that's not a very good way of deterring an attack, because:

-The attacker can easily overcome this by dynamically changing the IP address

-Blocking a public IP may cut off other users that use it

User blocking

Another idea might be to block an account with too much failed login attempts. A special action would then be required from user in order to unlock it.


This is a risky approach. An attacker could make numerous attempts with a lot of valid usernames, and you’ll end up blocking a good portion of your users. Most of them will probably unblock their accounts the first time it happens. But will they do that the second time and then again and again? Eventually this may turn users away from your app and that’s obviously not what we need.



A lighter version of this solution is to lock an account temporarily, with a response like "You entered your password incorrectly for a few times in a row. Try again in 30 seconds". In this case the account owner doesn't need to do anything really aside from waiting a bit. But a persistent attacker could likely trigger the temporary locking again and again, stripping the actual user of the ability to sign in.

CAPTCHA

CAPTCHA stands for Completely Automated Public Turing Test to Tell Computers and Humans Apart. No matter how it is implemented, a notorious "proof that you're not a robot" request is always irritating. Quite often it's not convenient to resolve CAPTCHA on desktop and sometimes on mobile versions it could suddenly turn into usability wall for a user. In applications that prioritize user friendliness, CAPTCHA should be considered a last resort.


Moreover, many CAPTCHA implementations are vulnerable to attacks - either automated, that utilize OCR or neural networks, or social engineering-type, in which large groups of people are paid (or lured) to solve CAPTCHA puzzles in real time.



If you want to (or must) add CAPTCHA to the login page, consider the following:

-Don't ask CAPTCHA immediately before the first login attempt, it is better to do that after one or more failed attempts in a row for a given username. This way you’ll irritate real users less.

-Ask for CAPTCHA for non-existing username sign in attempts to complicate the attacker’s task of finding real/active accounts.

-Don't implement your own CAPTCHA solution. Use an existing, proven and possibly paid one.

Latency/Delay

During brute force attack an attacker will try out many password options. Introducing a delay between failed login attempts would significantly slow the process down, probably rendering the whole deal too time-consuming for an attacker. That additional latency won't bother real users, for who will likely not mind waiting a few extra seconds is they’ve made a mistake typing in a password. For longer periods, like 10 seconds, consider showing user some kind of a countdown timer.

Asking user an additional secret question

The secret question and a corresponding answer are configured in user profile. Present that question for logins with too many failed login attempts, expecting the user to provide a valid answer. Make sure to ask such question also for invalid logins, so the attacker won’t have another way of discovering real (existing) accounts.

Tricking brute forcing tools

In a brute force attack some of the penetration testing tools might be used, like the above mentioned THC-Hydra. Those programs send requests with User-Agent header set to a default value, a tell-tale sign of the attack tool.


By randomly returning the 200 status response for requests with such header, an application can fool the attacker that will no longer be able to distinguish between correct and failed attempts. It’ll work on amateur hackers who don't know how to modify Hydra's request headers. Note this isn't a fully secure solution as we can't always rely on request headers.


To be continued…

SHARE WITH FRIENDS
You might find this interesting
Our cases
Bosch Classic Cars - Digital Engagement Platform for 19K Vintage Car Owners
Our cases
Liferay Portal Performance Tuning Services for a Major Online Gaming Software Supplier
Web
Three Authentication Approaches to Keep Your Clients Safe
Our cases
How to apply React Native while developing heavy cross-platform mobile apps
Mobile
Reasons to believe in Ionic hybrid app
Web
SEO Tips & Tricks for Single Page Web Applications
E-book
How to Secure Web Product Development — FREE eBook
E-book
Digital Transformation: the Philosopher’s Stone of Economic Growth
Web,Outsourcing,Other
Angular 5 VS React.js – Who’s Going to Set the Tone in the Upcoming Year?
Web
Agile and DevOps are Key Drivers of Digital Transformation
Web
K&C insights: how to make your workflow work for you
Web,Other
GoLang: Features, Pros and Cons
Our cases
Reference: Major producer of auto electronics and spare parts
Outsourcing,Other
Hybrid, SaaS+PaaS, IoT: Cloud Trends to Catch in 2018
Web,Outsourcing,Other
Angular vs. React vs. Vue – Let the Fight Start!
DevOps
DevOps with Puppet: Tips on Setting it up for Configuring Servers
Web,Outsourcing,Other
JS Frameworks: The Trendiest Frameworks You Should Know
Our cases
Micro-service Architecture for New AngularJS Application - Case Study
Mobile
Native or Hybrid Apps: A Quick Comparison
DevOps
Installation and setting up: Nextcloud as a local network storage on CentOS7
Web
Centralized Logging with Logstash, Elasticsearch & Kibana
Web
A Guidance for Keeping Your Web Development Project Within the Budget: Three Key Pillars
Web
Plan to Succeed: 4 Tips for Building Scalable Software
Web
Microservices… when do we need them?
Web
Debunking imaginary shortcomings of cross-platform frameworks
Our cases
Portal Performance Tuning For Major German Travel Agency
Web
Technologies that Foster Digital Transformation
Web,Other
How to Make Your Web Solution Rock: 7 Areas to Check
Web
4 Time-Saving Ways to Test Your Cross Platform Mobile App
Web,Outsourcing,Other
Angular 5.0.0 – A Better Version of Itself
E-book
Top Tools for Cost-Effective Web Development — eBook
Web
A secret formula of an agile dream team
Web
Cloud Deployment: Overview of Options
Web
How to Motivate Your Dedicated Team to Work with Legacy Projects
Web,Our cases
White Label: A Customized Software Solution from a Business and Tech Perspective
Web
Cost efficient technologies
Web
Scaling software solutions - how it works
DevOps,Outsourcing,Other
How to setup Kubernetes cluster on AWS
DevOps
Docker: Virtualize Your Development Environment Right
Web
When Microservices Help Make Future-Ready Products
Outsourcing,Other
How to Ramp up Your Team Wisely
Outsourcing,Testing
How the QA Team Tests Your Project
DevOps
How We Manage Our Infrastructure with Chef
Our cases
Reformation of Deployment Cycle for Bosch Classic Cars Portal
Our cases
Fast and Lightweight Mobile Application based on PhoneGap/ Cordova
Our cases
Drivelog.de — Web Marketplace for Car Owners and Service Providers
DevOps
Use case: how to build and run Docker containers with NVIDIA GPUs
DevOps
How We Use Ansіble for Configuration of Our Environments
Web
Angular 2.0 vs Angular 1.4. What fits you best?
Other
Big Data: Why Your Business Needs it ASAP
Web,Outsourcing,Other
How a Company Can Benefit from White Label: K&C experience
DevOps
How to Build a Rancher & Docker Based Cloud
DevOps
Setting Up: Traefik Balancer In Rancher Cloud
E-book
Determining Approaches to Mobile App Development
Web,Other
Dedicated Teams for Web Development: Choice Criteria to be Checked
Web
Angular 4 vs React – what to choose in 2017
Outsourcing
The BPM in the Microservice Environment
DevOps,Outsourcing,Other
ROCKET.CHAT as an internal messaging system and helpdesk platform
Web,Amazon Web Services
Monolith, Microservices, Serverless... Are We in the Middle of the Way?
Web
JQuery vs. Angular: Ad Astra per Aspera
DevOps
How to start services on Linux
Web
Advanced Technologies for Marketing Automation
Web,Outsourcing
Node.js vs. Angular.js – Two Sides of the Same Coin
DevOps,Outsourcing
AWS DevOps: A New Way to Run Business
Web,Outsourcing
Why It’s Better to Use Vue.js than Angular and React in 2018
Web,Outsourcing
Migration from Angular 1 to Angular 5
DevOps,Outsourcing,Amazon Web Services
Information Security with AWS DevOps
Other
Europe’s Big Payments Directive PSD2
Our cases
The Platform Providing Event Organization
Web,Outsourcing,Other
Golang vs. Node.js
Our cases
VAIX - Fault tolerant infrastructure for 24/7 high-load machine learning service
Web,DevOps,Our cases
Our case: Marketplace for gaming goods
Web,Outsourcing
Angular 6 Will Be A Hit
Web,Outsourcing,Testing
Web App Security 101: Keep Calm and Do Threat Modeling
Web,Mobile,Outsourcing,Other
All You Wanted to Know About Chatbot Platforms
Web
What's New in React 16.3.0 - 16.4.2: Features Overview
Web,Outsourcing
ANGULAR 6 versus REACT 16.3
Other
GDPR: Smart Practices
Web
Fintech Apps - A Lucrative Solution for Customers and Businesses Alike
Other
Swimming with Sharks
Web
Node.js 10.0.0: Everyone’s Favorite Got Even Better
DevOps,Outsourcing
Rancher 2.0: A Quick Look at the New Version
Our cases
How to Save Money Using Your Own Infrastructure
Other
I’m Tired of Blockchain Hype, Are You?
Web,Other
Progressive Web Apps and Why You May Need Them
Other
Don’t Treat Me Like a Fool: The worst thing you can do for your business
Other
How to Convert Your Business to an Amazon-Style Market Leader
Web,Outsourcing,Other
JavaScript & WebSockets: How to Build Real-Time Applications
Other
Culture eats technology for breakfast
Outsourcing,Other
How to Control Agile Development: Progress and Costs
Marketing
Аudience-based Marketing
Other,Marketing
How to Become a Leader in Your Market
Web,Other
SSR or CSR for Progressive Web App
Web,Outsourcing
Angular 6 vs. Ember 3
Outsourcing
SCALED AGILE FRAMEWORKS: YOUR COMPLETE GUIDE TO WHICH, WHY AND HOW
DevOps,Other
Security in Kubernetes and How Companies Can Benefit from It
DevOps,Other
DevOps Becomes DevSecOps to Secure Your Application
Web,Other
JAMSTACK IS THE NEW FACE OF STATIC SITES
DevOps
Hashicorp in Kubernetes: The short guide for Consul & Vault
Testing
What Is Quality Assurance and Why You Need It Immediately
Web,Outsourcing,Amazon Web Services
DEBUGGING AWS LAMBDA FUNCTIONS
Other
The Power of the Holistic Business Analysis
Other
Ember, jQuery, Angular, React, Vue: What to Choose?
DevOps
Kubernetes backup with Heptio Ark
DevOps
What to Choose: NFS or CEPH?
Web,Mobile,Back-end,Amazon Web Services
Serverless Architecture for Modern Apps: Stacks Providers & Caveats
Web,Mobile,Back-end,Amazon Web Services
Why Enterprises Choose Serverless Architecture
DevOps,Amazon Web Services
Kubernetes is at the Forefront of a Secure Microservice Future
DevOps
DevOps: Kubernetes Federation on Google Cloud Platform
Web
All You Need to Know About Web App Security Now
Web,Outsourcing,Testing
QA for CxOs: How to Hire and Outsource
Web,DevOps,Outsourcing
DevOps als DevSecOps – Integrierter Schutz vor Bedrohungen ohne Termin- und Budgetüberschreitung
Web,Outsourcing
Angular 7 vs React
Web,Mobile,Outsourcing
Web-Anwendungen ziehen mit Mobile-Apps gleich
Web,Outsourcing,Testing
Sicherheit für Web-Anwendungen - dank Threat Modeling
Outsourcing,Testing
Die Rolle des QS-Teams in Software-Projekten
Outsourcing,Other
Fortschritt und Kosten im Griff: agile Software-Entwicklung unter kontrollierten Bedingungen