โปรดอธิบายสาเหตุและรายการภาษาที่มีการใช้งานคุณสมบัติ (ผิดพลาด) เท่าที่คุณทราบ
โพสต์สิ่งที่คุณพิจารณาถึงคุณสมบัติที่เป็นอันตรายไม่ใช่สิ่งที่คุณไม่ชอบ
a = 1/0
- การแสดงออกขั้นพื้นฐานเป็นอันตราย ;-)
โปรดอธิบายสาเหตุและรายการภาษาที่มีการใช้งานคุณสมบัติ (ผิดพลาด) เท่าที่คุณทราบ
โพสต์สิ่งที่คุณพิจารณาถึงคุณสมบัติที่เป็นอันตรายไม่ใช่สิ่งที่คุณไม่ชอบ
a = 1/0
- การแสดงออกขั้นพื้นฐานเป็นอันตราย ;-)
คำตอบ:
ข้อมูล: http://php.net/manual/th/security.globals.php
นี่คือคุณลักษณะที่แย่ที่สุดที่จะนำมาใช้เนื่องจากเหตุผลในการอ่านและเหตุผลด้านความปลอดภัย โดยพื้นฐานแล้วพารามิเตอร์ GET ทั้งหมดที่ได้รับจะถูกเปลี่ยนเป็นตัวแปร
ตัวอย่างเช่นกับ URL นี้: /index.php?value=foobar
คุณสามารถทำสิ่งต่อไปนี้:
<?php
echo $value; // return foobar
?>
เมื่อคุณกำลังอ่านโค้ดมันค่อนข้างสับสนที่จะรู้ว่าตัวแปรมาจากไหน
นอกจากนี้หากใช้งานผิดวัตถุประสงค์อาจทำให้เกิดช่องโหว่ด้านความปลอดภัย นี่คือตัวอย่างรหัสจาก php.net ที่แสดงให้เห็นว่าสามารถนำไปใช้ในทางที่ผิดได้อย่างไร:
<?php
// define $authorized = true only if user is authenticated
if (authenticated_user()) {
$authorized = true;
}
// Because we didn't first initialize $authorized as false, this might be
// defined through register_globals, like from GET auth.php?authorized=1
// So, anyone can be seen as authenticated!
if ($authorized) {
include "/highly/sensitive/data.php";
}
?>
อนุญาต Null โดยค่าเริ่มต้นความผิดพลาดของ "ล้านล้าน" * ดอลลาร์ ขออภัยโทนี่โฮอาร์ เกือบทุกภาษามีอยู่บนโลกใบนี้
* ฉันปรับการแสดงออกประกาศเกียรติคุณจาก Tony Hoare เพื่อสะท้อนการสูญเสียที่เกิดขึ้นจริงในวันนี้ :-)
MACROS C และ C ++ ถ้าฉันต้องเห็นข้อผิดพลาดของคอมไพเลอร์อื่นเนื่องจากมีคนเลือกชื่อฟังก์ชันมาตรฐานสำหรับแมโครของพวกเขาซึ่งใช้รหัสของฉันฉันจะกรีดร้อง เรามาดูการละเมิดครั้งสุดท้าย:
#define vector(int) new VARIANT[int];
Aaarg! คุณทำอะไรกับเวกเตอร์ STL ของฉัน!
การตกหล่นโดยค่าเริ่มต้นในคำสั่งการเปลี่ยน C และ C ++
break
คำสั่งหรือบางคนเพิ่มเคสระหว่างสองกรณี (หรือสั่งอีกครั้ง) ไม่สังเกตเห็นว่ามีการตกลงระหว่างกัน ฉันไม่เห็นทางที่ fallthrough ดีกว่าวิธีที่ C # ต้องใช้ทั้งการแบ่งหรือกรณีข้าม ฯลฯ
การแปลงประเภทโดยนัยเมื่อประเภทที่ถูกแปลงระหว่างไม่มีความสัมพันธ์ที่ชัดเจน ตัวอย่างเช่นการแปลงแบบสุ่มไม่ใช่ตัวเลขstring
ให้เป็นint
เช่นใน PHP
explicit
ซึ่งจะหยุดการแปลงประเภทโดยนัย แต่ยังคงมีปัญหาอยู่
0
ค่าบางค่า
ข้ามไป : แม้ว่าจะใช้ได้ในบางกรณี แต่ก็มักจะใช้ในทางที่ผิดและนำไปสู่การอ่านยาก
ไม่มี
เพียงเพราะฟีเจอร์ที่ถูกนำไปใช้ในทางที่ผิดบ่อยครั้งไม่ได้ทำให้เกิดอันตราย
IMHO ทั้งหมด "ถือว่าเป็นอันตราย" คือReductio ad Hitlerumของการสนทนาภาษาโปรแกรม
ส่วนใหญ่ถ้าไม่ทั้งหมดของคุณสมบัติ "อันตราย" มีหรือมีมา แต่เดิมกรณีการใช้งานที่ถูกต้องมากหรือเป็นเพียงวิธีการอำนวยความสะดวกในตอนแรก มันขึ้นอยู่กับนักพัฒนาที่จะเข้าใจข้อดีข้อเสียและรหัสตาม
หากคำถามของคุณมีความหมายที่จะเป็นบางสิ่งบางอย่างตามแนวของ "คุณสมบัติภาษาอะไรมีข้อผิดพลาดทั่วไปหรือผลข้างเคียงที่โชคร้าย" คำตอบของฉันจะแตกต่างกัน
[แก้ไข] มีความชัดเจน: ฉันไม่ได้หมายถึงการใช้วิธีการคัดค้านอย่างต่อเนื่อง หากนักพัฒนาซอฟต์แวร์คิดค่าเสื่อมราคา / ลบคุณลักษณะคุณควรใช้การแทนที่ ฉันหมายถึงแนวคิดว่าส่วนปัจจุบันของภาษาถือว่าเป็นอันตรายเพราะบางคนไม่ชอบสิ่งที่กระตุ้นหรือการแลกเปลี่ยนที่เกี่ยวข้องกับการใช้งานที่หลายคนพูดถึง
Autovivification (หรือคุณสมบัติอื่น ๆ ผูกตัวแปร -on- (assign | ใช้)) เป็นคุณสมบัติที่ฉันได้พบเพื่อให้ข้อบกพร่องมากที่สุด
PLEASE
ใน INTERCAL อย่าใช้มันให้พอมันบ่น ใช้มันมากเกินไปก็บ่น
แม้ว่าคนบางคนไม่เห็นด้วยกับชายหรือสิ่งต่าง ๆ ที่เขาพูดJavaScriptของ Douglas Crockford จำนวนมาก: The Good Partsเป็นคำถามที่ใช้กับ JS ท่ามกลางข้อร้องเรียนของ Crockford:
ขอบเขตทั่วโลกโดยค่าเริ่มต้นสำหรับทุกอย่าง (DC แสดงวิธีการใช้ฟังก์ชั่น / วัตถุเป็น namespaces และตัวคั่นขอบเขตที่จะโต้เถียงนี้)
คำสั่งwith
ที่มีพฤติกรรมความล้มเหลวคือการกำหนดสิ่งต่าง ๆ ที่ namespace ทั่วโลก (Gah! มันเหมือนคำขวัญ JS คือถ้าคุณล้มเหลวแล้วล้มเหลวอย่างหนักที่สุด !)
พฤติกรรมที่ไม่คาดคิดกับ==
ผู้ปฏิบัติงานซึ่งโดยทั่วไปกำหนดให้คุณต้องใช้ตัว===
ดำเนินการเสมอ
อัฒภาคแทรก
จริงๆแล้ว JS จำนวนมากควรได้รับการพิจารณาว่าเป็นอันตรายแม้กระทั่งทั้งภาษา แต่ชิ้นส่วนที่ดีนั้นก็แย่มากจนทำให้มันเหมาะสำหรับมัน (อย่างน้อยสำหรับฉัน)
ตกลงไม่ใช่คุณสมบัติของภาษาเอง แต่ก็ยังมีความเกี่ยวข้องอย่างใกล้ชิด
ทันใดนั้นแอปพลิเคชั่น Flash / Flex ของคุณก็หยุดทำงานและไม่มีใครสามารถบอกได้ว่าเกิดอะไรขึ้นกับ f * ไม่มีข้อความแสดงข้อผิดพลาดไม่มีสแต็คเทรซไม่มีอะไรเลย เป็นเพียงว่าการเปลี่ยนหน้าจอก็ไม่ได้เกิดขึ้น (หรือเกิดขึ้นในทางที่ผิด) หรือปุ่มไม่ตอบสนองต่อการคลิกอีกต่อไปหรือ comboboxes ว่างเปล่าแทนที่จะถูกเติมด้วยรายการบางรายการ
"คุณสมบัติ" เพียงอย่างเดียวนั้นมีหน้าที่รายงานยักหลายอย่างและผมสีเทาจำนวนมากที่ฉันได้รับ -.- ในขณะที่ popping อัพข้อความลับ ๆ บางอย่างในหน้าของผู้ใช้ไม่พึงประสงค์อย่างน้อยก็อย่างน้อยก็สามารถช่วยนักพัฒนาได้รับการแก้ไขปัญหา
แต่ Flash Player ปล่อยให้คุณแทงไปในที่มืดโดยอาศัยคำอธิบายของผู้ใช้ (ในขณะที่ปัญหาอาจเกิดจากตำแหน่งที่แตกต่างอย่างสิ้นเชิงในรหัสที่ไม่มีส่วนเกี่ยวข้องกับสิ่งที่ผู้ใช้ทำ) เฉพาะในกรณีที่คุณใช้ Debug Player คุณจะได้รับหน้าต่างป๊อปอัพพร้อมกับข้อความแสดงข้อผิดพลาดและสแต็กสแต็ก
อย่างไรก็ตามอาจเป็นเรื่องที่น่าสนใจในการรับชมภาพยนตร์ที่ฝังตัวแฟลชในเว็บไซต์ข่าวบางแห่งและได้รับข้อความซ้ำ ๆ : D
ใน C / C ++: การกำหนดนั้นเป็นนิพจน์ที่รวมเข้ากับการมอบหมาย = และการเปรียบเทียบ == ตัวดำเนินการที่คล้ายกันมาก ไม่ใช่คุณสมบัติที่เป็นอันตรายต่อ แต่เป็นวิธีที่ง่ายในการแนะนำข้อผิดพลาด (บางครั้งบอบบาง) โดยการพิมพ์ผิดพนักงานโดยไม่ตั้งใจ
int i = 10;
someCode();
if(i = 5)
{
/* We don't want this block to be executed, but it is */
moreCode();
}
เข้าถึงโมดิฟายเออร์ใน Java ด้วยค่าเริ่มต้นภาษาส่วนตัวของแพ็กเกจและค่าเริ่มต้นของแผนการเขียนโปรแกรมส่วนตัว
rm -rf $nosuchvar/*
การเปลี่ยนตัวแปรไม่ได้กำหนดโดยสตริงที่ว่างเปล่าในเปลือกโดยไม่มีคำเตือนใด ๆ
${varname:-/dev/null}
อาจจะเป็นวิธีแก้ปัญหา ...
ความสามารถในการหมุนทวนเข็มนาฬิกาในโลโก้ Wtf ให้เปลี่ยน360 - x
องศาตามเข็มนาฬิกา
ใน Java และในภาษาอื่นคุณสามารถหยุดเธรดจากอีกอันหนึ่งโดยไม่มีการให้เวลาสำหรับเธรดที่คุณหยุดให้เสร็จสิ้นอย่างถูกต้อง ความสามารถนี้ถูกคัดค้านโดยพิจารณาจากปัญหาจำนวนมากที่สามารถนำมาใช้ในเกือบทุกสถานการณ์
ตัวแปรตัวแปรใน PHP
เพียงเพราะคุณ$can
ไม่ได้หมายความว่าคุณ$$should
use strict
) และวิธีที่ง่ายในการเปิดใช้อีกครั้งในกรณีที่คุณต้องการ ( no strict 'refs'
)
With
คำสั่งใน Delphi มาถึงใจแม้ว่าจะมีกรณีที่มันเป็นประโยชน์
อาร์เรย์ใน AWK เริ่มต้นที่ดัชนี1 !
car
! : P
ใน Perl บริบทสเกลาร์กับบริบทรายการอาจเป็นเรื่องยุ่งยาก มีจุดดีที่ทำให้การดำเนินการบางอย่างสะดวก แต่บางครั้งคุณพบสิ่งที่แย่มากเช่นการเปลี่ยนความหมายของผู้ปฏิบัติงานอย่างสมบูรณ์ (อาจอยู่ในระยะห่างที่สำคัญในรหัส)
sub foo { (1..5) }
my @list = foo(); # (1,2,3,4,5)
my $length = scalar @list; # 5. the length of the list.
my $length2 = scalar foo(); # '' (the empty string. because it's false)
นั่นไม่ถูกต้อง
(มันเกิดขึ้นจากการพยายามทำบางสิ่งบางอย่างที่ทำหน้าที่คล้ายกับโอเปอเรเตอร์ช่วงปกติดังนั้นคุณสามารถพูดอะไรซักอย่างในวงวนได้next if /start_regex/ .. /end_regex/
)
Python 2.x ไวยากรณ์การนำเข้าแบบสัมพัทธ์ สมมติว่าฉันมีแพคเกจx.plugins
ที่เพิ่มการสนับสนุนสำหรับห้องสมุดอื่น ๆ x
อีกมากมายสำหรับ และคิดว่าฉันมีsqlalchemy
โมดูลในเพื่อให้สามารถเพิ่มการสนับสนุนเพื่อx.plugins
sqlalchemy x
คุณคิดว่าจะเกิดอะไรขึ้นถ้าฉันเพิ่มบรรทัดต่อไปนี้ใน sqlalchemy.py
import sqlalchemy
คำตอบคือโมดูลจะพยายามนำเข้าเอง สิ่งที่ไวยากรณ์นี้ทำคือทำให้ไม่สามารถนำเข้าแพคเกจ sqlalchemy ส่วนกลางที่แท้จริงได้ Python 2.5 เพิ่มวิธีการระบุว่านี่คือการนำเข้าแบบสัมพัทธ์:
from . import sqlalchemy
... แต่มันไม่ได้จนกว่า Python 3 ที่ไวยากรณ์แรกจะได้รับการกำจัด (แม้ว่าจะสามารถปิดการใช้งานใน Python 2.6+ ด้วยfrom __future__ import absolute_import
)
sun.misc.unsafeเป็นรายการโปรดของฉันตลอดกาล ; คอลเลกชันของ "เราต้องการสิ่งนี้เพื่อดำเนินการต่างๆ แต่จริงๆแล้วไม่คิดว่าคุณควรใช้มัน"
บล็อกทั่วไปของ FORTRAN หากคุณทำผิดพลาดง่าย ๆ ส่วนหนึ่งของแอปพลิเคชั่นอาจปิดบังส่วนโค้งของอีกส่วนหนึ่งได้
FORTRAN ได้รับคำสั่ง goto / COBOL แก้ไขคำสั่ง รหัสแก้ไขตัวเอง อันตรายเตือนสัตว์ประหลาดปาเก็ตตี้ที่บินได้ !!
การวางแนววัตถุ (จากภาษาที่พิมพ์แบบคงที่ทั้งหมด) ฉันจะเดิมพันคุณลักษณะนี้ได้และจะยังคงที่จะเสียค่าใช้จ่ายอย่างมากมายมากกว่าตัวชี้ null การวางแนววัตถุทำได้ดีในภาษาที่ส่งผ่านข้อความแบบไดนามิกเท่านั้น ดังนั้นควรลบออกจากภาษาแบบไดนามิกเช่น Python ด้วย (เนื่องจากไม่ได้ใช้การส่งข้อความ แต่เป็นการเรียกรูทีนย่อยทั่วไป)
magic_quotes
ใน PHP
นักพัฒนาที่ไม่มีประสบการณ์ก็ขึ้นอยู่กับว่ามันถูกเปิดใช้งานและจะถือว่าอินพุตของผู้ใช้ทั้งหมดถูกหลบหนีเพื่อใช้ในแบบสอบถาม SQL หรือพึ่งพามันถูกปิดการใช้งานและจะหนีจากอินพุตของพวกเขา
เมื่อสมมติว่าเปิดใช้งานอยู่แล้วเรียกใช้รหัสบนระบบที่ไม่เปิดช่องโหว่การฉีด SQL ที่กว้าง
เมื่อสมมติว่ามันถูกปิดการใช้งานและไม่ใช่มันจะส่งผลให้แบ็กสแลชถูกจัดเก็บจริงในฐานข้อมูลทำให้เกิดสตริงที่น่าเกลียด / ไม่ถูกต้อง
นอกจากนี้ยังไม่มีวิธีที่ง่ายที่สุดในการจัดการกับทั้งสองกรณี - คุณต้องตรวจสอบว่ามีการเปิดใช้งานหรือไม่get_magic_quotes_gpc()
และใช้stripslashes()
กับค่าทั้งหมดใน$_*
อาร์เรย์ - เนื่องจากarray_map
ไม่เรียกซ้ำคุณต้องมีฟังก์ชันที่กำหนดเองสำหรับสิ่งนี้
คุณสมบัติภาษาที่อนุญาตให้โปรแกรมเมอร์เขียนโค้ดที่ไม่มีข้อคิดเห็นหรือไม่มีความคิดเห็น
ออกไปข้างนอกนิดหน่อยที่นี่ - ฟังก์ชั่นโมฆะ ฟังก์ชั่นมักจะทำอะไรบางอย่างดังนั้นจึงควรส่งคืนผลลัพธ์หรือข้อมูลอื่น ๆ ที่เกี่ยวข้องกับความสำเร็จหรือความล้มเหลว
POKE ในภาษาเบสิก
ฉันต้องบอกว่าเก็บขยะ ไม่ได้ขจัดความจำเป็นในการคิดเกี่ยวกับการจัดการหน่วยความจำ แต่กำจัดการรับรู้ถึงความจำเป็นในการคิดเกี่ยวกับการจัดการหน่วยความจำซึ่งทั้งหมดมักจะกำจัดความคิดที่เกิดขึ้นจริงแล้วคุณจะได้รับทรัพยากรมหาศาลและไม่รู้ว่าทำไม โดยเฉพาะอย่างยิ่งเมื่อพฤติกรรมของ GC generational สมัยใหม่สามารถอธิบายได้โดยไม่ต้องมีอติพจน์มากเกินไปในฐานะ "หน่วยความจำขนาดใหญ่หนึ่งรั่วไหลโดยการออกแบบ" อย่างไรก็ตาม
C และ C ++ แน่นอน: ตัวชี้ทางคณิตศาสตร์ การอนุญาตให้บุคคลแปลงจำนวนเต็มเป็นที่อยู่หน่วยความจำกำลังถามถึงปัญหา
และบางทีแม้แต่การเข้าถึงตัวชี้ไปยังดิบอย่างสมบูรณ์?
ใน C ++ คุณมีการอ้างอิงที่ทำให้ตัวชี้เกือบไม่จำเป็นทั้งหมด สำหรับกรณีที่เหลือตัวชี้สมาร์ทควรได้รับการพิจารณาบังคับ
Java ยังพิสูจน์ให้เห็นว่าคุณสามารถสร้างภาษาการเขียนโปรแกรมที่ใช้ตัวชี้โดยไม่อนุญาตให้ผู้ใช้เข้าถึงค่าตัวชี้ได้
นอกเหนือจากnull
... แต่นั่นเป็นเรื่องที่แตกต่าง
for(int i=0;i<SIZE;++i) ++arr[i]
for(int*i=arr;i<arr+SIZE;++i)*i++
java ทั้งหมดที่มีการจัดการเพื่อพิสูจน์ว่าคุณต้องการตัวชี้หรือคุณไม่เคยดูsun.misc.Unsafe
? หากคุณไม่ต้องการตัวชี้โปรดอธิบายวิธีเขียนฟังก์ชันการแลกเปลี่ยนทั่วไปโดยใช้ Java (เช่น int a = 1, b = 2; swap (a, b); ยืนยัน (a == 2 && b == 1);) ไม่พูดถึงปัญหาทั้งหมดใน c / c ++ คุณจะมีถ้าคุณได้ใช้การอ้างอิง คุณจะเรียกใช้ฟังก์ชันเสมือนบนตัวชี้ทึบแสงแบบไม่มีตัวชี้ได้อย่างไร